Vydavatelství Naše vojsko, n. p., Praha – 1989 Vytiskly JČT, n. p., České Budějovice, provoz 6 Jindřichův Hradec
ÚVOD 16K monitorový program Spectra je složitý program ve strojovém kódu struktura je velmi zřetelná a to proto, že je rozdělena do tří hlavních částí: a) b) c)
procesoru
Z80.
Jeho
Vstupní a výstupní podprogramy Interpret jazyka BASIC Manipulace s výrazy
Tyto bloky jsou ale ještě příliš velké na to, aby je bylo možno snadno pochopit vcelku, a je monitorový program v této knize rozdělen do deseti částí. Nyní nastíníme každou z těchto částí:
proto
Restartovací podprogramy a tabulky Na začátku monitorového programu jsou různé restartovací podprogramy, které jsou volány jednobajtovými instrukcemi RST. Tyto restarty jsou využity všechny. Například restart #08 je využíván pro hlášení různých sdělení nebo chyb. Tabulky v této části monitorového programu obsahují nezkrácené tvary klíčových slov a kódy tlačítek.
Podprogram pro obsluhu klávesnice Klávesnice je testována každou 1/50 sec, a po testu je na příslušnou systémovou proměnnou uložen kód příslušné klávesy. Všechna tlačítka na klávesnici "opakují" jestliže jsou stlačena delší dobu. O to se stará také tento podprogram.
Podprogram pro obsluhu reproduktoru Spectrum má vestavěný reproduktor a tóny vznikají opakovaným užitím instrukce OUT. V řídícím podprogramu byla věnována velká pozornost tomu, aby bylo zajištěno, že žádaný tón bude mít příslušnou výšku a délku trvání.
Podprogramy obsluhující kazetový magnetofon Jednou ze slabých stránek počítače ZX-81 bylo to, že jen velmi malá část jeho monitorového programu byla určena k obsluze kazetového magnetofonu. Ale ve Spectru je už rozsáhlý blok strojového kódu a dá se říci, že jedním z nejúspěšnějších rysů Spectra je právě vysoká kvalita ovládacích podprogramů. Basicové programy nebo bloky dat jsou ukládány pomocí hlavičkového bloku, který má 17 bajtů a je ukládán první. Hlavička popisuje charakter dat ukládaných v následujícím bloku. Jedinou "nevýhodou" tohoto systému je to, že není možno zabezpečit utajení bloků dat.
Podprogramy obsluhující obrazovku a tiskárnu Všechny ostatní vstupní a výstupní podprogramy jsou "vektorovány" pomocí kanálových a "streamových" (proudových) adres. Ve standardním Spectru je vstup možný pouze z klávesnice, ale výstup může být směrován na tiskárnu a horní nebo dolní část televizního displeje. Hlavní "vstupní" podprogram v této části monitorového programu je EDITOR, který umožňuje uživateli vkládat znaky do dolní části televizního displeje. Podprogram PRINT OUT je dosti pomalý, protože je společný pro všechny druhy tisku. Například přidání jednoho bajtu na displej v sobě zahrnuje též současné posouzení stavu funkcí OVER a INVERSE při každém použití tohoto podprogramu.
Komentovaný výpis paměti ROM
5
Prováděcí podprogramy V této části monitorového programu můžeme najít iniciační podprogram a hlavní prováděcí smyčku interpretu jazyka Basic. Ve Spectru je kontrolována syntaxe basicového řádku, který je posléze uložen do programové oblasti, jestliže měl číslo, jinak je okamžitě vykonán, což může ve svém důsledku vést k různým situacím. (Zřetelně je to vidět v případě operace RUN).
Interpretace příkazů jazyka Basic Tato část monitorového programu považuje basicový řádek za soubor příkazů. Pro každý příkaz je zde "příkazový" podprogram, který provede (interpretuje) příslušný příkaz jako sled instrukcí ve strojovém kódu.
Vyhodnocování výrazª Spectrum má velmi obsažný program pro vyhodnocování výrazů, který umožňuje využít širokou škálu typů proměnných, funkcí a operací. Tato část monitoru je opět dosti pomalá, a to právě proto, že se zabývá všemi možnými alternativami. Zvláště zpracování řetězců je velmi dobře zvládnuto. Všechny jednoduché řetězce jsou uloženy dynamicky a jejich staré kopie jsou okamžitě, jakmile se stanou nadbytečnými, zničeny. To znamená, že není potřeba provádět vytřiďování "smetí" tak jako u jiných systémů.
Aritmetické podprogramy Spectrum používá dva typy čísel. Celočíselné hodnoty v rozsahu -65535 až 65535 jsou takzvané krátké (integer) formy, zatímco všechna ostatní čísla jsou ukládána v pětibajtové formě zvané pohyblivá řádová čárka (floating point). Současná verze monitoru má však bohužel také dvě chyby. 1) Chyba v dělení (34. bit je při dělení ztracen). 2) Hodnota -65535 je někdy uložena ve formě integer a jindy ve formě floating point, což někdy působí problémy.
Kalkulátor pro reálná čísla Kalkulátor Spectra zpracovává čísla a řetězce. Jeho operace jsou specifikovány tzv. "literály". Tato část monitorového programu obsahuje podprogramy pro všechny matematické funkce. Funkce jako sin, exp, ln atd. jsou získávány aproximačním způsobem. Aproximace se provádí rozvojem Čebyševových polynomů. Celkově se dá říci, že 16K monitor nabízí extrémně široký rozsah různých basicových příkazů a funkcí, ale protože jeho tvůrci měli k dispozici jen omezený prostor v paměti, je tento program spíše kompaktnější než rychlejší.
6
Komentovaný výpis paměti ROM
PODPROGRAMY RESTARTŮ A TABULKY RST #00 START Maskované přerušení je zakázáno a registrový pár DE nastaven tak, aby obsahoval nejvyšší možnou adresu paměti RAM. 0000
START
DI XOR LD JP
Zákaz přerušení i testu klávesnice #00 pro start, ale #FF pro NEW Nejvyšší možná adresa RAM Skok dopředu
A DE,#FFFF #11CB,START/NEW
RST #08 ERROR RESTART Chybový ukazatel je nastaven tak, aby ukazoval na pozici chyby. 0008
ERROR-1
LD LD JP
HL,(#5C5D) {CH-ADD} (#5C5F),HL {X-PTR} #0053,ERROR-2
Adresa dosazená interpretem je okopírována do chybového ukazatele, dříve než se bude pokračovat.
RST #10 RESTART TISK ZNAKU Registr A obsahuje kód znaku, který má být vytištěn. 0010
PRINT-A-1
JP #15F2,PRINT-A-2 DEFB #FF,#FF,#FF,#FF,#FF
Okamžitý skok dopředu. Volné místo.
RST #18 RESTART NAČTENÍ ZNAKU Obsah místa adresovaného systémovou proměnnou CH-ADD je přečten. Návrat, jestliže se jedná o znak použitelný k tisku, jinak je CH-ADD zvětšen a testy se opakují. 0018
GET-CHAR
001C
TEST-CHAR
LD LD CALL RET
HL,(#5C5D) {CH-ADD} A,(HL) #007D,SKIP-OVER NC
RST #20 RESTART NAČTENÍ DALŠÍHO ZNAKU Při interpretaci basicového řádku postupování po řádku. 0020
NEXT-CHAR
CALL #0074,CH-ADD+1 JR #001C,TEST-CHAR DEFB #FF,#FF,#FF
Vyzvedni hodnotu adresovanou systémovou proměnnou CH-ADD. Zjisti, zda se jedná o znak použitelný k tisku a vrať se, je-li to pravda.
je
tento
podprogram
opakovaně
vyvoláván,
což
způsobuje
Je nutno zvětšit CH-ADD. Skok zpět a test nové hodnoty. Volná místa.
RST #28 RESTART KALKULÁTORU Kalkulátor pracující s pohyblivou řádovou čárkou začíná na adrese #335B. 0028
FP-CALC
JP #335B,CALCULATE DEFB #FF,#FF,#FF,#FF,#FF
Okamžitě skoč dopředu. Volná místa.
Komentovaný výpis paměti ROM
7
RST #30 RESTART VYTVOŘENÍ BC PROSTORU Tento podprogram vytváří volná místa v pracovním prostoru. Počet vytvářených míst je dán hodnotou uloženou v reg. BC. 0030
BC-SPACES
PUSH LD PUSH JP
BC HL,(#5C61) (WORKSP) HL #169E,RESERVE
Uschovej čítač. Vyzvedni současnou adresu pracovního prostoru a uchovej ji před vstupem do samotného podprogramu.
RST #38 PODPROGRAM MASKOVATELNÉHO PŘERUŠENÍ Hodiny reálného času ve SPECTRU jsou zvětšeny a současně je testována klávesnice kdykoliv dojde k maskovatelnému přerušení. 0038
MASK-INT
0048
KEY-INT
PUSH PUSH LD INC LD LD OR JR INC PUSH PUSH CALL POP POP POP POP EI RET
AF HL HL,(#5C78) (FRAMES) HL (#5C78),HL (FRAMES) A,H L NZ,#0048,KEY-INT (IY+64) (FRAMES+2) BC DE #02BF,KEYBOARD DE BC HL AF
Uchovej hodnoty uložené v těchto registrech. Dolní dva bajty systémové proměnné FRAMES jsou zvětšeny každých 20 ms. (Evropská norma) Nejvyšší bajt této proměnné je zvětšen pouze tehdy, je-li hodnota nižších dvou bajtů nulová. Uschovej hodnoty obsažené v těchto registrech. Nyní testuj klávesnici. Obnov hodnoty v registrech.
Maskovatelné přerušení je před návratem znovu povoleno.
PODPROGRAM ERROR-2 Návratové adresy do interpretu ukazují na data, která určují, ke které chybě došlo. Tato data jsou vyzvednuta a přenesena do systémové proměnné ERR-NR. Než se provede odskok dopředu a vyčištění zásobníku kalkulátoru, je také vyčištěn zásobník. 0053
ERROR-2
0055
ERROR-3
POP LD LD LD JP DEFB DEFB
HL L,(HL) (IY+0),L SP,(#5C3D) {ERR-SP} #16C5,SET-STK #FF,#FF,#FF,#FF #FF,#FF,#FF
Adresa na zásobníku ukazuje na kód chyby. (ERR-NR) Je přenesena do ERR-NR a provede se vyčištění zásobníku před odskokem do SET-STK. Volná místa.
PODPROGRAM NEMASKOVATELNÉHO PŘERUŠENÍ Tento podprogram není v normálním SPECTRU využit, ale měl by umožňovat NMI (nemaskovatelné přerušení). Systémová proměnná na adr. #5CB0, která se jmenuje NMIADD, musí mít nulovou hodnotu aby došlo k resetu. 0066
8
RESET
PUSH PUSH LD LD OR
AF HL HL,(#5CB0) {NMIADD} A,H L
Uchovej hodnoty obsažené v registrech. Dva bajty proměnné NMIADD musí být oba nulové. Komentovaný výpis paměti ROM
0070
NO-RESET
JR JP POP POP RETN
NZ,#0070,NO-RESET (HL) HL AF
Pozn.: zde mělo správně být Skok na START. Obnov hodnoty v registrech a vrať se.
JR z,#0070.
PODPROGRAM CH-ADD+1 Adresa, která se nachází v CH-ADD je zvětšena a opět uložena. Nyní se vezme obsah místa adresovaného CH-ADD. Vstupní body podprogramu TEMP-PTR1 a TEMP-PTR2 jsou použity, aby nastavily CH-ADD na přechodnou periodu. 0074 0077 0078
CH-ADD+1 TEMP-PTR1 TEMP-PTR2
LD INC LD LD RET
HL,(#5C5D) HL (#5C5D),HL A,(HL)
(CH-ADD) (CH-ADD)
Vyzvedni adresu. Zvětši ukazatel. Nastav adresu. Vyzvedni adresovanou hodnotu a vrať se.
PODPROGRAM SKIP-OVER Hodnota, která do tohoto podprogramu vstupuje v registru A, je testována zda se jedná o znak, který je možno tisknout. Různé speciální kódy způsobují, že reg. HL je jednou nebo dvakrát zvětšen a podle toho se současně upravuje hodnota CH-ADD. 007D
0090
SKIP-OVER
SKIPS
CP RET CP RET CP RET CP CCF RET INC CP JR INC SCF LD RET
#21 NC #0D Z #10 C #18
Vrať se s vynulovaným CY, jestli se jedná o obyčejný znak. Vrať se, jestliže bylo dosaženo konce řádku. Jestliže se jedná o hodnotu v rozsahu #00 až #0F, vrať se s nastaveným CY. Vrať se s kódy #18-#20 rovněž s nastaveným CY.
C HL #16 C,#0090,SKIPS HL (#5C5D),HL
(CH-ADD)
Jednou přeskoč. Skoč dopředu při kódu #10 až #15 (INK až OVER)). Ještě jednou skoč (AT & TAB). Vrať se s nastaveným CY a s CH-ADD nastavenou na příslušnou adresu.
TABULKA KÓDOVANÝCH KLÍČOVÝCH SLOV - "TOKENS" Všechny TOKENS, které SPECTRUM používá jsou expandovány odkazy na tuto tabulku. Poslední bajt každého TOKEN je označen nastavením bitu 7. 0095 009D 00A5 00AD 00B5 00BD 00C5 00CD 00D5 00DD 00E5 00ED
BF 59 49 4E 54 4F CE 41 41 49 CE 49
52 A4 4E A4 41 44 53 CE 54 4E 41 CE
4E 50 D4 41 C2 C5 49 41 CE D4 42 55
C4 C9 53 54 56 56 CE 53 4C 53 D3 53
49 46 43 54 41 41 43 CE CE 51 50 D2
4E CE 52 D2 4C CC 4F 41 45 D2 45 53
4B 50 45 41 A4 4C D3 43 58 53 45 54
45 4F 45 D4 43 45 54 D3 D0 47 CB 52
? Y I N T O N A A I N I
R $ N $ A D S N T N A N
N P T A B E I A N T B U
D I S T V V N S L S S S
Komentovaný výpis paměti ROM
I F C T A A C N N Q P R
N N R R L L O A E R E S
K P E A $ L S C X S E T
E O E T C E T S P G K R 9
00F5 00FD 0105 010D 0115 011D 0125 012D 0135 013D 0145 014D 0155 015D 0165 016D 0175 017D 0185 018D 0195 019D 01A5 01AD 01B5 01BD 01C5 01CD 01D5 01DD 01E5 01ED 01F5 01FD
A4 42 3C 4E 53 46 4D 52 20 A3 52 43 CB 41 D4 4F 50 53 41 53 42 4E CD 4F 55 4F 45 45 52 52 41 49 D7 54
43 49 BD C5 54 CE 41 41 A3 4D 49 49 50 53 49 56 52 D4 C4 54 4F 54 52 20 C2 41 D4 58 49 55 4E C6 43 55
48 CE 3E 54 45 43 D4 53 43 45 46 52 41 C8 4E 45 49 53 44 4F 52 49 45 54 49 C4 50 D4 4E CE 44 43 4C 52
52 4F BD 48 D0 41 4D C5 4C 52 D9 43 50 42 56 D2 4E 54 41 52 44 4E CD CF 4E 4C 41 50 D4 53 4F 4C 45 CE
A4 D2 3C 45 44 D4 4F 4F 4F 47 42 4C 45 52 45 4F D4 4F 54 C5 45 55 46 47 50 49 55 4F 50 41 4D D3 41 43
4E 41 BE CE 45 46 56 50 53 C5 45 C5 D2 49 52 55 4C D0 C1 4E D2 C5 4F 4F 55 53 53 4B 4C 56 49 44 D2 4F
4F 4E 4C 54 46 4F C5 45 45 56 45 49 46 47 53 D4 4C 52 52 45 43 44 D2 20 D4 D4 C5 C5 4F C5 5A 52 52 50
D4 C4 49 CF 20 52 45 4E 20 45 D0 4E 4C 48 C5 4C 49 45 45 D7 4F 49 47 53 4C 4C 4E 50 D4 52 C5 41 45 D9
$ B < N S F M R # R C K A T O P S A S B N M O U O E E R R A I W T
C I = E T N A A # M I I P S I V R T D T O T R B A T X I U N F C U
H N > T E C T S C E F R A H N E I S D O R I E T I D P T N N D C L R
R O = H P A M E L R Y C P B V R N T A R D N M O N L A P T S O L E N
$ R < E D T O O O G B L E R E O T O T E E U F G P I U O P A M S A C
N A > N E F V P S E E E R I R U L P A N R E O O U S S K L V I D R O
O N L T F O E E E V E I F G S T L R R E C D R
T D I O R E N E P N L H E L I E E W O I G S L L N P T R E A E Y
T T E E O E Z R R P
TABULKY KLÁVES Ve SPECTRU je 6 oddělených tabulek kláves. Výsledný kód znaku závisí na stištění určité klávesy a na momentálně použitém režimu. (a) Tabulka hlavních kláves - L režim a CAPS SHIFT. 0205 020D 0215 021D 0225
10
42 4E 4D 0E 20
48 4A 4B 4C 0D
59 55 49 4F 50
36 37 38 39 30
35 34 33 32 31
54 52 45 57 51
47 46 44 53 41
56 43 58 5A
B N M SYM.SH. SPACE
H J K L ENTER
Y U I 0 P
6 7 8 9 0
5 4 3 2 1
T R E W Q
G F D S A
V C X Z
Komentovaný výpis paměti ROM
(b) Režim EXTEND. Klávesy písmen. 022C 0230 0234 0238 023C 0240 0244
E3 B4 AF A7 B2 C2 C1
C4 BC B0 A6 BA E1 B8
E0 BD B1 BE E5 B3
E4 BB C0 AD A5 B9
READ TAN CODE PI SIN CHR$ STR$
BIN SGN VAL INKEY$ INT LLIST LN
LPRINT ABS LEN PEEK RESTORE COS
DATA SQR USR TAB RND EXP
(c) Režim EXTEND. Klávesy písmen a SYMBOL SHIFT. 0246 024A 024E 0252 0256 025A 025E
7E B7 BF DD B5 5D 5B
DC 7B AE DE D6 DB D7
DA 7D AA DF 7C B6
5C D8 AB 7F D5 D9
~ ATN IN INVERSE ASN ] [
BRIGHT { VAL$ OVER VERIFY FLASH BEEP
PAPER } SCREEN$ OUT | ACS
\ CIRCLE ATTR © MERGE INK
(d) Řídící kódy. Klávesy číslic a CAPS SHIFT. 0260 0264 0268
0C 07 06 04 05 08 0A 0B 09 0F
DELETE EDIT CAPS LOCK INV.VIDEO kurzor vlevo dolů vpravo GRAPHICS
TRUE VIDEO nahoru
(e) Kódy symbolů. Klávesy písmen a SYMBOL SHIFT. 026A 026E 0272 0276 027A 027E 0282
E2 C8 AC 2E C7 C5 C6
2A CC 2D 2C 3C 2F 3A
3F CB 2B 3B C3 C9
CD 5E 3D 22 3E 60
STOP >= AT . <= OR AND
* TO , < / :
? THEN + ; NOT <>
STEP ^ = " > £
(f) Režim EXTEND. Klávesy číslic a SYMBOL SHIFT. 0284 0288 028C
D0 CE A8 CA D3 D4 D1 D2 A9 CF
FORMAT OPEN POINT
DEF FN CLOSE CAT
FN MOVE
Komentovaný výpis paměti ROM
LINE ERASE
11
KLÁVESNICOVÉ PODPROGRAMY
PODPROGRAM VYHODNOCENÍ KLÁVESNICE Tento velmi důležitý podprogram je vyvoláván z hlavního klávesnicového podprogramu a z podprogramu INKEY$ (při SCANNINGu). Ve všech případech obsahuje registr E hodnotu v rozsahu #00-#27 byla-li stlačena některá z kláves, nebo hodnotu #FF nebyla-li stlačena žádná klávesa. Registr D obsahuje hodnotu, která indikuje stištění SHIFTovacích kláves. Jestliže byly stlačeny obě SHIFTovací klávesy, obsahují registry D a E hodnoty pro CAPS SHIFT a SYMBOL SHIFT. Jestliže nebyla stištěna žádná klávesa obsahuje registrový pár DE hodnotu #FFFF. Nulový indikátor se vrací vynulován, když došlo ke stištění dvou kláves a ani jedna z nich nebyla klávesa SHIFT. 028E
KEY-SCAN
LD
L,#2F
LD LD
DE,#FFFF BC,#FEFE
Počáteční hodnota pro každý řádek bude: #2F, #2E, ..., #28 (8 řádků). Nastav registrový pár DE na signál "žádná klávesa". Registr C obsahuje adresu portu, registr B je čítač.
Nyní se vstupuje do smyčky, která bude vykonána osmkrát a při každém průchodu se bude začínat s novou počáteční hodnotou v registru L jak bylo uvedeno výše. 0296
KEY-LINE
029F
KEY-3KEYS
02A1
KEY-BITS
02AB
KEY-DONE
IN CPL AND JR LD LD INC RET SUB SRL JR LD LD JR DEC RLC JR
A,(C)
Je čten specifikovaný port. Stištěná klávesa v této řádce nastaví příslušný bit #1F (jedná se o bity 0-4). Z,#02AB,KEY-DONE Nebyla-li stištěna žádná klávesa provede se odskok, H,A jinak jsou klávesové bity uloženy do registru H a A,L kód "první" klávesy v tomto řádku je uložen do registru A. D Jestliže byly stištěny 3 klávesy, nemůže registr D obsahovat hodnotu #FF a NZ provede se návrat. #08 V této smyčce je H opakovaně odečítána hodnota #08, dokud není NC,#02A1,KEY-BITS nalezen klávesový bit. D,E Okopíruj předchozí klávesovou hodnotu do registru D a E,A ulož novou klávesovou hodnotu do registru E. NZ,#029F,KEY-3KEYS Skoč zpět, jsou-li ještě další stisknuté klávesy v tomto řádku. L Řádka byla prozkoumána počáteční hodnota může být snížena. B Čítač je posunut doleva a C,#0296,KEY-LINE provede se odskok, jestliže se nejednalo o poslední řádek.
Nyní se provedou čtyři testy: LD INC RET CP RET CP RET LD LD LD CP RET
12
A,D A Z #28 Z #19 Z A,E E,D D,A #18
Pokud registr D obsahuje hodnotu #FF, je zároveň s touto hodnotou přijata i jakákoliv hodnota v registru E. Je-li v registru D hodnota #28 (CAPS SHIFT), je opět přijata i jakákoliv hodnota v registru E. Je-li v registru D hodnota #19 (SYMBOL SHIFT), je také přijata i jakákoliv hodnota v registru E. Je ovšem možné, že v registru E je hodnota pro SYMBOL SHIFT a toto musí být také zváženo. Z=0, jestliže se nejednalo o SYMBOL SHIFT a nějakou klávesu
Komentovaný výpis paměti ROM
PODPROGRAM KLÁVESNICE Tento podprogram je volán při každém maskovatelném přerušení, což se děje 50krát za sekundu, je-li procesor v modu IM1. Úkolem tohoto podprogramu je otestovat klávesnici a dekódovat hodnoty stištěných kláves. Výsledný kód stištěné klávesy je předán do systémové proměnné LAST-K, pokud to umožní "opakovací statut". Po uložení získaného kódu do syst. proměnné je nastaven bit 5 v systémové proměnné FLAGS jako signál, že byla stlačena klávesa. 02BF
KEYBOARD
CALL #028E,KEY-SCAN RET NZ
číslo určující typ stlačené klávesy je uloženo do reg. DE Bylo-li stlačeno více kláves (ne SHIFT) provede se návrat.
Je využíván zdvojený systém systémových proměnných KSTATE (KSTATE0-KSTATE3 (1.sada) a KSTATE4-KSTATE7 (2.sada)), který umožňuje detekci stištění další klávesy i když program ještě pokračuje v opakovací periodě předchozí klávesy. Systém přijme novou klávesu, byla-li stištěna alespoň 1/10 sec., což odpovídá pěti voláním podprogramu klávesnice.
02C6
K-ST-LOOP
LD BIT JR INC DEC DEC JR LD
HL,#5C00 (KSTATE0) 7,(HL) NZ,#02D1,K-CH-SET HL (HL) HL NZ,#02D1,K-CH-SET (HL),#FF
Začne se s KSTATE0. Je-li systém volný (tj. KSTATE0/4 obsahují hodnotu #FF), provede se odskok dopředu. HL ukazuje na čítač pěti volání který je následovně zmenšen a provede se odskok, nebyla-li 1.sada volná. Signál: 1.sada volná.
Po otestování 1. sady systému bude změněn ukazatel a testována 2. sada. 02D1
K-CH-SET
LD LD CP JR
A,L HL,#5C04 (KSTATE4) L NZ,#02C6,K-ST-LOOP
Nižší bajt adresy 1.sady je porovnán s nižším bajtem adresy 2.sady a provede se odskok při kontrole 2. sady.
Provede se návrat, nebyla-li stištěna žádná klávesa nebo pouze jedna z kláves SHIFT. CALL #031E,K-TEST RET NC
dobu.
Proveď nezbytné testy a vrať se, je-li to třeba.
Nyní bude rozlišeno zda se jedná o nový stisk, nebo byla-li stištěna nějaká klávesa již delší
LD CP JR EX LD CP JR
HL,#5C00 (KSTATE0) (HL) Z,#0310,K-REPEAT DE,HL HL,#5C04 (KSTATE4) (HL) Z,#0310,K-REPEAT
Nejdříve zhodnoť 1.sadu a jestliže se hodnoty shodují, skoč dopředu. Je uschována adresa KSTATE0. Podívej se do 2.sady a jsou-li kódy shodné, skoč dopředu (opakuj).
Nová klávesa bude akceptována, je-li jedna ze sad systému KSTATE volná. BIT JR EX BIT RET
7,(HL) NZ,#02F1,K-NEW DE,HL 7,(HL) Z
Posuď 2.sadu a skoč dopředu, je-li volná. Nyní testuj 1.sadu a pokračuj, je-li volná.
Nové tlačítko musí být nyní akceptováno. Ale před tím než bude do LAST-K uložena nová hodnota, musí být bajty systému KSTATE nastaveny na správné hodnoty tak, aby neobsahovaly žádné opakovací hodnoty. Nyní může být zjištěn kód tlačítka. Komentovaný výpis paměti ROM
13
02F1
K-NEW
LD LD INC LD INC LD LD INC
E,A Kód je okopírován do registru E a (HL),A do KSTATE0/4. HL (HL),#05 Počítadlo 5-ti průchodů HL je nastaveno na hodnotu 5. A,(#5C09) (REPDEL) Třetí proměnná tohoto systému je nastavena (HL),A na hodnotu systémové proměnné REPDEL (normálně 0.7 sec). HL HL ukazuje nyní na KSTATE3/7.
Dekódování hlavního kódu závisí na stavu MODE, bitu 3 systémové proměnné FLAGS a SHIFTového bajtu. LD LD PUSH CALL POP LD
C,(IY+7) (MODE) D,(IY+1) (FLAGS) HL #0333,K-DECODE HL (HL),A
Další tři instrukční opakujících kláves. 0308
K-END
LD SET RET
řádky
jsou
Vyzvedni hodnotu MODE. Vyzvedni hodnotu FLAGS. Uschovej ukazatel po dobu dekódování hlavního kódu. Konečná hodnota je uložena v proměnné KSTATE3/7 odkud je vybírána v případě opakování. společné
pro
vyhodnocení
jak
nově
vložených
kláves
tak
(#5C08),A (LAST-K) Vlož novou hodnotu do LAST-K a 5,(IY+1) (FLAGS) signalizuj, že byla stlačena nová klávesa a konečně se vrať.
PODPROGRAM OPAKOVÁNÍ KLÁVESY Klávesa bude opakována při prvním výskytu po zpožďovací periodě REPDEL (normálně 0.7 sec.) a při dalších výskytech (opakování) po zpožďovací periodě REPPER (normálně 0.1 sec). 0310
K-REPEAT
INC LD INC DEC RET LD LD INC LD JR
HL (HL),#05 HL
Ukazuj na čítač 5ti volání v sadě, která je právě používána, a nastav jí na hodnotu 5. HL nyní ukazuje na 3. systémovou proměnnou (tj. REPPER/REPDEL), (HL) která je právě zmenšena a NZ je proveden návrat, jestliže zpožďovací perioda neproběhla. A,(#5C0A) (REPPER) V opačném případě bude hodnotu zpoždění (HL),A udávat hodnota na sys. proměnné REPPER. HL Opakování bylo přijato, A,(HL) takže bude nakonec do registru A uložena hodnota KSTATE3/7 #0308,K-END a předána podprogramu K-END.
PODPROGRAM K-TEST Hodnota klávesy je testována a provede se návrat, jestliže nebyla stištěna žádná klávesa nebo pouze některý SHIFT. Jinak bude nalezen kód pro příslušnou klávesu. 031E
14
K-TEST
LD LD LD CP RET CP JR BIT RET
B,D D,#00 A,E #27 NC #18 NZ,#032C,K-MAIN 7,B NZ
Je okopírován SHIFTovací bajt. Vynuluj registr D pro pozdější užití. Přenes číslo klávesy do registru A a byl-li to CAPS SHIFT nebo žádná klávesa, proveď návrat. Pokud se nejedná o SYMBOL SHIFT, provede se odskok dopředu. SYMBOL SHIFT a jiné klávesy jsou akceptovány a je proveden návrat, jednalo-li se pouze o SYMBOL SHIFT. Komentovaný výpis paměti ROM
Hlavní kód je nalezen v tabulce hlavních kláves. 032C
K-MAIN
LD ADD LD SCF RET
HL,#0205 HL,DE A,(HL)
Bázová adresa tabulky. Najdi v tabulce kód klávesy. Signál: platné stištění. Vrať se.
PODPROGRAM DEKÓDOVÁNÍ KLÁVESNICE Do tohoto programu se vstupuje s "hlavním kódem" v registru E, s hodnotou systémové proměnné FLAGS v registru D, hodnotou MODE v registru C a se SHIFT bajtem v registru B. Posouzením těchto čtyř hodnot s pomocí šesti klávesových tabulek je získán "finální kód", který je na výstupu uložen v registru A. 0333
K-DECODE
LD CP
A,E #3A
JR DEC JP JR
C,#0367,K-DIGIT C M,#034F,K-KLC-LET Z,#0341,K-E-LET
Okopíruj "hlavní kód". Pokud se jedná o posouzení číslicových kláves, ENTER, SPACE a obou SHIFTů, provede se skok. Zmenši hodnotu MODE a skoč dopředu, vyžadují-li to mody K,L,C nebo mod E.
Zůstává pouze grafický mod a "finální kód" je vypočítán přímo z "hlavního kódu". ADD RET
A,#4F
Přičti doplněk a vrať se s "finálním kódem".
Jsou posouzeny znaky v EXTENDED MODE. 0341
K-E-LET
LD INC JR LD
HL,#01EB B Z,#034A,K-LOOK-UP HL,#0205
Bázová adresa tabulky "b". Nebyla-li stisknuta žádná ze SHIFTových kláves, užij tabulku "b". Jinak užij bázovou tabulku "c".
Tabulky "b-f" jsou obslouženy následujícím podprogramem. Ve všech případech je nalezen a předán "finální kód". 034A
K-LOOK-UP
LD ADD LD RET
D,#00 HL,DE A,(HL)
Vynuluj registr D. Najdi v tabulce "finální kód". Pak se hezky vrať.
Nyní jsou posuzovány znaky v modech K, L a C. Ale nejprve se musí pracovat s kódy pro SYMBOL SHIFT. 034F
K-KLC-LET
LD BIT JR BIT JR BIT RET INC RET ADD
HL,#0229 0,B Z,#034A,K-LOOK-UP 3,D Z,#0364,K-TOKENS 3,(IY+48) (FLAGS2) NZ B NZ A,#20
Bázová adresa tabulky "e". Jedná-li se o SYMBOL SHIFT + písmeno skoč zpět. Jseš-li se v modu K, skoč dopředu. Byl-li nastaven CAPS LOCK, vrať se s "finálním kódem". Byl-li stištěn CAPS SHIFT, vrať se s tou samou hodnotou. Jedná-li se o malé písmeno, je třeba přičíst #20 k hlavnímu kódu
Komentovaný výpis paměti ROM
15
RET
a provést návrat.
Číselné hodnoty pro "tokens" jsou získány přičtením hodnoty #A5 k "hlavnímu kódu". 0364
K-TOKENS
ADD RET
A,#A5
Přičti požadovaný doplněk a vrať se.
Nyní jsou posuzovány číselné klávesy, SPACE, ENTER a oba SHIFTy.
0367
K-DIGIT
CP RET DEC JP JR LD BIT JR CP JR
#30 C C M,#039D,K-KLC-DGT NZ,#0389,K-GRA-DGT HL,#0254 5,B Z,#034A,K-LOOK-UP #38 NC,#0382,K-8-&-9
Pokračuj jedině v tom případě, jedná-li se o číslo, tzn. vrať se při SPACE (#20), ENTER (#0D) nebo oba SHIFTy (#0E). Nyní rozděl číselné klávesy do tří skupin a to podle modů K,L,C a modu G. Pokračuj v modu E. Bázová adresa tabulky "f". Použij tuto tabulku pro SYMBOL SHIFT a číselné klávesy v EXTENDED MODU. Jedná-li se o klávesy 8 a 9, skoč dopředu.
Číselné klávesy 0 až 7 mají dát buď kód barvy papíru nebo inkoustu - když je stlačen CAPS SHIFT. SUB INC RET ADD RET
#20 B Z A,#08
Rozsah #30 až #37 je snížen na #10 až #17 a jestliže nebyl užit CAPS LOCK, vrať se s hodnotou tohoto papíru. Ale kdyby byl rozsah #18 až #1E, znamená to že se jedná o barvu inkoustu.
Klávesy 8 a 9 musí dávat BRIGHT a FLASH. 0382
K-8-&-9
SUB INC RET ADD RET
#36 B Z A,#FE
Hodnoty #38 a #39 dávají #02 a #03. Nebyl-li použit CAPS SHIFT, provede se návrat (jedná se o kód pro BRIGHT). Je odečtena dvojka a vzniknou tak hodnoty #00 a #01 (FLASH). Návrat s těmito kódy.
Číselné klávesy v grafickém modu mají dát skupinu grafických znaků (#80 až (#0F) a kód pro DELETE (#0C). 0389
K-GRA-DGT
LD CP JR CP JR AND ADD INC RET XOR
HL,#0230 #39 Z,#034A,K-LOOK-UP #30 Z,#034A,K-LOOK-UP #07 A,#80 B Z #0F
RET
Bázová adresa tabulky "d". Použij tuto tabulku přímo jak pro klávesu 9, která má provést GRAPHICS, tak pro klávesu 0, která provede DELETE. Pro klávesy 1 až 8 uprav rozsah na hodnoty #80 až #87 a pokud nebyla stlačena ani jedna ze SHIFTovacích kláves, proveď návrat. Byl-li stlačen některý SHIFT, uprav rozsah na hodnoty #88 až #8F. Návrat.
Nakonec posuzuj číslicové klávesy v modech K, L, & 039D
16
K-KLC-DGT
INC RET BIT
B Z 5,B
#8f), grafický kód
C.
Pokud nebyl stištěn žádný SHIFT, vrať se přímo s "finálními kódy" #30 až #39. Je-li stisknuta Komentovaný výpis paměti ROM
LD JR
HL,#0230 klávesa CAPS SHIFT, NZ,#034A,K-LOOK-UP použij tabulku "d".
Nyní mohou být nalezeny kódy pro různé číslicové klávesy při použití SYMBOL SHIFTu.
03B2
K-&-CHAR
SUB CP JR CP RET LD RET LD RET
#10 #22 Z,#03B2,K-&-CHAR #20 NZ A,#5F A,#40
Sniž rozsah na #20 až #29 a odděl zavináč ( @ ) od ostatních. Znak "_" musí být také oddělen a vrať s "finálními kódy" #21, #23 Ulož do registru A kód znaku "_" vrať se. Ulož do registru A kód znaku "@" vrať se.
Komentovaný výpis paměti ROM
proto se až #29. a a
17
PODPROGRAMY PRO OVLÁDÁNÍ REPRODUKTORU Dva podprogramy v této části jsou: a) podprogram BEEPER obsluhující reproduktor; b) podprogram pro příkaz BEEP. Reproduktor je aktivován logickou nulou na D4 během instrukce OUT #FE, která používá port 254. Podobně při logické 1 je reproduktor deaktivován. Střídáním logických úrovní na D4 vzniká tón. (pozn.překl.: D4 označuje bit 4 na datové sběrnici) Uvažujme tón střední C jehož frekvence je 261.63Hz. K vytvoření tohoto tónu musí být reproduktor střídavě zapínán a vypínán každou 1/523.26 sekundy. Systémové hodiny ve Spectru jsou nastaveny na kmitočet 3.5 MHz a tón střední C bude tedy vyžadovat vystřídání logických úrovní každých 6689 T stavů. Tato poslední hodnota je nepatrně snížena aby se předešlo nevyhnutelným časovým ztrátám. Představuje délku časové smyčky pro podprogram BEEPER.
PODPROGRAM BEEPER Do tohoto podprogramu se vstupuje s hodnotou f*t v registrovém páru DE, kde f je daná frekvence po dobu t sekund. Registrový pár HL obsahuje počet T stavů děleno 4. Tedy pro tón střední C v trvání jedné sekundy DE obsahuje hodnotu #0105 což je INT (261.63*1) a HL obsahuje +066A což je odvozeno od 6689/4-30,125. 03B5
BEEPER
DI LD SRL SRL CPL AND LD LD LD ADD LD AND RRCA RRCA RRCA OR
A,L L L
Zákaz přerušení během trvání BEEPu. Přechodná úschova L. Každá "1" v registru L má počítat 4 T stavy, ale provedením INT(L/4) dochází k čítání 16 T stavu. Vrací původní hodnotu do L a zjišťuje zbytek po dělení
#03 C,A B, #00 IX,#03D1 Bázová adresa časové smyčky IX,BC Oprava délky časové smyčky za každou "1" zlomkové části. A,(#5C48) (BORDCR) Vyzvedni současnou barvu pro BORDER a #38 ulož ji do bitů 0,1 a 2 registru A.
#08
Výstup MIC je vypnut.
Zde se vstupuje do smyčky, která produkuje vlastní zvuk. V DE je počet kompletních průchodů. HL obsahuje "délku časové smyčky". 03D1 03D2 03D3 03D4
BE-IX+3 BE-IX+2 BE-IX+1 BE-IX+0
03D6
BE-H&L-LP
NOP NOP NOP INC INC DEC JR LD DEC JP
Přičte 4 T stavy za každý dřívější vstupní bod, který je použit. B Hodnoty v BC přijdou C z HL viz. dále. C časová smyčka; NZ,#03D6,BE-H&L-LP tedy BC*4 T stavy. C,#3F (Při polovičním cyklu B se bude C rovnat L+1) NZ,#03D6,BE-H&L-LP
Reproduktor je nyní střídavě zapínán a vypínán. XOR OUT LD LD 18
#10 (#FE),A B,H C,A
Otoč bit 4. Vykonej instrukci OUT při zachování barvy BORDERu. Resetuj registr B. Uschovej registr A. Komentovaný výpis paměti ROM
BIT JR
4,A NZ,#03F2,BE-AGAIN
Skok, jestliže jsi v bodě polovičního cyklu.
Po úplném cyklu se testuje registrový pár DE. LD OR JR LD LD DEC JP
A,D E Z,#03D6,BE-END A,C C,L DE (IX)
Skok zpět, jestliže již byl vykonán poslední průchod Obnovení uschované hodnoty. Resetuj registr C. Zmenšení čítače průchodů smyčkou. Skok zpět na počátek smyčky.
Parametry pro druhý poloviční cyklus jsou nastaveny. 03F2
BE-AGAIN
LD INC JP
C,L C (IX)
Resetuj registr C. Přičti 16 T stavů, protože tato cesta je kratší. Skok zpět na počátek smyčky.
Maskovatelné přerušení je obnoveno po ukončení BEEPu. 03F6
BE-END
EI RET
Obnovení přerušení. Závěrečný návrat.
PODPROGRAM PŘÍKAZU BEEP Před vstupem do tohoto podprogramu musí být na vrcholu zásobníku kalkulátoru uložena výška tónu P a pod ní délka trvání tónu t. 03F8
BEEP
RST DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB
#28,FP-CALC #31,zdvojení #27,int #C0,st-mem-0 #03,rozdíl #34,stk-data #EC,exponent+7C #6C,#98,#1F,#F5 #04,násobení #A1,stk-one #0F,součet #38,konec výpočtu
Volání FP kalkulátoru. t,P,P t,P,i ( i = INT P ) t,P,i ( i uloženo do mem-0 ) t,P ( p je zlomková část P ) konstanta K na zásobník (K=0.057762606)
t,pK t,pK,1 t,pK+1
Nyní se provede řada testů i (celočíselná hodnota výšky tónu u). LD LD AND JR INC LD INC LD LD RLA SBC CP JR INC
HL,#5C92 A,(HL) A NZ,#046C,REPORT-B HL C,(HL) HL B,(HL) A,B A,A C NZ,#046C,REPORT-B HL
Toto je mem-0-1 (MEMBOT). Vyzvedni exponent i a vyvolej chybu, pokud se nejedná o "krátkou formu". Kopíruj znaménkový bajt do registru C. Kopíruj nižší bajt do registru B a do registru A.
Vyvolej chybu pokud neplatí, že -128 <= i <= +127.
Komentovaný výpis paměti ROM
19
CP JR LD ADD JP JP
(HL) NZ,#046C,REPORT-B A,B A,#3C P,#0425,BE-i-OK PO,#046C,REPORT-B
Dále testuj nižší bajt. Akceptuj pouze -60 <= i <= +67. Odmítni hodnoty od -128 do -61.
Poznámka: Rozsah +70 až +127 bude zamítnut později. Nyní může být nalezena správná frekvence pro výšku i. 0425 0427
BE-i-OK BE-OCTAVE
LD INC SUB JR ADD PUSH LD CALL CALL
B,#FA B #0C NC,#0427,BE-OCTAVE A,#0C BC HL,#046E #3406,LOC-MEM #33B4,STACK-NUM
Začni "6" oktáv pod středním C. Opakovaně snižuj i, aby byla nalezena správná oktáva. Přičti zpět poslední odečet. Uchovej číslo oktávy. Bázová adresa tabulky půl tónů. Prohledej tabulku a nalezenou FP hodnotu přidej na zásobník kalkulátoru.
Nyní se vezme v úvahu zlomková část výšky. RST #28,FP-CALC DEFB #04,násobení DEFB #38,konec výpočtu
t,pK+1,C t,C(pK+1)
Konečná frekvence f je nalezena modifikací poslední hodnoty podle čísla oktávy. POP ADD LD RST DEFB DEFB
AF A,(HL) (HL),A #28,FP-CALC #C0,st-mem-0 #02,výmaz
Vyzvedni číslo oktávy. a vynásob "poslední hodnotu"*2^x. (x=číslo oktávy) t,f frekvence provizorně uložena v mem-0.
Výpočet trvání tónu. DEFB DEFB CALL CP JR
#31,zdvojení #38,konec výpočtu #1E94,FIND-INT1 #0B NC,#046C,REPORT-B
t,t Hodnota INT t musí být v rozsahu #00 až #0A.
Počet kompletních cyklů pro BEEP je dán součinem f*t. RST DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB 20
#28,FP-CALC #E0,get-mem-0 #04,násobení #E0,get-mem-0 #34,stk-data #80,4 bajty #43,exponent #93 #55,#9F,#80,#00 #01,záměna #05,dělení #34,stk-data #35,exponent #85 #71,#00,#00,#00
t t,f f*t f*t,f Na vrcholu zásobníku se vytvoří kons. KK=3.5*10^6/8. (KK=437500) f*t,f,KK f*t,KK,f f*t,KK/f
f*t,KK/f,30.125 Komentovaný výpis paměti ROM
DEFB #03,odčítání DEFB #38,konec výpočtu
f*t,KK/f,-30.125
Poznámka: Hodnota 437500/f dává délku polovičního cyklu. Její snížení o 30.125 poskytne 120.5T stavů, během kterých dojde k produkci noty, nastavení čítačů a podobně. Nyní se přenesou hodnoty do patřičných registrů. CALL #1E99,FIND-INT2 PUSH BC
Hodnota časové smyčky je převedena do BC a je uschována.
Poznámka: Jestliže je tato hodnota příliš vysoká dojde k vyvolání chybového podprogramu což vyloučí hodnoty od +70 do +127. CALL POP LD LD
#1E99,FIND-INT2 HL D,B E,C
Hodnota f*t je přenesena do BC, časová smyčka do HL. f*t do DE
Nyní poslední test hodnoty f*t. LD OR RET DEC JP 046C
REPORT-B
A,D E Z DE #03B5,BEEPER
RST #08,ERROR-1 DEFB #0A
Návrat, pokud nejsou požadovány žádné cykly. Zmenšení čítače průchodů smyčkou a skok do podprogramu BEEPER. Ohlaš: B-Integer out of range
TABULKA PŮLTÓNŮ Tato tabulka obsahuje frekvence dvanácti půltónů v oktávě.
046E
DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB
#89,#02,#D0,#12,#86 #89,#0A,#97,#60,#75 #89,#12,#D5,#17,#1F #89,#1B,#90,#41,#02 #89,#24,#D0,#53,#CA #89,#2E,#9D,#36,#B1 #89,#38,#FF,#49,#3E #89,#43,#FF,#6A,#73 #89,#4F,#A7,#00,#54 #89,#5C,#00,#00,#00 #89,#69,#14,#F6,#24 #89,#76,#F1,#10,#05
frekvence
tón
261.63 277.18 293.66 311.12 329.63 349.23 369.99 392 415.30 440 466.16 493.88
C C# D D# E F F# G G# A A# H
"NÁZEV PROGRAMU" (ZX81) Následující podprogram je pro ZX81 a nebyl odstraněn když se program přepisoval pro SPECTRUM. 04AA
DEFB DEFB DEFB DEFB DEFB DEFB
#CD,#FB,#24,#3A #3B,#5C,#87,#FA #8A,#1C,#E1,#D0 #E5,#CD,#F1,#2B #62,#6B,#0D,#F8 #09,#CB,#FE,#C9
Komentovaný výpis paměti ROM
21
PODPROGRAMY
SAVE - LOAD - VERIFY
Vstupní bod pro tyto podprogramy je na adrese #0605 SAVE-ETC. (Nicméně skutečné podprogramy pro SAVE, LOAD nebo VERIFY bloků bajtů začínají od #04C2). Ve všech případech obsahuje DE počet bajtů, v IX je adresa umístění začátku bloku dat v paměti. Registr A obsahuje #00 pro hlavičku a #FF pro vlastní blok dat. Rychlost přenosu je 1200 bit/sec. PODPROGRAM SA-BYTES Je volán pro SAVE hlavičky (z #09BA) a později pro vlastní blok dat (z #099E). 04C2
04D0
SA-BYTES
SA-FLAG
LD PUSH LD BIT JR LD EX INC DEC DI LD LD
HL,#053F HL HL,#1F80 7,A Z,#04D0,SA-FLAG HL,#0C98 AF,AF’ DE IX A,#02 B,A
Uložení adresy SA/LD-RET do zásobníku. Konstanta 5 sec. pro zaváděcí signál hlavičky. Skok, když se zaznamenává hlavička. Pouze 2 sec. pro datový blok. Uložení podmínkového registru. Délka o jedničku zvětšena. Bázová adresa snížena. Přerušení zakázáno po dobu SAVE. Maska pro MIC,BORDER červený. Přenos hodnoty 2 do B.
Nyní následuje podprogram pro tvorbu pulsů zaváděcího signálu. Pulsy MIC - on a MIC - off jsou dlouhé 2.168 T (taktů hodin). Barva BORDERu se mění v témže rytmu z červené do cyanu (při nástupné a sestupné hraně signálu). 04D8
SA-LEADER
DJNZ OUT XOR LD DEC JR DEC DEC JP
#04D8,SA-LEADER (#FE),A #0F B,#A4 L NZ,#04D8,SA-LEADER B H P,#04D8,SA-LEADER
Hlavní časová perioda. MIC on-off, BORDER červený - cyan v každém průchodu. Hlavní časová konstanta. Snížení nižšího bajtu čítače. Skok pro další puls. Další průchod, redukce o 13 T stavů. Snížení vyššího bajtu čítače. Zpět pro další puls dokud není zaváděcí část kompletní.
Dále je vyslán synchronizační puls (sync):
04EA
SA-SYNC-1
04F2
SA-SYNC-2
LD DJNZ OUT LD LD DJNZ OUT
B,#2F #04EA,SA-SYNC-1 (#FE),A A,#0D B,#37 #04F2,SA-SYNC-2 (#FE),A
MIC off: 667 T od OUT k OUT. MIC on a červená. Signál MIC off a cyan. MIC on: 735 T od OUT k OUT MIC off a BORDER cyan.
Bajt indikace bude zaznamenán jako první. LD EX LD JP
BC,#3B0E AF,AF’ L,A #0507,SA-START
3B je časovací konstanta, #0E = MIC off a žlutou. Indikační bajt do reg. A a jeho převod do L s odesláním. Skok do záznamové smyčky.
Je zaznamenán indikační bajt, dál už následují bajty dat. Poslední je paritní bajt, který je konstruován průběžně postupným porovnáváním hodnot všech zaznamenávaných bajtů (pro kontrolu správnosti záznamu při verifikaci nebo načítání).
22
Komentovaný výpis paměti ROM
04FE
SA-LOOP
0505
SA-LOOP-P
0507
SA-START
LD OR JR LD LD XOR LD LD SCF JP
A,D E Z,#050E,SA-PARITY L,(IX+00) A,H L H,A A,#01 #0525,SA-8-BITS
Čítač délky dat je testován a když dosáhne 0, provede se skok. Do L další bajt pro záznam. H je momentální paritní bajt. Přidej nový bajt záznamu. Nový paritní bajt do H. Signál MIC on a modrá. CY jako návěští pro 8 bitů zaznamenávaného bajtu. Skok do tvorby bajtu a jeho zaznamenání na pásek.
Před posláním paritního bajtu k nahrání je bajt převeden do L: 050E
SA-PARITY
LD JR
L,H #0505,SA-LOOP-P
Konečná podoba paritního bajtu. Skok zpět.
Následující podprogram tvaruje jednotlivé bity nahrávaného bajtu tak, že každý obsahuje on i off puls, přičemž pulsy pro bity log.1 jsou přesně dvakrát delší než pulsy bitu log.0 (o 855 T). 0511
SA-BIT-2
0514
SA-BIT-1
051A 051C
SA-SET SA-OUT
LD BIT DJNZ JR LD DJNZ OUT LD JR DEC XOR INC
A,C 7,B #0514,SA-BIT-1 NC,#051C,SA-OUT B,#42 #051A,SA-SET (#FE),A B,#3E NZ,#0511,SA-BIT-2 B A A
Druhý průchod; MIC off a žlutá. Indikátor nuly je 1 (při 2. průchodu). Hlavní časovací smyčka, 801 T při 2. průchodu. Skok na kratší průchod při tvorbě log.0. Při tvorbě log.1 o 855 T víc. Při 1. průchodu MIC on. Při 2. průchodu MIC off a žlutá. Čas. konstanta pro 2. průchod. Zpět na konec 1. průchodu, jinak puls 13 T. CY nastaven na 0. Registr A je 1; MIC on a modrá.
Smyčka 8 bitů: Reg. L obsahuje nahrávaný bajt a bit přenosu, CY je nastaven na jedna (jako návěští) z podprogramu SA-START. Každý bit je odeslán na výstup a CY nulován. Po osmi průchodech podprogramem bude registr L vynulován a program pokračuje dál. 0525
053C
SA-8-BITS
SA-DELAY
RL JP DEC INC LD LD IN RRA RET LD INC JP LD DJNZ RET
L NZ,#0514,SA-BIT-1 DE IX B,#31 A,#7F A,(#FE)
Bit 7 do CY a návěští do nulového bitu. Opakování do vynulování registru L. Sniž čítač bajtů. Posuň bázovou adresu o 1 dopředu. Nastav časovou konstantu pro první bit dalšího bajtu. Adresa brány pro klávesu BREAK a její otestování.
NC A,D A NZ,#04FE,SA-LOOP B,#3B #053C,SA-DELAY
Návrat (do SA/LD RET) v případě, že je BREAK. Jinak test čítače bajtů a skok zpět i když je čítač nulový. Návrat jestliže je čítač bajtů nastaven na #FFFF.
Poznámka: Vynulovaný bit způsobí puls MIC off následovaný pulsem MIC on, oba v délce 855T stavů. Jedničkový bit dává pulsy 2 krát delší. Povšimněte si, že mezi synchronizačním pulsem, indikačním bajtem a dalšími bajty nejsou žádné mezery.
Komentovaný výpis paměti ROM
23
PODPROGRAM SA/LD-RETROUTINE Je společný pro SAVE i LOAD. BORDER je nastaven na původní barvu a naposledy je testováno tlačítko BREAK. 053F
SA/LD-RET
0552
REPORT-D
0554
SA/LD-END
PUSH LD AND RRCA RRCA RRCA OUT LD IN RRA EI JR
AF A,(#5C48) #38
(BORDCR)
(#FE),A A,#7F A,(#FE)
C,#0554,SA/LD-END
RST #08,ERROR-1 DEFB #0C POP AF RET
Uložení CY (CY je resetováno při chybném LOADu). Vyzvednutí barvy ze systémové proměnné BORDCR.
Přenos barvy BORDER do bitů 2,1,0. Nastavení BORDERu na původní barvu. Test tlačítka BREAK
Povolení maskovaného přerušení. Není-li BREAK, skok. Ohlaš: D-BREAK-CONT repeats Obnovení původního stavu CY. Návrat.
PODPROGRAM LD-BYTES Tento podprogram je volán jako funkce LOAD nebo VERIFY hlavičky (z #076E) nebo dat (z #0802). 0556
LD-BYTES
INC EX DEC DI LD OUT LD PUSH IN RRA AND OR LD CP
D AF,AF’ D A,#0F (#FE),A HL,#053F HL A,(#FE) #20 #02 C,A A
Z flag je vynulován (neboť D nemůže obsahovat #FF). A=#00 - hlavička, A=#FF pro blok. CY=0 - VERIFY. CY=1 - LOAD. Registr D zpět na původní hodnotu. Zákaz přerušení. Bílý BORDER. Adresa SA/LD-RET na zásobník. Test brány #FE. Rotace načteného bajtu, ale zvážení jen bitu EAR. Signál BORDER červený je uložen i do registru C. (#22 pro OFF a #02 pro ON stav vstupu EAR) Nulový indikátor je nastaven na 1.
Prvním úkolem při čtení dat z pásku je zjistit, zda existuje nějaký pulsní signál (tedy hrany on-off a off-on). 056B 056C
LD-BREAK LD-START
RET NZ CALL #05E7,LD-EDGE-1 JR NC,#056B,LD-BREAK
Návrat při BREAKu. Není-li přítomen signál během 1400 T stavů, návrat s CY=1. Jinak je BORDER nastaven na cyan.
Dále se čeká a zjišťuje, zda je signál stále přítomen.
0574
24
LD-WAIT
LD DJNZ DEC LD OR JR CALL JR
HL,#0415 #0574,LD-WAIT HL A,H L NZ,#0574,LD-WAIT #05E3,LD-EDGE-2 NC,#056B,LD-BREAK
Délka čekání je téměř 1 sekunda.
Čekací smyčka. Pokračuj při zachycení dvou po sobě jdoucích hran v dané periodě. Komentovaný výpis paměti ROM
Nyní bude přijat jen zaváděcí signál. 0580
LD-LEADER
LD CALL JR LD CP JR INC JR
B,#9C #05E3,LD-EDGE-2 NC,#056B,LD-BREAK A,#C6 B NC,#056C,LD-START H NZ,#0580,LD-LEADER
Časovací konstanta, Pokračuj při zachycení dvou po sobě jdoucích hran v dané periodě. Tyto hrany musí být zachyceny během 3000 T. Počet párů hran je ukládán do reg. H dokud jich není 256.
Po zaváděcím signálu přicházejí části off a on pulsu sync. 058F
LD-SYNC
LD CALL JR LD CP JR CALL RET
B,#C9 #05E7,LD-EDGE-1 NC,#056B,LD-BREAK A,B #D4 NC,#058F,LD-SYNC #05E7,LD-EDGE-1 NC
Časovací konstanta. Každá hrana je testována, dokud nejsou nalezeny dvě hrany blízko sebe. (startovací puls sync).
Na konci musí být ještě konečná hrana části on synchronizačního pulsu sync.
Teď už se mohou načítat bajty hlavičky nebo programu (bloku dat) v operacích LOAD, VERIFY. První bajt určuje typ. LD XOR LD LD LD JR
A,C #03 C,A H,#00 B,#B0 #05C8,LD-MARKER
Smyčka čtení bajtu se používá datovými a na závěr bajt paritní. 05A9
LD-LOOP
05B3
LD-FLAG
EX JR JR LD JR RL XOR RET LD RRA LD INC JR
BORDER na modrou a žlutou.
Inicializace bajtu parity na 0. Časovací konstanta pro bajt určující typ. Skok do smyčky čtení bajtu. k načtení vždy
jednoho
bajtu. První
je
typový, následován
AF,AF’ NZ,#05B3,LD-FLAG NC,#05BD,LD-VERIFY (IX+00),L #05C2,LD-NEXT C L NZ A,C
Vyzvednutí indikátorů. Skok pro první (typový) bajt. Skok při VERIFY nahrávky. Uložení načteného bajtu na správnou adresu. Skok pro načtení dalšího bajtu. Dočasné uložení CY. Návrat když se typový bajt liší od typového bajtu z pásky; CY=0. CY je obnoveno na původní hodnotu.
C,A DE #05C4,LD-DEC
Čítač je zvětšen, aby bylo kompenzováno jeho zmenšení po odskoku.
Při VERIFYkaci je nově načtený bajt porovnán s původním: 05BD
LD-VERIFY
Nový
LD XOR RET
A,(IX+00) L NZ
Zjištění hodnoty původního bajtu a porovnání s právě načteným bajtem. Návrat, jestliže se oba bajty nerovnají.
bajt bude načten po jednotlivých bitech.
Komentovaný výpis paměti ROM
25
05C2 05C4
LD-NEXT LD-DEC
05C8
LD-MARKER
INC DEC EX LD LD
IX DE AF,AF’ B,#B2 L,#01
Zvýšení adresy pro uložení dalšího bajtu. Snížení čítače délky bloku. Uložení indikátorů. Časovací konstanta. Uložení značkového bitu.
Tato smyčka sestavuje načítaný bajt do registru L. 05CA
LD-8-BITS
CALL RET LD CP RL LD JP LD XOR LD
#05E3,LD-EDGE-2 NC A,#CB B L B,#B0 NC,#05CA,LD-8-BITS A,H L H,A
Nalezení délky pulsů jednotlivých bitů. Návrat při nesprávné (větší) délce pulsu, (pak CY=0) Porovnání délky oproti asi 2400 T, kdy pro nulový bit je CY=0 a pro jedničkový bit je CY=1. Uložení nového bitu do registru L. Časová konstanta pro další bit. Nejednalo-li se o poslední (osmý)bit skok zpět do smyčky. Vyzvedni paritní bajt z reg.H. a přidej nový bajt. Výsledek zpět do H.
Průchody se opakují do vynulování čítače DE, pak musí být i paritní bajt nulový. LD OR JR LD CP RET
A,D E NZ,#05A9,LD-LOOP A,H #01
Je-li DE nenulový, skok zpět pro další bajt. Test paritního bajtu. Je-li paritní bajt nulový - návrat s CY=1, jinak CY=0.
PODPROGRAMY LD-EDGE-2 A LD-EDGE-1 Tyto dva podprogramy jsou nejdůležitější částí operací LOAD a VERIFY. Vstupuje se do nich s časovou konstantou v registru B a barvou BORDERu i "typem hrany" v registru C. Návrat z těchto podprogramů je s CY=1, když požadovaný počet hran byl nalezen v povolené periodě - pak změna v registru B u CY=0 při chybě. Z flag=0 pokud byla stisknuta klávesa BREAK. Zflag=1 znamená "bez nálezu" a provede se návrat. LD-EDGE-2 slouží pro nalezení délky kompletního pulsu. LD-EDGE-1 slouží k určení času, který uplyne do nalezení hrany. 05E3
LD-EDGE-2
05E7 05E9
LD-EDGE-1 LD-DELAY
CALL RET LD DEC JR AND
#05E7,LD-EDGE-1 NC A,#16 A NZ,#05E9,LD-DELAY A
Zde se v podstatě volá ještě jednou LD-EDGE-1 a návrat pokud došlo k chybě. Čekání 358 T před vstupem do vzorkovací smyčky.
Následuje vzorkovací smyčka. Obsah registru B je zvýšen při každém průchodu. Návrat "bez nálezu" při dosažení 0 v reg. B. 05ED
26
LD-SAMPLE
INC RET LD IN RRA RET XOR AND JR
B Z A,#7F A,(#FE)
Čítání průchodů. CY=0 & Z=1 "bez nálezu". Čtení z brány #7FFE (BREAK a EAR).
NC C #20 Z,#05ED,LD-SAMPLE
CY=0 & Z=0, když byla stisknuta klávesa BREAK. Test bajtu s posledním typem hrany. Skok zpět, když je beze změny.
Komentovaný výpis paměti ROM
Byla nalezena nová 'hrana' ve stanovené době k hledání. Takže následuje změna barvy a nastavení CY flagu. LD CPL LD AND OR OUT SCF RET
A,C C,A #07 #08 (#FE),A
Změna posledního "typu hrany" a barvy BORDERu. Bere se jen barva BORDERu. Signál MIC-off. Změna barvy BORDERu červená/fialová nebo modrá/žlutá. Signalizace úspěšného nalezení před návratem.
Podprogram LD-EDGE-1 trvá 465T, plus 58T z každého průchodu vzorkovací smyčkou při neúspěšném hledání. Například při očekávání sync pulsu (viz. LD-SYNC na #058F) je povoleno 10 průchodů vzorkovací smyčkou. Hledání hrany probíhá během cca 1100T (465+10+58+přechody). Tak je zajištěno zachycení části off pulsu sync, který přichází po dlouhých pulsech zaváděcího signálu.
PODPROGRAMY PŘÍKAZU SAVE, LOAD, VERIFY, MERGE Užívá se jako vstupní bod pro všechny čtyři povely. Hodnota v T-ADDR se u jednotlivých funkcí liší. V první části podprogramu probíhá konstrukce hlavičky v pracovní oblasti. 0605
0621
0629
0642
SAVE-ETC
SA-SPACE
SA-BLANK
REPORT-F
POP LD SUB LD CALL CALL JR LD LD AND JR LD RST PUSH POP LD LD LD INC DJNZ LD CALL LD DEC ADD INC JR LD AND JR RST DEFB
AF A,(#5C74) {T-ADDR-lo} #E0 (#5C74),A {T-ADDR-lo} #1C8C,EXPT-EXP #2530,SYNTAX-Z Z,#0652,SA-DATA BC,#0011 A,(#5C74) {T-ADDR-lo} A Z,#0621,SA-SPACE C,#22 #30,BC-SPACES DE IX B,#0B A,#20 (DE),A DE #0629,SA-BLANK (IX+1),#FF #2BF1,STK-FETCH HL,#FFF6 BC HL,BC BC NC,#064B,SA-NAME A,(#5C74) {T-ADDR-lo} A NZ,#0644,SA-NULL #08,ERROR-1 #0E
Zničení návratové adresy SCAN-LOOP. Redukce T-ADDR-lo o #E0; pak je 00 pro SAVE, 01 pro LOAD, 02 pro VERIFY 03 pro MERGE. Uložení parametrů na zásobník kalkulátoru. Skok při testování syntaxe. 17 adres pro hlavičku SAVE, ale 34 pro ostatní povely.
Vytvoří se požadovaný prostor v pracovní oblasti. Předání parametrů z DE do IX. Název programu může mít až 10 znaků, ale nejdříve se uloží 11 mezer na připravené místo.
Nulové jméno jen při #FF. Parametry jména jsou vyvolány a je testována jeho délka. Tato hodnota je přímo -10 (doplněk). Není-li jméno delší než 10 pokračuje se dál.
Ale LOAD, VERIFY, MERGE jsou umožněny i při nulových nebo velmi dlouhých názvech. Ohlaš: F-Invalid file name
Pokračování práce se jménem programu:
Komentovaný výpis paměti ROM
27
0644
SA-NULL
LD OR JR LD
A,B C Z,#0652,SA-DATA BC,#000A
Skok dál, když je délka názvu nulová. Useknutí přebytečných znaků.
Nyní je název přenesen do WORKSPACE (od jeho druhé adresy): 064B
SA-NAME
PUSH POP INC EX LDIR
IX HL HL DE,HL
Přesun počáteční adresy do HL. Posun na druhou adresu. Výměna ukazatelů a přenos jména.
Dále jsou zvažovány některé parametry připojené za povel (pokud existují). 0652
0670
SA-DATA
REPORT-2
RST CP JR LD CP JP RST CALL SET JR LD LD DEC JR
#18,GET-CHAR #E4 NZ,#06A0,SA-SCR$ A,(#5C74) {T-ADDR-lo} #03 Z,#1C8A,REPORT-C #20,NEXT-CHAR #28B2,LOOK-VARS 7,C NC,#0672,SA-V-OLD HL,#0000 A,(#5C74) {T-ADDR-lo} A Z,#0685,SA-V-NEW
RST #08,ERROR-1 DEFB #01
Načtení znaku. Jedná se o znak "DATA" ? Skoč, když ne.
Není možný MERGE "název" DATA Načtení dalšího znaku a zvýšení syst. proměnné CH-ADD. Vyhledání řetězce v oblasti proměnných. Nastavení bitu 7 v názvu pole. Skok dopředu, jedná-li se o existující pole. Signál: užití nového pole. Porovnání obsahu T-ADDR a vyvolání chybového hlášení, když bylo požadováno SAVE nebo VERIFY nového pole. Ohlaš: 2-Variable not found
Pokračování v práci s existujícím polem: 0672
SA-V-OLD
JP CALL JR INC LD LD INC LD LD INC
NZ,#1C8A,REPORT-C #2530,SYNTAX-Z Z,#0692,SA-DATA-1 HL A,(HL) (IX+11),A HL A,(HL) (IX+12),A HL
Skok dopředu při kontrole syntaxe. Nižší bajt délky pole je přesouván do pracovní oblasti a je následován příslušným vyšším bajtem délky pole.
Další část je společná pro "nová" i "stará" pole. 0685
068F
SA-V-NEW
SA-V-TYPE
LD LD BIT JR INC LD
(IX+14),C A,#01 6,C Z,#068F,SA-V-TYPE A (IX+0),A
Kopie jména pole. Je pole číselné? Skok, když je číselné. Je znakové. Uložení typu na první adresu hlavičkové oblasti.
Test poslední části příkazu. 0692 28
SA-DATA-1
EX
DE,HL
Uložení ukazatele do DE. Komentovaný výpis paměti ROM
RST CP JR RST CALL EX JP
#20,NEXT-CHAR #29 NZ,#0672,SA-V-OLD #20,NEXT-CHAR #1BEE,CHECK-END DE,HL #075A,SA-ALL
Načtení dalšího znaku a zvýšení syst. proměnné CH-ADD. Je konec závorky ")" ? Hlášení "REPORT-C" když ne. Načtení dalšího znaku a zvýšení syst. proměnné CH-ADD. Pokračuj na další část příkazu při zjišťování syntaxe. Ukazatel zpět do HL (indikuje začátek obsahu existujícího pole).
Test na token SCREEN$. 06A0
SA-SCR$
CP JR LD CP JP RST CALL LD LD LD LD LD JR
#AA NZ,#06C3,SA-CODE A,(#5C74) {T-ADDR-lo} #03 Z,#1C8A,REPORT-C #20,NEXT-CHAR #1BEE,CHECK-END (IX+11),#00 (IX+12),#1B HL,#4000 (IX+13),L (IX+14),H #0710,SA-TYPE-3
Není-li token SCREEN$, skok dopředu.
Je zakázáno MERGE "název" SCREEN$ Vyzvednutí následujícího znaku a zvýšení CH-ADD. Posun na další část příkazu při zjišťování syntaxe. Do hlavičky je ukládán počet nahrávaných bajtů, což je pro obrazovou paměť právě #1B00. Adresa 1. bajtu obrazové paměti je právě #4000. A toto číslo je také uloženo mezi hlavičkové údaje.
Test na token CODE. 06C3
SA-CODE
CP JR LD CP JP RST CALL JR LD AND JP CALL JR
#AF NZ,#0716,SA-LINE A,(#5C74) {T-ADDR-lo} #03 Z,#1C8A,REPORT-C #20,NEXT-CHAR #2048,PR-ST-END NZ,#06E1,SA-CODE-1 A,(#5C74) {T-ADDR-lo} A Z,#1C8A,REPORT-C #1CE6,USE-ZERO #06F0,SA-CODE-2
Není-li token CODE, skok dopředu.
Není dovoleno MERGE "název" CODE Vyzvednutí následujícího znaku a zvýšení CH-ADD. Skok, když příkaz pokračuje.
Není povoleno SAVE "název" CODE bez uvedení parametrů. Uložení 0 na zásobník kalkulátoru pro startovací adresu.
Hledání startovací adresy. 06E1
06F0
SA-CODE-1
SA-CODE-2
CALL RST CP JR LD AND JP
#1C82,EXPT-1NUM #18,GET-CHAR #2C Z,#06F5,SA-CODE-3 A,(#5C74) {T-ADDR-lo} A Z,#1C8A,REPORT-C
CALL #1CE6,USE-ZERO JR
Vyzvedni 1. číslo za CODE. Následuje-li další číslo skok dopředu, první číslo bylo startovací adresou.
Není povoleno SAVE CODE bez parametrů, startovací adresy a délky. Uložení nuly do kalkulátorového zásobníku pro počet bajtů.
#06F9,SA-CODE-4
Zjištění počtu bajtů. 06F5
SA-CODE-3
RST #20,NEXT-CHAR CALL #1C82,EXPT-1NUM
Vyzvednutí následujícího znaku a zvýšení CH-ADD. Zjištění počtu bajtů.
Komentovaný výpis paměti ROM
29
Parametry jsou uloženy do hlavičkové části pracovní oblasti. 06F9
SA-CODE-4
CALL CALL LD LD CALL LD LD LD LD
#1BEE,CHECK-END #1E99,FIND-INT2 (IX+11),C (IX+12),B #1E99,FIND-INT2 (IX+13),C (IX+14),B H,B L,C
Posun na další část příkazu při zjišťování syntaxe. Přenos délky do BC. a její uložení do hlavičky. Přenos startovací adresy do BC a její uložení do hlavičky. Přenos ukazatele do HL jako obvykle.
SCREEN$ a CODE jsou oba typu 3. 0710
SA-TYPE-3
LD JR
(IX+0),#03 #075A,SA-ALL
Nyní vlož číslo pro typ bloku dat. Vrať se na dráhu.
Zjištění přítomnosti LINE a dalších možných parametrů. 0716
SA-LINE
CP JR CALL LD JR
#CA Z,#0723,SA-LINE-1 #1BEE,CHECK-END (IX+14),#80 #073A,SA-TYPE-0
Je-li token LINE, skok dopředu. Posun na další část povelu při zjišťování syntaxe. Už nejsou další parametry.
Zjištění čísla, které musí následovat po výrazu LINE. 0723
SA-LINE-1
LD AND JP RST CALL CALL CALL LD LD
A,(#5C74) {T-ADDR-lo} A NZ,#1C8A,REPORT-C #20,NEXT-CHAR #1C82,EXPT-1NUM #1BEE,CHECK-END #1E99,FIND-INT2 (IX+13),C (IX+14),B
Nelze provádět SAVE "název" LINE bez udání čísla. Vyzvednutí následujícího znaku a zvýšení CH-ADD. Uložení čísla do kalkulátorového zásobníku. Posun na další část povelu při zjišťování syntaxe. Přenos čísla řádku autostartu do BC a jeho uložení.
LINE a žádný parametr jsou oba typu 0. 073A
SA-TYPE-0
LD
(IX+00),#00
Uložení čísla typu.
Parametry určující program a jeho proměnné jsou nalezeny a uloženy do hlavičkové části pracovní oblasti. LD LD SCF SBC LD LD LD SBC LD LD EX
HL,(#5C59) {E-LINE} DE,(#5C53) {PROG} HL,DE (IX+11),L (IX+12),H HL,(#5C4B) {VARS} HL,DE (IX+15),L (IX+16),H DE,HL
Ukazatel konce oblasti proměnných. Ukazatel počátku basicového programu. Odečet pro určení délky programu + proměnných a její uložení. Opakování odečtu, ale jen pro zjištění délky samotného programu.
Přesun ukazatele do HL.
Ve všech případech byly připraveny hlavičkové informace. 30
Komentovaný výpis paměti ROM
IX+0 IX+1 až IX+10 IX+11 a IX+12 IX+13 až IX+16
Obsahuje Obsahuje Obsahuje Obsahuje
číslo jméno počet různé
typu dat. (#FF v IX+1 znamená data beze jména). bajtů bloku dat. parametry, jejichž obsah záleží na typovém čísle.
Nyní se separuje jedna z operací SAVE, LOAD, VERIFY nebo MERGE. 075A
SA-ALL
LD AND JP
A,(#5C74) {T-ADDR-lo} A Je-li povel SAVE Z,#0970,SA-CONTRL skoč dopředu
V případě zbylých tří operací je prvních 17 bajtů hlavičkové části pracovní oblastí vybaveno informacemi, jak uvedeno výše. Teď je čas pro odebrání hlavičky z pásku. PUSH HL LD BC,#0011 ADD IX,BC
Uložení ukazatele adresy určení. Formování 1. adresy 2.hlavičkové oblasti do IX.
Smyčka pro načtení hlavičky. 0767
LD-LOOK-H
PUSH LD XOR SCF CALL POP JR
IX DE,#0011 A #0556,LD-BYTES IX NC,#0767,LD-LOOK-H
Uložení 1. adresy 2. hlavičkové oblasti. LOAD 17ti bajtů. Signál: hlavička. Signál: LOAD. Hledání hlavičky. Obnovení 1. adresy 2.hlavičkové oblasti. Skoky dokud neskončeno.
Nová hlavička se vypíše na obrazovce, ale podprogram pokračuje jen tehdy, když se "nový" typ neliší od "starého":
078A
LD-TYPE
LD CALL LD LD LD CP JR LD CP JR
A,#FE #1601,CHAN-OPEN (IY+82),#03 {SCR-CT} C,#80 A,(IX+0) (IX-17) NZ,#078A LD-TYPE C,#F6 #04 NC,#0767 LD-LOOK-H
Ujištění, že kanál S je otevřen. Nastavení čítače skrolování. Signál: typy se neliší. Porovnání "nového" typu se "starým". Liší-li se, skoč. Když OK., tak dej signál: 10 znaků a porovnej je. Je-li číslo "typu 4" a více, je hlavička nesmyslná a odskakuje se.
Objeví se jedno z hlášení: Program:, Number array:, Character array:, Bytes: LD PUSH CALL POP
DE,#09C0 BC #0C0A,PO-MSG BC
První adresa bloku uvedených hlášení. Uložení registru C, dokud není zobrazeno. Patřičné hlášení se zobrazí.
Zobrazí se nové jméno a potom se toto porovná se starým. PUSH POP LD ADD LD LD
IX DE HL,#FFF0 HL,DE B,#0A A,(HL)
Registrový pár DE bude ukazovat na nový typ a registrový pár HL na staré jméno. 10 znaků jména. Znak z názvu
Komentovaný výpis paměti ROM
31
INC JR LD ADD LD
A NZ,#07A6,LD-NAME A,C A,B C,A
je to #FF ? ne - porovnávat dál Pokud je staré jméno prázdné indikovat signál všechny znaky souhlasí.
Následující smyčka tiskne znaky nového jména. Pokud toto jméno souhlasí, je při výstupu ze smyčky čítač nulový. 07A6
07AD
LD-NAME
LD-CH-PR
INC LD CP INC JR INC RST DJNZ BIT JR LD RST
DE A,(DE) (HL) HL NZ,#07AD,LD-CH-PR C #10,PRINT-A-1 #07A6,LD-NAME 7,C NZ,#0767,LD-LOOK-H A,#0D #10,PRINT-A-1
Znak nového jména porovnat se starým nečítat pokud písmeno nesouhlasí. Tisknout znak jména. Opakovat pro všech deset znaků. Jméno souhlasilo pokud je čítač nulový. Nové jméno ukončit znakem CR.
Hlavička souboru odpovídá požadované hlavičce. Dále se rozlišuje, zda se bude provádět LOAD, VERIFY nebo MERGE. POP LD CP JR LD DEC JP CP JP
HL A,(IX+0) #03 Z,#07CB,VR-CONTRL A,(#5C74) (T-ADDR-lo) A Z,#0808,LD-CONTRL #02 Z,#08B6,ME-CONTRL
Obnovit ukazatel. SCREEN$ a CODE jsou ošetřeny podprogramem pro VERIFY. Je požadována funkce LOAD ? Je požadována funkce MERGE ? Pokud ne zbývá pouze VERIFY.
PODPROGRAM ŘÍZENÍ "VERIFY" Proces ověřování probíhá podobně jako čtení, s tím rozdílem, že data se neukládají, ale pouze ověřují. Tento podprogram je také používán při čtení bloku dat. 07CB
07E9
32
VR-CONTRL
VR-CONT-1
PUSH LD LD LD LD LD OR JR SBC JR JR LD CP JR POP LD OR JR
HL L,(IX-06) H,(IX-05) E,(IX+11) D,(IX+12) A,H L Z,#07E9,VR-CONT-1 HL,DE C,#0806,REPORT-R Z,#07E9,VR-CONT-1 A,(IX+00) #03 NZ,#0806,REPORT-R HL A,H L NZ,#07F4,VR-CONT-2
Ulož ukazatel. Vyzvedni počet bajtů ze staré hlavičky. Počet bajtů z nové hlavičky. Skoč dopředu v případě, že délka není určena. T.j. příkaz 'LOAD jméno CODE'. Vypiš chybu R v případě, že blok dat je větší než je požadováno. Délky jsou shodné - v pořádku. Chybové hlášení R se také vypíše, pokud se pokusíme ověřovat bloky s nestejnou délkou. Obnovení ukazatele (kam se bude ukládat). Tento ukazatel se použije, pokud není roven nule. V tom případě se totiž místo něho použije Komentovaný výpis paměti ROM
LD LD
L,(IX+13) H,(IX+14)
hodnota z nové hlavičky.
Nyní se podle příznaku VERIFY/LOAD provede buď načtení nebo ověření. 07F4
0800
VR-CONT-2
VR-CONT-3
PUSH POP LD CP SCF JR AND LD
HL IX A,(#5C74) (T-ADDR-lo) #02 NZ,#0800,VR-CONT-3 A A,#FF
Přesuň pointer do registrového páru IX. Nastavit příznak pro zpracování bloku dat. A to buď příznak LOAD, nebo příznak VERIFY. Příznak pro zpracování pouze datového bloku.
PODPROGRAM PRO PŘEČTENÍ BLOKU DAT Tento podprogram je společný pro všechny čtecí podprogramy. 0802
LD-BLOCK
CALL #0556,LD-BYTES RET C
LOAD/VERIFY bloku dat. Pokud není chyba - návrat.
Chybové hlášení R - Tape loading error. 0806 REPORT-R
RST #08,ERROR-1 DEFB #1A
Zavolej hlášení chyby.
PODPROGRAM PRO ŘÍZENÍ PŘÍKAZU LOAD Tento podprogram řídí čtení basicovského programu včetně proměnných. 0808
LD-CONTRL
LD LD PUSH LD OR JR INC INC INC EX JR
E,(IX+11) D,(IX+12) HL A,H L NZ,#0819,LD-CONT-1 DE DE DE DE,HL #0825,LD-CONT-2
Vyzvedni délku bloku z nové hlavičky. Uložit cílový ukazatel. Skoč dopředu v případě pokusu o načtení dosud nedeklarovaného pole. Přidej tři bajty pro novou proměnnou. Místo pro jméno a délku nové proměnné. Skoč dopředu.
Nyní je tedy v paměti dost místa pro blok dat. 0819
LD-CONT-1
LD LD EX SCF SBC JR
L,(IX-06) H,(IX-05) DE,HL HL,DE C,#082E,LD-DATA
Vezmi délku existujícího programu včetně proměnných. Skoč dopředu pokud není vyžadována žádná paměť navíc.
Otestuj volné místo. 0825
LD-CONT-2
LD ADD LD LD CALL
DE,#0005 HL,DE B,H C,L #1F05,TEST-ROOM
Komentovaný výpis paměti ROM
5 bajtů navíc. Výsledek do BC. Otestuj. 33
082E
LD-DATA
POP LD AND JR LD OR JR DEC LD DEC LD DEC INC INC INC LD CALL LD
HL A,(IX+0) A Z,#0873,LD-PROG A,H L Z,#084C,LD-DATA-1 HL B,(HL) HL C,(HL) HL BC BC BC (#5C5F),IX {X-PTR} #19E8,RECLAIM-2 IX,(#5C5F) {X-PTR}
Vyzvedni ukazatel. Skoč dopředu pokud se čte basicovský program. Skoč dopředu pokud se čte nové pole. Vezmi délku existujícího pole
Ukazatel posuň na jméno. Přičti tři bajty pro délku a název.
Ulož registr IX po dobu rušení staré proměnné.
Nyní je vyhrazeno místo pro novou proměnnou - na konci platné oblasti pro data. 084C
LD-DATA-1
LD DEC LD LD PUSH INC INC INC LD PUSH CALL INC POP LD POP INC LD INC LD INC PUSH POP SCF LD JP
HL,(#5C59) {E-LINE} HL C,(IX+11) B,(IX+12) BC BC BC BC A,(IX-3) AF #1655,MAKE-ROOM HL AF (HL),A DE HL (HL),E HL (HL),D HL HL IX A,#FF #0802,LD-BLOCK
Nalezení konce oblasti proměnných, který je označen bajtem #80. Do BC je uložena délka nového pole, která je okamžitě uschována. Nyní se přičtou tři bajty pro jméno a délku pole. Je zjištěn název pole a okamžitě uschován. Je vytvořen prostor v počtu bajtů udaných registry BC. HL nyní ukazuje na 1. bajt pole, kam bude po zjištění uloženo jeho jméno. Opět je vyzvednuta délka pole
a po bajtech uložena. HL nyní ukazuje na adresu, kam bude ukládán již samotný obsah pole. Tato adresa je zároveň okamžitě přenesena do IX. Signál: LOAD. Signál: blok dat. Je proveden odskok na LOADovací podprogram.
LOAD BASICového programu a jeho proměnných: 0873
34
LD-PROG
EX LD DEC LD LD LD PUSH CALL POP
DE,HL HL,(#5C59) {E-LINE} HL (#5C5F),IX {X-PTR} C,(IX+11) B,(IX+12) BC #19E5,RECLAIM-1 BC
Uschování 1. adresy programu do DE. Nalezení konce oblasti proměnných, který je označen bajtem #80. Uschování IX. Do BC je uložena délka programu a okamžitě uschována. Podprogram zničí starý existující BASICový program. Délka nového programu je opět uložena do BC. Komentovaný výpis paměti ROM
PUSH PUSH CALL LD INC LD LD ADD LD LD LD AND JR LD LD LD
HL BC #1655,MAKE-ROOM IX,(#5C5F) {X-PTR} HL C,(IX+15) B,(IX+16) HL,BC (#5C4B),HL {VARS} H,(IX+14) A,H #C0 NZ,#08AD,LD-PROG-1 L,(IX+13) (#5C42),HL {NEWPPC} (IY+10),#00 {NSPPC}
Jsou uschovány ukazatele programové oblasti a délky programu. Vytvoření nového místa pro program a jeho proměnné. V IX je obnovena jeho původní hodnota.
Systémová proměnná VARS je nastavena na novou hodnotu, která již odpovídá parametrům nového programu. Je testováno, zda byl přítomen příkaz LINE. Odskok jestliže se nejedná o autostart. Jinak jsou nastaveny systémové proměnné NEWPPC a NSPPC.
Nyní může být načten blok dat: 08AD
LD-PROG-1
POP POP SCF LD JP
DE IX A,#FF #0802,LD-BLOCK
Je vyzvednuta délka a adresa 1.bajtu programu. Signál: LOAD. Signál: blok dat. A nahraj ho.
PODPROGRAM ŘÍZENÍ MERGE Tento podprogram se skládá ze tří částí: a) LOAD bloku dat do oblasti WORKSPACE. b) MERGE řádků nového programu mezi řádky starého programu. c) MERGE nových proměnných do starých proměnných. Začíná se s načtením bloku dat. 08B6
ME-CONTRL
LD LD PUSH INC RST LD EX POP PUSH PUSH POP SCF LD CALL
C,(IX+11) B,(IX+12) BC BC #30,BC-SPACES (HL),#80 DE,HL DE HL HL IX A,#FF #0802,LD-BLOCK
Načti délku bloku do BC a uschovej ji. Vytvoř prostor o délce LEN+1 v pracovním prostoru a do bajtu "navíc" vlož koncový znak. Přesun ukazatele startu do HL. Vyzvedni původní délku. Uschovej kopii startu. A převeď start do IX. Signál: LOAD. Signál: blok dat. Proveď LOAD bloku dat.
Nyní dojde k splynutí řádků nového a starého programu. POP HL LD DE,(#5C53)
{PROG}
Vyzvedni start nového programu. Vyzvedni start starého programu.
Vstup do smyčky, která zpracovává řádky nového programu. 08D2
ME-NEW-LP
LD
A,(HL)
Vyzvedni číslo řádku
Komentovaný výpis paměti ROM
35
AND #C0 JR NZ,#08F0,ME-VAR-LP
a testuj je. Skok, když jsou řádky skončeny.
Vstup do vnitřní smyčky, která zpracovává řádky starého programu. 08D7
ME-OLD-LP
08DF
ME-OLD-L1
08EB
ME-NEW-L2
LD INC CP INC JR LD CP DEC DEC JR
A,(DE) DE (HL) HL NZ,#08DF,ME-OLD-L1 A,(DE) (HL) DE HL NC,#08EB,ME-NEW-L2
PUSH EX CALL POP JR CALL JR
HL DE,HL #19B8,NEXT-ONE HL #08D7,ME-OLD-LP #092C,ME-ENTER #08D2,ME-NEW-LP
Vyzvedni vyšší bajt čísla řádku a porovnej jej s novým inkrementuj ukazatele. Skok dopředu, není-li shoda. Opakuj porovnání také pro nižší bajty čísla řádku. Obnov oba ukazatele. Skok při nalezení správného místa pro řádek nového programu. Jinak najdi adresu začátku dalšího starého řádku. Procházej smyčkou pro každý starý řádek. Vlož nový řádek a skoč zpět do hlavní smyčky.
Obdobným způsobem budou nyní splývat nové a staré proměnné. 08F0
ME-VAR-LP
LD LD CP RET PUSH LD
A,(HL) C,A #80 Z HL HL,(#5C4B)
{VARS}
Vyzvedni postupně jména všech proměnných a testuj je. Test na konec a návrat, když byly všechny proměnné posouzeny. Uschovej ukazatel. Vyzvedni VARS (pro starý program).
Nyní vstup do smyčky, kde se naleznou všechny existující proměnné. 08F9
ME-OLD-VP
0901
ME-OLD-V1
LD CP JR CP JR PUSH CALL POP EX JR
A,(HL) #80 Z,#0923,ME-VAR-L2 C Z,#0909,ME-OLD-V2 BC #19B8,NEXT-ONE BC DE,HL #08F9,ME-OLD-VP
Vyzvedni jméno proměnné. Jakmile je nalezen koncový bajt, proveď skok dopředu (bude se přidávat). Porovnej první bajt názvů a skoč dopředu pro další posouzení. Uschovej název nové proměnné a hledej další starou proměnnou. Obnov ukazatele. a pokračuj ve smyčce.
Stará a nová proměnná se shodují podle prvních bajtů, ale proměnné s dlouhými názvy je třeba porovnat celé. 0909
ME-OLD-V2
AND CP JR POP PUSH PUSH
#E0 #A0 NZ,#0921,ME-VAR-L1 DE DE HL
V úvahu se vezmou pouze bity 7,6 a 5. Akceptuj všechny typy proměnných, kromě proměnných s dlouhým názvem. DE bude ukazovat na první znak názvu nové proměnné a bude uschován. Úschova ukazatele na první znak názvu staré proměnné.
Vstup do smyčky k porovnání všech znaků názvu dlouhé proměnné.
36
Komentovaný výpis paměti ROM
0912
091E
ME-OLD-V3
ME-OLD-V4
INC INC LD CP JR RLA JR POP JR POP JR
HL DE A,(DE) (HL) NZ,#091E,ME-OLD-V4 NC,#0912,ME-OLD-V3 HL #0921,ME-VAR-L1 HL #0901,ME-OLD-V1
Posuň oba ukazatele. Porovnej oba znaky a skoč, jestliže se neshodují. Dokud není nalezen poslední znak, pokračuj ve smyčce. Vyzvedni ukazatel na první znak názvu staré proměnné a skoč s úspěšným nálezem dopředu. Vyzvedni ukazatel na první znak názvu staré proměnné a skoč s neúspěšným nálezem zpět.
Zde je vstup pro shodu. 0921
ME-VAR-L1
LD
A,#FF
Signál: náhrada proměnné.
Zde je vstup pro neshodu. A obsahuje #80 což je signál, že proměnná má být přidána. 0923
ME-VAR-L2
POP EX INC SCF CALL JR
DE DE,HL A #092C,ME-ENTER #08F0,ME-VAR-LP
Vyzvedni ukazatel na první znak názvu nové proměnné. Zaměň registry. Z flag=1 jde-li o náhradu a Z flag=0 jde-li o přidání. Signál: proměnná. Nyní proveď vložení. Pokračuj ve smyčce a posuzuj další proměnnou.
MERGE řádky nebo proměnné Do tohoto podprogramu se vstupuje s následujícími parametry: CY=0 - MERGE basicového řádku. CY=1 - MERGE proměnné. Z flag=0 - Bude se přidávat. Z flag=1 - Bude se nahrazovat. HL ukazuje na start nového vstupu. DE ukazuje kam se provede MERGE. 092C
ME-ENTER
JR EX LD EX CALL CALL EX LD EX
NZ,#093E,ME-ENT-1 AF,AF' (#5C5F),HL {X-PTR} DE,HL #19B8,NEXT-ONE #19E8,RECLAIM-2 DE,HL HL,(#5C5F) {X-PTR} AF,AF'
Skoč, jde-li o "přídavek". Uschovej příznaky. Uschovej "nový" ukazatel, zatímco bude provedena likvidace řádku nebo proměnné. Obnov všechny ukazatele a příznaky.
Nyní může dojít k vložení "nového". 093E
ME-ENT-1
EX PUSH CALL LD LD EX PUSH EX JR DEC CALL INC JR
AF,AF’ DE #19B8,NEXT-ONE (#5C5F),HL {X-PTR} HL,(#5C53) {PROG} (SP),HL BC AF,AF’ C,#0955,ME-ENT-2 HL #1655,MAKE-ROOM HL #0958,ME-ENT-3
Uschovej příznaky. Uschovej cílový ukazatel. Nalezni délku "nového". Uschovej ukazatel na "nové". Vyzvedni PROG aby se předešlo poškození. Uschovej PROG na zásob. a současně vyzvedni ukaz. nov. Uschovej délku. Obnov příznaky. Skoč, jestliže přidáváš novou proměnnou. Nový řádek je vložen před cílovou lokaci. Vytvoř prostor pro nový řádek. Skoč dopředu.
Komentovaný výpis paměti ROM
37
0955 0958
ME-ENT-2 ME-ENT-3
CALL INC POP POP LD LD PUSH PUSH EX LDIR
#1655,MAKE-ROOM HL BC DE (#5C53),DE {PROG} DE,(#5C5F) {X-PTR} BC DE DE,HL
Vytvoř prostor pro novou proměnnou. Ukazuj na první novou lokaci. Obnov délku. Vyzvedni PROG a ulož na patřičné místo. Také vyzvedni "nový" ukazatel a opět ulož délku a "nový" ukazatel. Zaměň ukazatele a kopíruj "nové" do prostoru, který byl vytvořen.
Nová proměnná nebo řádek musí být nyní odstraněny z pracovního prostoru. POP POP PUSH CALL POP RET
HL BC DE #19E8,RECLAIM-2 DE
Vyzvedni ukazatel na "nové". Vyzvedni délku. Uschovej ukazatel na "staré". Odstraň řádek nebo proměnnou z pracovního prostoru. Vyzvedni ukazatel na "staré" a vrať se.
PODPROGRAM ŘÍZENÍ SAVE Podprogram SAVE je velmi pochopitelný. 0970
SA-CONTRL
PUSH LD CALL XOR LD CALL SET CALL
HL A,#FD #1601,CHAN-OPEN A DE,#09A1 #0C0A,PO-MSG 5,(IY+2) (TV-FLAG) #15D4,WAIT-KEY
Uschovej si ukazatel. Signál: kanál K. Otevři kanál K. Signál 1. hlášení. Báze tabulky kazetových hlášení. Tiskni hlášení: Start tape, then press any key. Signál: obrazovka bude vyžadovat smazání. Čekej na stlačení klávesy.
Po stisknutí tlačítka se začne nahrávat hlavička. PUSH IX Uschovej si adresu hlavičky. LD DE,#0011 Počítadlo 17ti bajtů, které budou nahrány. XOR A Signál: hlavička. CALL #04C2,SA-BYTES Nahrání hlavičky. POP IX Obnovení adresy hlavičky Následuje pauza asi jednu sec. před nahráním dat.
0991
38
SA-1-SEC
LD HALT DJNZ LD LD LD POP JP
B,#32 #0991,SA-1-SEC E,(IX+11) D,(IX+12) A,#FF IX #04C2,SA-BYTES
Pauza 50ti přerušení. Do DE je vložena délka zaznamenávaného bloku dat. Signál: blok dat. Obnovení ukazatele 1. adresy bloku a konečně se všechno nahraje!
Komentovaný výpis paměti ROM
TEXTY POUŽÍVANÉ PŘI PRÁCI S KAZETOU Každé hlášení je zakončeno invertovaným znakem, tzn.: bit 7 tohoto znaku je logická 1. Bajt #0D (carriage return) způsobí tisk od levého okraje na dalším řádku. 09A1 09A2 09C1 09CB 09DA 09EC
DEFB DEFM DEFM DEFM DEFM DEFM
#80 'Start tape, then press any key.' #0D,'Program:‘ #0D,'Number array:' #0D,'Character array:' #0D,'Bytes:'
Komentovaný výpis paměti ROM
39
PODPROGRAMY OBSLUHUJÍCÍ TISK NA OBRAZOVKU A TISKÁRNU
PODPROGRAM PRINT-OUT Veškerý tisk na hlavní část obrazovky, dolní část obrazovky a na tiskárnu obstarávají následující podprogramy. Do podprogramu PRINT-OUT vstupuje kód znaku, kontrolního znaku, nebo tokenu v registru A. 09F4
PRINT-OUT
CALL CP JP CP JR CP JR LD LD LD ADD LD ADD PUSH JP
#0B03,PO-FETCH #20 NC,#0AD9,PO-ABLE #06 C,#0A69,PO-QUEST #18 NC,#0A69,PO-QUEST HL,#0A0B E,A D,#00 HL,DE E,(HL) HL,DE HL #0B03,PO-FETCH
Aktuální tisková pozice. Jestliže se jedná o znak který lze tisknout, provede se skok. Tiskni otazník pro hodnoty #00 až #05 a pro hodnoty #18 až #1F. Báze "řídící" tabulky. Převeď kód do registrového páru DE. Indexuj v tabulce a vyzvedni doplněk. Přičti doplněk a proveď nepřímý skok do příslušného podprogramu.
TABULKA ŘÍDÍCÍCH ZNAKŮ adresa 0A11 0A12 0A13 0A14 0A15 0A16 0A17 0A18 0A19
doplněk 4E 57 10 29 54 53 52 37 50
znak PRINT čárka EDIT kurzor vlevo kurzor vpravo kurzor dolů kurzor nahoru DELETE ENTER nevyužito
adresa 0A1A 0A1B 0A1C 0A1D 0A1E 0A1F 0A20 0A21 0A22
doplněk 4F 5F 5E 5D 5C 5B 5A 54 53
znak nevyužito INK PAPER FLASH BRIGHT INVERSE OVER AT TAB
PODPROGRAM KURZOR VLEVO Na vstupu obsahuje registr B číslo aktuálního řádku a registr C číslo aktuálního sloupce. 0A23
0A38 0A3A
40
PO-BACK-1
PO-BACK-2 PO-BACK-3
INC LD CP JR BIT JR INC LD LD CP JR DEC LD JP
C A,#22 C NZ,#0A3A,PO-BACK-3 1,(IY+1) (FLAGS) NZ,#0A38,PO-BACK-2 B C,#02 A,#18 B NZ,#0A3A,PO-BACK-3 B C,#21 #0DD9,CL-SET
Pohyb doleva o jeden sloupec. Akceptuj tuto změnu pokud nepřevýší max. hodnotu pro levou stranu. Při obsluze tiskárny skok dopředu. Jeden řádek nahoru. Nastav sloupcovou hodnotu. Testuj na nejvyšší řádek. Poznámka: správně mělo být #19. Akceptuj změnu, pokud není vrchol obrazovky. Nepřijatelné, takže o řádek dolů. Nastav na levou krajní pozici. Proveď nepřímý návrat přes CL-SET & PO-STORE.
Komentovaný výpis paměti ROM
PODPROGRAM KURZOR VPRAVO Tento podprogram provede identickou operaci jako basicové PRINT OVER 1; CHR$ 32;. 0A3D
PO-RIGHT
LD PUSH LD LD CALL POP LD RET
A,(#5C91) (P-FLAG) AF (IY+87),#01 (P-FLAG) A,#20 #0B65,PO-CHAR AF (#5C91),A (P-FLAG)
Vyzvedni P-FLAG a uschovej na zásobníku. Nastav P-FLAG na OVER 1. Tiskni mezeru. Obnov původní hodnotu pro P-FLAG. Poznámka: Programátor zapomněl na návrat přes PO-STORE.
PODPROGRAM "NÁVRATU VOZÍKU" Jestliže se jedná o výstup na tiskárnu, provede se vyprázdnění bafru. Při výstupu na obrazovku se bude testovat rolování obrazovky před snížením čísla řádku. 0A4F
PO-ENTER
BIT JP LD CALL DEC JP
1,(IY+1) (FLAGS) NZ,#0ECD,COPY-BUFF C,#21 #0C55,PO-SCR B #0DD9,CL-SET
Při obsluze tiskárny skok dopředu. Nastav levý krajní sloupec. Je-li potřeba roluj obrazovku. Nyní o řádek dolů. Nepřímý návrat přes CL-SET & PO-STORE.
PODPROGRAM TISKNI ČÁRKU Současná sloupcová hodnota je manipulována a registr A je nastaven na #00 pro TAB 0, nebo #10 pro TAB 16. 0A5F
PO-COMMA
CALL LD DEC DEC AND JR
#0B03,PO-FETCH A,C A A #10 #0AC3,PO-FILL
Proč znovu? Číslo sloupce. Posun doprava o dva sloupce a test. V registru A bude nyní #00 nebo #10. Výstup přes PO-FILL.
PODPROGRAM TISK OTAZNÍKU Kdykoliv dojde k pokusu o tisk znaku, který tisknout nelze, vytiskne se místo něj otazník. 0A69
PO-QUEST
LD JR
A,#3F #0AD9,PO-ABLE
Kód pro otazník. Tisk znaku.
PODPROGRAM PRO TISK ŘÍDÍCÍCH ZNAKŮ S OPERANDY Řídící znaky od INK do OVER vyžadují jeden operand, zatímco řídící znaky AT & TAB musí být následovány dvěma operandy. Tento podprogram v případě jednoho operandu uloží kód řídícího znaku do TVDATA-lo a operand je v registru A. V případě dvou operandů je prvý operand uložen do TVDATA-hi a druhý v registru A. 0A6D
PO-TV-2
LD LD JR
DE,#0A87 Změna adresy pro "výstupní podprogram" na #0A87,PO-CONT. (#5C0F),A (TVDATA-hi) Ulož první operand do TVDATA-hi. #0A80,PO-CHANGE
Pro AT a TAB je vstupní bod zde. 0A75
PO-2-OPER
LD JR
DE,#0A6D #0A7D,PO-TV-1
Změna adresy pro "výstupní podprogram" na #0A6D,PO-TV-2. a ulož kód znaku do TVDATA-lo.
Komentovaný výpis paměti ROM
41
Vstupní bod pro řídící znaky barev INK až OVER. 0A7A 0A7D
PO-1-OPER PO-TV-1
LD LD
DE,#0A87 Změna adresy pro "výstupní podprogram" na #0A87,PO-CONT. (#5C0E),A (TVDATA-lo) Ulož kód řídícího znaku.
Adresa "výstupního" podprogramu je změněna přechodně. 0A80
PO-CHANGE
LD LD INC LD RET
HL,(#5C51) (CURCHL) (HL),E HL (HL),D
HL ukazuje na adresu výstupního podprogramu. Vložení této nové adresy způsobí, že další kód bude považován za operand.
Jakmile jsou operandy uloženy, podprogram pokračuje. 0A87
PO-CONT
LD CALL LD LD LD CP JP JR
DE,#09F4 #0A80,PO-CHANGE HL,(#5C0E) (TVDATA) D,A A,L #16 C,#2211,CO-TEMPS NZ,#0AC2,PO-TAB
Obnovení původní adresy pro PRINT-OUT (#09F4). Vyzvedni řídící kód a prvý operand, (jestli budou dva operandy) "poslední" operand a řídící kód jsou přesunuty. Jedná-li se o INK až OVER, pak skok dopředu. Skok dopředu jde-li o TAB.
Nyní zpracuj řídící charakter AT.
0AAC
0ABF
PO-AT-ERR
PO-AT-SET
LD LD LD SUB JR ADD LD BIT JR LD SUB JP INC LD INC BIT JP CP JP JP
B,H C,D A,#1F C C,#0AAC,PO-AT-ERR A,#02 C,A 1,(IY+1) (FLAGS) NZ,#0ABF,PO-AT-SET A,#16 B C,#1E9F,REPORT-B A B,A B 0,(IY+2) (TV-FLAG) NZ,#0C55,PO-SCR (IY+49) (DF-SZ) C,#0C86,REPORT-5 #0DD9,CL-SET
Číslo řádku. Číslo sloupce. Převrácení čísla sloupce t.j. #00 až #1F se změní na #1F až #00. Musí být v rozsahu. Přičtení doplňku, aby C obsahoval #21 až #22. Při obsluze tiskárny skok dopředu. Převrácení čísla řádku. t.j. #00 až #15 se změní na #16 až #01. Je-li vše v pořádku skok dopředu. Rozsah #16 až #01 se změní na #17 až #02 A nyní na #18 až #03. Jedná-li se o tisk v dolní části obrazovky, proveď případné rolování obrazovky. Vyvolej chybové hlášení při nedostatku místa. Návrat přes CL-SET & PO-STORE.
Zde zpracuj řídící znak TAB. 0AC2 0AC3
42
PO-TAB PO-FILL
LD CALL ADD DEC AND RET LD SET
A,H #0B03,PO-FETCH A,C A #1F Z D,A 0,(FLAGS)
Vyzvedni prvý operand. Aktuální tisková pozice. Přičtení aktuální sloupcové hodnoty. Zjisti kolik mezer, modulo 32 je zapotřebí a vrať se, je-li výsledek nula. Použij D jako čítač. Potlač "úvodní mezeru". Komentovaný výpis paměti ROM
0AD0
PO-SPACE
LD CALL DEC JR RET
A,#20 #0C3B,PO-SAVE D NZ,#0AD0,PO-SPACE
Vytiskni D * mezer. Konec.
ZNAKY KTERÉ LZE TISKNOUT. Požadovaný znak (nebo znaky) je vytisknut voláním PO-ANY následované podprogramem PO-STORE. 0AD9
PO-ABLE
CALL #0B24,PO-ANY
Vytiskni znak(y) a pokračuj přes PO-STORE.
PODPROGRAM ÚSCHOVA POZICE Nové hodnoty pro řádek, sloupec a adresa "bodu" jsou uschovány v příslušných systémových proměnných. 0ADC
0AF0
0AFC
PO-STORE
PO-ST-E
PO-ST-PR
BIT JR BIT JR LD LD RET LD LD LD RET LD LD RET
1,(IY+1) (FLAGS) NZ,#0AFC,PO-ST-PR 0,(IY+2) (TV-FLAG) NZ,#0AF0,PO-ST-E (#5C88),BC (S-POSN) (#5C84),HL (DF-CC) (#5C8A),BC (S-POSNL) (#5C82),BC (ECHO-E) (#5C86),HL (DF-CCL) (IY+69),C (P-POSN) (#5C80),HL (PR-CC)
Skok dopředu při obsluze tiskárny. Skok při obsluze dolní části obrazovky. Uschovej hodnoty, které se vztahují k hlavní části obrazovky a vrať se. Uschovej hodnoty, které se vztahují k dolní části obrazovky a vrať se. Uschovej hodnoty, které se vztahují k bafru tiskárny a vrať se.
PODPROGRAM VYZVEDNUTÍ POZICE Parametry aktuální tiskové pozice jsou vyzvednuty z příslušných systémových proměnných. 0B03
0B1D
PO-FETCH
PO-F-PR
BIT JR LD LD BIT RET LD LD RET LD LD RET
1,(IY+1) (FLAGS) NZ,#0B1D,PO-F-PR BC,(#5C88) (S-POSN) HL,(#5C84) (DF-CC) 0,(IY+2) (TV-FLAG) Z BC,(#5C8A) (S-POSNL) HL,(#5C86) (DF-CCL) C,(IY+69) (P-POSN) HL,(#5C80) (PR-CC)
Skok dopředu při obsluze tiskárny. Vyzvedni hodnoty, které se vztahují k hlavní části obrazovky a vrať se, pokud toto bylo úmyslem. Jinak vyzvedni hodnoty, které se vztahují k dolní části obrazovky a vrať se. Vyzvedni hodnoty, které se vztahují k bafru tiskárny a vrať se.
PODPROGRAM TISKU JAKÉHOKOLIV ZNAKU Obyčejné znaky, token, grafické znaky a UDG znaky jsou pojednány odděleně. 0B24
PO-ANY
CP JR CP JR LD CALL
#80 C,#0B65,PO-CHAR #90 NC,#0B52,PO-T&UDG B,A #0B38,PO-GR-1
Při obyčejném znaku skok dopředu. Při UDG znaku skok dopředu. Přesun grafického znaku. Vytvoření grafické formy.
Komentovaný výpis paměti ROM
43
CALL #0B03,PO-FETCH LD DE,#5C92 (MEMBOT) JR #0B7F,PR-ALL
Obnovení HL. DE ukazuje na začátek grafické formy. Skok dopředu a tisk grafického znaku.
Grafické znaky jsou konstruovány pouze pro tento případ v oblasti paměti pro kalkulátor t.j. MEM-0 až MEM-1. 0B38
PO-GR-1
0B3E
PO-GR-2
0B4C
PO-GR-3
LD CALL RR SBC AND LD RR SBC AND OR LD LD INC DEC JR RET
HL,# 5C92 (MEMBOT) #0B3E,PO-GR-2 B A,A #0F C,A B A,A #F0 C C,#04 (HL),A HL C NZ,#0B4C,PO-GR-3
Ve skutečnosti volej následující podprogram dvakrát. Určení bitu 0 (a později i bitu 2) grafického kódu. A bude obsahovat #00, nebo #0F podle hodnoty bitu v kódu. Uschovej výsledek v C. Určení bitu 1 (a později i bitu 3) grafického kódu. A bude obsahovat #00, nebo #0F podle hodnoty bitu v kódu. Oba výsledky jsou kombinovány. A obsahuje polovinu znakové formy a bude použito čtyřikrát. Po horní polovině znakové formy přijde dolní polovina.
Nyní se oddělí znaky UDG a tokens. 0B52
PO-T&UDG
0B5F
PO-T
0B65
PO-CHAR
0B6A
PO-CHAR-2
0B76
PO-CHAR-3
SUB JR ADD PUSH LD JR CALL JP PUSH LD EX LD RES CP JR SET LD LD ADD ADD ADD ADD POP EX
#A5 NC,#0B5F,PO-T A,#15 BC BC,(#5C7B) (UDG) #0B6A,PO-CHAR-2 #0C10,PO-TOKENS #0B03,PO-FETCH BC BC,(#5C36) (CHARS) DE,HL HL,#5C3B (FLAGS) 0,(HL) #20 NZ,#0B76,PO-CHAR-3 0,(HL) H,#00 L,A HL,HL HL,HL HL,HL HL,BC BC DE,HL
Skok dopředu při tokens. Znaky UDG jsou nyní od #00 do #0F. Uschovej hodnoty aktuální tiskové pozice. Vyzvedni bázovou adresu oblasti UDG a skoč dopředu. Vytiskni token a vrať se přes PO-FETCH. Uschovej hodnoty současné pozice. Vyzvedni bázovou adresu oblasti CHARS a uschovej tiskovou adresu v HL. Umožni úvodní mezeru. Jestliže se nejedná o mezeru, potom skoč dopředu. Ale potlač úvodní mezeru, jestliže už existuje. Převedení kódu znaku do HL.
HL=HL*8 Nalezení bázové adresy znaku. Je vyzvednuta aktuální tisková pozice a bázová adresa převedena do DE.
PODPROGRAM TISK VŠECH ZNAKŮ Tento podprogram tiskne osmibitové matice všech znaků. Na vstupu obsahuje DE bázovou adresu znakové formy, HL cílovou adresu a v BC je aktuální tisková pozice pro řádek a sloupec. 0B7F
44
PR-ALL
LD DEC
A,C A
Vezmi číslo sloupce a posuň se o jednu pozici doprava. Komentovaný výpis paměti ROM
0B93
PR-ALL-1
LD JR DEC LD BIT JR PUSH CALL POP LD CP PUSH CALL POP
A,#21 NZ,#0893,PR-ALL-1 B C,A 1,(IY+1) (FLAGS) Z,#0B93,PR-ALL-1 DE #0ECD,COPY-BUFF DE A,C C DE Z,#0C55,PO-SCR DE
Nejde-li o nový řádek skoč dopředu. Posuň o jednu pozici dolů. Při obsluze obrazovky skok dopředu. Uschovej bázovou adresu během vyprazdňování bafru a obnov ji. Vezmi číslo nového sloupce. Testuj zda-li byl použit nový řádek. Jestliže ano, podívej se jestli není potřeba rolovat displej.
Nyní posuď současný stav INVERSE & OVER.
0BA4
0BB6
PR-ALL-2
PR-ALL-3
PUSH PUSH LD LD RRA JR INC RRA RRA SBC LD LD AND BIT JR SET SCF EX
BC HL A,(#5C91) (P-FLAG) B,#FF C,#0BA4,PR-ALL-2 B
A,A C,A A,#08 A 1,(IY+1) (FLAGS) Z,#0BB6,PR-ALL-3 1,(IY+48) (FLAGS2) DE,HL
Uschovej poziční a cílové hodnoty. Vyzvedni P-FLAG. Připrav masku #FF pro OVER 1. Testuj bit 0 a proveď skok při OVER 1. Uprav masku na #00 pro OVER 0. Rotuj bit 2 P-FLAG do CY a připrav masku #00 pro INVERSE 0 a masku #FF pro INVERSE 1. Ulož masku do registru C. Nastav registr A jako čítač mikrořádků. Nuluj CY flag. Při obsluze obrazovky skoč dopředu. Signál: bafr již není prázdný. Nastav CY jako signál: používá se tiskárna. Před vstupem do smyčky zaměň bázovou a cílovou adresu.
Zde bude během osmi průchodů smyčkou proveden tisk znaku. 0BB7
PR-ALL-4
0BC1
PR-ALL-5
EX LD AND XOR XOR LD EX JR INC INC DEC JR EX DEC BIT CALL POP POP DEC INC
AF,AF’ A,(DE) B (HL) C (DE),A AF,AF’ C,#0BD3,PR-ALL-6 D HL A NZ,#0BB7,PR-ALL-4 DE,HL H 1,(IY+1) (FLAGS) Z,#0BDB,PO-ATTR HL BC C HL
Uschovej CY flag v registru F'. Vyzvedni stávající mikrořádek. Použij masku pro OVER a výsledek XORuj s mikrořádkem. Proveď XOR také s maskou pro INVERSE a vlož na cílovou adresu. Vyzvedni CY flag a skoč, je-li nastaven pro tiskárnu. Uprav cílovou adresu. Posuň se na další řádek zdrojové matice. Zmenši čítač a skoč zpět, pokud není nulový. HL musí obsahovat správnou vyšší adresu znakové oblasti. Při obsluze obrazovky nastav příslušný bajt atributů. Obnov původní cílovou a poziční adresu. Snížení čísla sloupce. Zvýšení cílové adresy.
Komentovaný výpis paměti ROM
45
RET
Návrat.
Při obsluze tiskárny musí být cílová adresa zvětšována po přírůstcích #20. 0BD3
PR-ALL-6
EX LD ADD LD EX JR
AF,AF’ A,#20 A,E E,A AF,AF’ #0BC1,PR-ALL-5
Opět uschovej CY flag. Přírůstek. Přičtení do registru E. Vyzvednutí CY flagu. Skok zpět do smyčky.
PODPROGRAM NASTAVENÍ ATRIBUTU Je nalezen příslušný bajt. Starý obsah je modifikován podle stavu ATTR-T, MASK-T a P-FLAG a tato nová hodnota je vložena zpět. 0BDB
PO-ATTR
0BFA
PO-ATTR-1
0C08
PO-ATTR-2
LD RRCA RRCA RRCA AND OR LD LD LD XOR AND XOR BIT JR AND BIT JR XOR BIT JR AND BIT JR XOR LD RET
A,H
Vyšší bajt cílové adresy je dělen osmi.
#03 #58 H,A (#5C8F) (ATTR-T) A,(HL) E D E 6,(IY+87) (P-FLAG) Z,#0BFA,PO-ATTR-1 #C7 2,A NZ,#0BFA,PO-ATTR-1 #38 4,(IY+87) (P-FLAG) Z,#0C08,PO-ATTR-2 #F8 5,A NZ,#0C08,PO-ATTR-2 #07 (HL),A
AND #03 určí, která třetina obrazovky je adresována. Nyní je formován vyšší bajt adresy atributu. D obsahuje ATTR-T a E obsahuje MASK-T. Hodnota "starého" atributu do A. Maskování.
Pokud není PAPER 9, skoč dopředu. Původní barva PAPER se ignoruje a podle odstínu INK bude nová barva PAPER buď černá (000), nebo bílá (111). Pokud není INK 9, skoč dopředu. Původní barva INK se ignoruje a podle odstínu PAPER bude nová barva INK buď černá (000), nebo bílá (111). Vlož novou hodnotu atributu a vrať se.
PODPROGRAM TISKU HLÁŠENÍ Tento podprogram se používá pro tisk hlášení a tokens. Na vstupu obsahuje registr A číslo hlášení nebo token v tabulce a v DE je bázová adresa této tabulky. 0C0A
PO-MSG
PUSH LD EX JR
HL H,#00 (SP),HL #0C14,PO-TABLE
Vyšší bajt poslední úložky na zásobníku je vynulován pro potlačení koncových mezer viz.dále v programu. Skok dopředu.
Zde je vstupní bod pro rozvinutí tokens. (#00 až #5A = RND až COPY). 0C10
46
PO-TOKENS
LD DE,#0095 PUSH AF
Bázová adresa pro tabulku tokens. Uschovej kód na zásobníku.
Komentovaný výpis paměti ROM
Tabulka je prohledána a správný vstup vytisknut. 0C14
PO-TABLE
CALL JR LD BIT CALL
#0C41,PO-SEARCH C,#0C22,PO-EACH A,#20 0,(IY+1) (FLAGS) Z,#0C3B,PO-SAVE
Nalezení požadované položky. Skok na tisk, není-li požadována úvodní mezera.
Jednotlivé znaky hlášení nebo tokens jsou postupně vytisknuty. 0C22
PO-EACH
LD AND CALL LD INC ADD JR
A,(DE) #7F #0C3B,PO-SAVE A,(DE) DE A,A NC,#0C22,PO-EACH
Vyzvedni kód a zruš "invertovaný" bit. Tiskni znak. Opět vyzvedni kód a posuň ukazatel dopředu. Invertovaný bit jde do CY jako signál posledního znaku. Skok, pokud nejsi u konce hlášení nebo token.
Nyní se posoudí potřeba závěrečné mezery.
0C35
PO-TRSP
POP CP JR CP RET LD CP RET LD
DE #48 Z,#0C35,PO-TRSP #82 C A,D #03 C A,#20
Pro hlášení obsahuje D #00 a pro tokens #00 až #5A. Jestliže poslední byl znak $, pak skok dopředu. Jestliže poslední byl kterýkoliv znak před invertovaným "A", pak se vrať. Prozkoumej hodnotu v D a jestliže indikuje, že bylo tisknuto hlášení,RND,INKEY$ nebo PI, vrať se. Všechny ostatní případy vyžadují následnou mezeru.
PODPROGRAM PO-SAVE Tento podprogram umožňuje tzv. rekurzivní tisk (tím, že volá sám uschovány. 0C3B
PO-SAVE
PUSH DE EXX RST #10,PRINT-A-1 EXX POP DE RET
Uschovej Uschovej Vytiskni Obnovení Obnovení Hotovo.
sebe). Obsahy registrů jsou
DE. HL a BC. jeden znak. HL a BC. DE.
PODPROGRAM PROHLEDÁVÁNÍ TABULEK Tento podprogram vrací DE jako ukazatel na první znak požadované položky a CY=0, má-li být posouzena úvodní mezera. 0C41
PO-SEARCH
0C44
PO-STEP
PUSH EX INC BIT INC JR DEC JR EX POP CP
AF DE,HL A 7,(HL) HL Z,#0C44,PO-STEP A NZ,#0C44,PO-STEP DE,HL AF #20
Uschovej číslo položky. Bázová adresa do HL. Uprav rozsah na #01 až "?" Čekej na invertovaný znak a pokud není, vracej se do smyčky. Počítej položky, dokud nenalezneš tu požadovanou. DE ukazuje na první znak. Vyzvedni číslo položky a pro prvních 32 čísel
Komentovaný výpis paměti ROM
47
RET LD SUB RET
C A,(DE) #41
se vracej s CY=1. Testuj první znak a je-li to písmeno bude zapotřebí úvodní mezera.
PODPROGRAM TESTOVÁNÍ SCROLL Kdykoliv by mohlo dojít k potřebě rolování displeje, volá se tento podprogram. K tomu dochází ve třech případech: a)Při zpracování řídícího znaku CR (carriage return). b)Je-li použito AT v INPUT řádku. c)Jestliže výpis přesáhne aktuální řádek a bude zapotřebí pokračovat na dalším řádku. Na vstupu obsahuje B číslo řádku, který má být testován. 0C55
PO-SCR
0C86 REPORT-5
BIT RET LD PUSH LD BIT JP CP JR RET BIT JR LD DEC JR LD CALL LD RES RET
1,(IY+1) (FLAGS) NZ DE,#0DD9 DE A,B 0,(IY+2) (TV-FLAG) NZ,#0D02,PO-SCR-4 (IY+49) (DF-SZ) C,#0C86,REPORT-5 NZ 4,(IY+2) (TV-FLAG) Z,#0C88,PO-SCR-2 E,(IY+45) (BREG) E Z,#0CD2,PO-SCR-3 A,#00 #1601,CHAN-OPEN SP,(#5C3F) (LIST-SP) 4,(IY+2) (TV-FLAG)
RST #08,ERROR-1 DEFB #04
Jestliže obsluhuješ tiskárnu, vrať se. Adresa CL-SET na zásobník. Číslo řádku do A. Jedná-li se o INPUT ...AT,skok dopředu. Je-li číslo řádku nižší než DF-SZ, skoč do podprogramu chybového hlášení a je-li vyšší, vrať se přes CL-SET. Pokud neobsluhuješ automatický výpis skoč dopředu. Vyzvedni čítač řádků, dekrementuj ho a skoč dopředu, je-li potřeba rolovat. Jinak otevři kanál "K", obnov zásobník, signalizuj konec automatického výpis a vrať se přes CL-SET. Ohlaš: 5-Out of screen
Nyní posuď, je-li potřeba vypsat sdělení "scroll?". 0C88
48
PO-SCR-2
DEC JR LD SUB LD LD PUSH LD PUSH LD CALL XOR LD CALL SET LD SET
(IY+82) (SCR-CT) NZ,#0CD2,PO-SCR-3 A,#18 B (#5C8C),A (SCR-CT) HL,(#5C8F) (ATTR-T) HL A,(#5C91) (P-FLAG) AF A,#FD #1601,CHAN-OPEN A DE,#0CF8 #0C0A,PO-MSG 5,(IY+2) (TV-FLAG) HL,#5C3B 3,(HL)
Dekrementuj skrolovací čítač. Není-li nulový, ke sdělení nedojde. Čítač je nastaven. na novou hodnotu. Aktuální hodnoty ATTR-T a MASK-T jsou uschovány. Aktuální hodnota P-FLAG je uschována. Kanál "K" je otevřen. Sdělení "scroll?" má číslo 0. Báze. Vypsání na obrazovku. Signál: čistit dolní část obrazovky po stisku klávesy. Toto je FLAGS. Signál: " L mod ". Komentovaný výpis paměti ROM
RES EXX CALL EXX CP JR CP JR OR CP JR LD CALL POP LD POP LD
5,(HL) #15D4,WAIT-KEY #20 Z,#0D00,REPORT-D #E2 Z,#0D00,REPORT-D #20 #6E Z,#0D00,REPORT-D A,#FE #1601,CHAN-OPEN AF (#5C91),A (P-FLAG) HL (#5C8F),HL (ATTR-T)
Signál: zatím žádná klávesa. Poznámka: Zde měl být také uschován DE. Vyzvedni kód stisknuté klávesy. Obnov registry. Při stisku BREAK, skoč na chybové hlášení. Při stisku STOP, skoč na chybové hlášení. Při stisku n nebo N, skoč na chybové hlášení. Ostatní znaky vyvolávají rolování. Otevření kanálu "S". Vyzvednutí a obnovení P-FLAG. Vyzvednutí a obnovení ATTR-T a MASK-T.
Nyní je displej odrolován. 0CD2
PO-SCR-3
CALL LD INC LD PUSH CALL LD RRCA RRCA RRCA AND OR LD
#0DFE,CL-SC-ALL B,(IY+49) (DF-SZ) B C,#21 BC #0E9B,CL-ADDR A,H
#03 #58 H,A
Celý displej je skrolován. Jsou nalezena čísla řádku a sloupce nad dolní částí obrazovky a uschována. Je nalezena adresa odpovídajícího atributu a tato je uložena do HL.
Řádek o který se jedná, obdrží atributy z dolní části obrazovky a nový řádek na nejspodnějším okraji displeje bude mít hodnoty z ATTR-P. Stačí tedy hodnoty atributů zaměnit.
0CF0
PO-SCR-3A
LD LD LD LD EX LD LD INC INC DJNZ POP
DE,#5AE0 A,(DE) C,(HL) B,#20 DE,HL (DE),A (HL),C DE HL #0CF0,PO-SCR-3A BC
RET
DE ukazuje na první atribut nejspodnějšího řádku. Hodnota bajtu do A. Bajt z řádku nad dolní částí obrazovky do C. 32 bajtů je ve hře. Záměna ukazatelů. Proveď první záměnu a pokračuj se stejnými hodnotami pro celý řádek. Vyzvedni číslo nejspodnějšího řádku a sloupce horní části obrazovky a vrať se.
Sdělení "scroll?" 0CF8
0D00
REPORT-D
DEFB #80 DEFB #73,#63,#72,#6F DEFB #6C,#6C,#BF
Úvodní značka – bude přeskočena. s c r o l l ? (invertovaný).
RST
Ohlaš:
#08,ERROR-1
Komentovaný výpis paměti ROM
49
DEFB #0C
D-BREAK-CONT repeats
Dolní část obrazovky je ošetřena následovně. 0D02
PO-SCR-4
CP JR ADD SUB RET NEG PUSH LD LD PUSH LD PUSH CALL LD
#02 C,#0C86,REPORT-5 A,(IY+49) (DF-SZ) #19 NC BC B,A HL,(#5C8F) (ATTR-T) HL HL,(#5C91) (P-FLAG) HL #0D4D,TEMPS A,B
Je-li příliš velká, skok na chybové hlášení. Jestliže není potřeba rolovat, provede se návrat. V A je počet skrolů které se mají vykonat. Uschování čísla řádku a sloupce. Počet rolování, ATTR-T a MASK-T jsou uschovány. Rovněž P-FLAG jde na zásobník. Budou použity "permanentní" barvy. Počet rolování do A.
Nyní je dolní část obrazovky skrolována A krát. 0D1C
PO-SCR-4A
0D2D
PO-SCR-4B
PUSH LD LD LD INC LD LD CP JR INC LD CALL POP DEC JR POP LD POP LD LD RES CALL
AF HL,#5C6B B,(HL) A,B A (HL),A HL,#5C89 (HL) C,#0D2D,PO-SCR-4B (HL) B,#18 #0E00,CL-SCROLL AF A NZ,#0D1C,PO-SCR-4A HL (IY+87),L (P-FLAG) HL (#5C8F),HL (ATTR-T) BC,(#5C88) (S-POSN) 0,(IY+2) (TV-FLAG) #0DD9,CL-SET
SET POP RET
0,(IY+2) (TV-FLAG) BC
Ulož počet. Hodnota v DF-SZ jde do B a do A, je inkrementována a vrácena do DF-SZ. Toto je S-POSN-hi. Skok se provede jedině tehdy, když B=původní hodnota DF-SZ, tedy rolování pouze dolní části. Zvětšení S-POSN-hi Hodnota pro rolování celého displeje. Roluj B krát. Vyzvednutí a zmenšení počtu rolování. Skok zpět, není-li skončeno. Vyzvedni a obnov P-FLAG. Vyzvedni a obnov ATTR-T a MASK-T. V případě změny S-POSN volej CL-SET, aby se do DF-CC uložila odpovídající hodnota. Signál: obsluha dolní částí obrazovky. Vyzvedni číslo řádku a sloupce a vrať se.
PODPROGRAM BAREVNÝCH POLOŽEK Toto je jeden z nejdůležitějších podprogramů. Je používán kdykoliv je zapotřebí, aby permanentní barevné hodnoty byly zkopírovány do přechodných systémových proměnných. Nejprve jsou zpracovávány ATTR-T a MASK-T. 0D4D
50
TEMPS
XOR LD BIT JR
A HL,(#5C8D) (ATTR-P) 0,(IY+2) (TV-FLAG) Z,#0D5B,TEMPS-1
Registr A je vynulován. Jsou vyzvednuty současné hodnoty ATTR-P a MASK-P. Jedná-li se o hlavní část obrazovky, skoč dopředu. Komentovaný výpis paměti ROM
0D5B
TEMPS-1
LD LD LD
H,A L,(IY+14) (BORDCR) (#5C8F),HL (ATTR-T)
Jinak použij hodnotu #00 a hodnotu systémové proměnné BORDER. Obě pak ulož na ATTR-T a MASK-T.
Další na řadě je P-FLAG.
0D65
TEMPS-2
LD JR LD RRCA XOR AND XOR LD RET
HL,#5C91 NZ,#0D65,TEMPS-2 A,(HL) (HL) #55 (HL) (HL),A
Toto je P-FLAG. Skoč dopředu, jestliže je to dolní část obrazovky A=#00. Jinak vyzvedni hodnotu P-FLAG a přesuň liché bity na místa sudých. Pokračuj v kopírování sudých bitů do registru A a do systémové proměnné P-FLAG.
PODPROGRAM CLS Hned na začátku je smazán celý displej - "body" jsou vynulovány a atributové bajty jsou nastaveny na hodnotu, která odpovídá systémové proměnné ATTR-P. Potom bude smazána také nižší část obrazovky. 0D6B 0D6E
CLS CLS-LOWER
CALL LD RES SET CALL LD CALL
#0DAF,CL-ALL HL,#5C3C 5,(HL) 0,(HL) #0D4D,TEMPS B,(IY+49) (DF-SZ) #0E44,CL-LINE
Hlavní část displeje je smazána. Toto je TV-FLAG. Signál: nemaž spodní část obrazovky po stisknutí tlačítka Signál: spodní část obrazovky. Nastav barevné hodnoty, tzn. nastav ATTR-T podle BORDCR. Dolní část obrazovky je pak vyčištěna za pomocí těchto hodnot.
S výjimkou atributových bajtů pro řádky 22 a 23 jsou všechny atributové bajty nastaveny podle hodnot v ATTR-P.
0D87 0D89
CLS-1 CLS-2
0D8E
CLS-3
LD LD DEC JR LD DEC LD DEC JR DJNZ
HL,#5AC0 A,(#5CBD) (ATTR-P) B #0D8E,CLS-3 C,#20 HL (HL),A C NZ,#0D89,CLS-2 #0D87,CLS-1
Adresa 1.atributového bajtu pro řádek 22. Vyzvedni ATTR-P. Čítač řádků. Skoč dopředu do smyčky. 32 znaků na řádek. Vracej se zpět po řádku a nastavuj atributové bajty.
Opakuj smyčku.
Velikost spodní části obrazovky bude nastavena. LD
(IY+49),#02 (DF-SZ)
Její velikost jsou dva řádky.
Nyní ještě zbývají další "úklidové práce". 0D94
CL-CHAN
0DA0
CL-CHAN-A
LD CALL LD LD AND LD INC LD INC
A,#FD #1601,CHAN-OPEN HL,(#5C51) (CURCHL) DE,#09F4 A (HL),E HL (HL),D HL
Kanál "K" bude otevřen. Vyzvedni adresu současného kanálu a jako výstupní adresu použij #09F4. (=PRINT-OUT) a vstupní adresa #10A8 (=KEY-INPUT).
Komentovaný výpis paměti ROM
51
LD CCF JR LD JR
DE,#10A8 C,#0DA0,CL-CHAN-A BC,#1721 #0DD9,CL-SET
První je uložena výstupní adresa, pak adresa vstupní. Protože se jedná o dolní část displeje bude nejnižší tiskový řádek číslo 23. Vrať se přes CL-SET.
PODPROGRAM MAZÁNÍ CELÉHO DISPLEJE Tato podprogram je volán: a) příkazem CLS b) hlavním prováděcím podprogramem c) automatickým výpisem. 0DAF
CL-ALL
LD LD RES CALL LD CALL CALL LD CALL LD LD LD INC LD LD LD
HL,#0000 (#5C7D),HL (COORDS) 0,(IY+48) (FLAGS2) #0D94,CL-CHAN A,#FE #1601,CHAN-OPEN #0D4D,TEMPS B,#18 #0E44,CL-LINE HL,(#5C51) (CURCHL) DE,#09F4 (HL),E HL (HL),D (IY+82),#01 (SCR-CT) BC,#1821
Jsou uloženy nuly do systémové proměnné COORDS. Signál: obrazovka je čistá. Proveď "úklidové práce". Kanál "S" bude otevřen. Permanentní barvy budou nastaveny. 24 řádků displeje bude smazáno. Zajisti,
že současná výstupní adresa je #09F4 (PRINT-OUT). Nastav rolovací čítač. Protože se jedná o horní část obrazovky, bude nejvyšší tisknutý řádek "řádek 0". Pokračuj do podprogramu CL-SET.
PODPROGRAM CL-SET Na vstupu do tohoto podprogramu obsahuje registrový pár BC číslo řádku a sloupce na obrazovce, nebo registr C obsahuje číslo sloupce v bafru tiskárny a pak je nalezena příslušná adresa bitu prvního znaku. Podprogram se vrací přes PO-STORE tak, aby byly uloženy všechny potřebné hodnoty. 0DD9
CL-SET
0DEE
CL-SET-1
0DF4
CL-SET-2
52
LD BIT JR LD BIT JR ADD SUB PUSH LD CALL POP LD SUB LD LD ADD JP
HL,#5B00 11,(IY+1) (FLAGS) NZ,#0DF4,CL-SET-2 A,B 0,(IY+2) (TV-FLAG) Z,#0DEE,CL-SET-1 A,(IY+49) (DF-SZ) #18 BC B,A #0E9B,CL-ADDR BC A,#21 C E,A D,#00 HL,DE #0ADC,PO-STORE
Adresa 1.bajtu bafru tiskárny. Obsluhuješ-li bafr tiskárny, skoč dopředu. Okopíruj číslo řádku. Obsluhuješ-li hlavní část obrazovky, skoč dopředu. První řádek dolní části obrazovky se nazývá "řádek #18" a to musí být převedeno. Číslo řádku a sloupce jsou uschována a číslo řádku je převedeno do reg. B. V HL je nyní adresa začátku řádku a čísla řádku a sloupce jsou opět uložena do BC. Číslo sloupce je nyní převráceno převedeno do registrového páru DE a na závěr je v HL vytvořena požadovaná adresa. Tyto hodnoty jsou uschovány podprogramem PO-STORE.
Komentovaný výpis paměti ROM
ROLOVACÍ PODPROGRAM Počet řádků, který má být rolován, vstupuje do podprogramu v registru B. 0DFE
CL-SC-ALL
LD
B,#17
Vstupní bod po dotazu "scroll?".
Hlavní vstupní bod z předcházejícího a nebo z příkazu INPUT AT. 0E00
CL-SCROLL
CALL #0E9B,CL-ADDR LD C,#08
Najdi počáteční adresu řádku. 8 mikrořádků tvoří kompletní znakový řádek.
Nyní přichází hlavní rolovací smyčka. Registr B obsahuje počet rolovaných řádků, HL ukazuje na adresu 1.rolovaného bajtu a registr C je využit jako počítadlo mikrořádků. 0E05
CL-SCR-1
PUSH PUSH LD AND LD JR
BC HL A,B #07 A,B NZ,#0E19,CL-SCR-3
Uschovej oba čítače. Uschovej adresu. Nejedná-li se o přechod na další třetinu displeje, skoč dopředu.
Mikrořádky prvního znakového řádku každé třetiny musí být přeneseny přes 2K hranici (každá třetina má 2KB). 0E0D
CL-SCR-2
EX LD ADD EX LD DEC LDIR
DE,HL HL,#F8E0 HL,DE DE,HL BC,#0020 A
Po skončení těchto operací zůstává v HL původní hodnota a DE ukazuje na novou cílovou adresu. Jedná se o 32 znaků. Zmenši počítadlo za každý přenesený řádek a přenes požadovaných 32 bajtů.
Pixlové řádky uvnitř třetin mají být nyní rolovány. Registr A obsahuje při prvním průběhu hodnoty #01 až #07, #09 až #0F nebo #11 až #17. 0E19
CL-SCR-3
EX LD ADD EX LD AND RRCA RRCA RRCA LD LD LD LDIR LD ADD AND JR
DE,HL HL,#FFE0 HL,DE DE,HL B,A #07
Znovu je DE nastaven tak, aby ukazoval na požadovanou cílovou adresu, ale tentokrát pouze o 32 pozic dále. Uschovej číslo řádku v registru B. Nyní zjisti, kolik znaků zůstává v této třetině.
C,A A,B B,#00
Předej celkový počet znaků do registru C. Vyzvedni číslo řádku. A nyní již obsahuje celkový počet znaků i BC a mikrořádek každého znaku je rolován. Připrav pro zvětšení adresu, na kterou se bude ukládat při třetinové hranici a zvětši HL o #0700. Nejsou-li zde již žádné další zvažované třetiny, skoč zpět.
B,#07 HL,BC #F8 NZ,#0E0D,CL-SCR-2
Nyní zjisti zda byla smyčka použita 8 krát; tj. pro 8 mikrořádků. POP INC POP DEC
HL H BC C
Vyzvedni adresu originálu. Adresuj další mikrořádek. Vyzvedni čítače. Zmenši čítač mikrořádků a pokud nebylo
Komentovaný výpis paměti ROM
53
JR
NZ,#0E05,CL-SR-1
přeneseno všech 8 mikrořádků skákej zpět.
Dále jsou rolovány atributové bajty. Povšimněte si, že registr B obsahuje stále počet řádků, které mají být rolovány, a registr C obsahuje nulu. CALL LD ADD EX LDIR
#0E88,CL-ATTR HL,#FFE0 HL,DE DE,HL
Je nalezena požadovaná adresa v oblasti proměnných a počet znaků v "B" řádcích. Přemísťovací konstanta pro všechny atributové bajty je 32 míst. Atributové bajty jsou nyní rolovány.
Zbývá ještě vyčistit spodní řádky displeje. LD
B,#01
B obsahuje 1, se kterou vstoupí do dalšího podprogramu.
PODPROGRAM SMAZÁNÍ ŘÁDKU Tento podprogram vyčistí spodní řádky obrazovky, jejichž počet je v registru B. 0E44
CL-LINE
PUSH BC CALL #0E9B,CL-ADDR LD C,#08
Číslo řádku je během podprogramu uschováno. V HL je vytvořena počáteční adresa řádku. Znovu je C nastaveno jako čítač 8 mikrořádků.
Zde přichází smyčka, která vyčistí všechny "pixlové" řádky. 0E4A
CL-LINE-1
0E4D
CL-LINE-2
PUSH PUSH LD AND RRCA RRCA RRCA LD LD LD DEC LD LD LD INC LDIR LD ADD DEC AND LD JR
BC HL A,B #07
C,A A,B B,#00 C D,H E,L (HL),#00 DE DE,#0701 HL,DE A #F8 B,A NZ,#0E4D,CL-LINE-2
Uschovej číslo řádku a čítač mikrořádků. Uschovej adresu. Uschovej číslo řádku v registru A. Zjisti, o kolik se jedná znaků nebo-li "B mod 8" řádků a tuto hodnotu předej do registru C (který bude obsahovat #00 pro novou třetinu). Vyzvedni číslo řádku a nastav registr BC tak, aby číslo které obsahuje bylo o jednu menší než počet znaků. Nastav DE tak, aby ukazoval na první znak, vyčisti bajt prvního znaku, nastav DE na druhý znak a vyčisti celý mikrořádek. Pro každou třetinu displeje bude HL zvýšeno o konstantu #0701. Dekrementuj čítač řádků. Předej číslo třetiny do registru B. Skoč zpět, jsou-li zde ještě nějaké třetiny k ošetření.
Zde se zjistí, jestli smyčka proběhla 8 krát. POP INC POP DEC JR
HL H BC C NZ,#0E4A,CL-LINE-1
Připrav adresu pro každý mikrořádek. Vyzvedni čítače. Zmenši čítač mikrořádků a skoč zpět, pokud není konec.
Nyní musí být nastaveny atributové bajty. Hodnota ATTR-P bude použita při obsluze hlavní části displeje a hodnota BORDCR při dolní části displeje. 54
Komentovaný výpis paměti ROM
CALL #0E88,CL-ATTR
0E80
CL-LINE-3
LD LD INC LD BIT JR LD LD DEC LDIR
H,D L,E DE A,(#5C8D) (ATTR-P) 0,(IY+2) (TV-FLAG) Z,#0E80,CL-LINE-3 A,(#5C48) (BORDCR) (HL),A BC
POP LD RET
BC C,#21
Je nalezen počet atributových bajtů a adresa prvního z nich. HL tedy ukazuje na první atributový bajt a DE na druhý. Vyzvedni hodnotu ATTR-P. Jedná-li se o hlavní část obrazovky, skoč dopředu, jinak použij hodnotu BORDCR. Nastav atributový bajt. Jeden bajt už je hotov. A nyní bude jeho hodnota okopírována do všech ostatních bajtů. Obnov si číslo řádku. Nastav číslo sloupce na nejkrajnější levou pozici a vrať se.
PODPROGRAM CL-ATTR Tento podprogram má dvě rozdílné funkce: a) Vypočítat adresu atributového bajtu pro danou adresu v paměti a uložit ji do DE. Povšimněte si, že hodnoty na vstupu ukazují na devátý mikrořádek znaku. b) Pro daný počet řádků v registru B je v registrovém páru BC navrácen počet znaků připadající na tyto řádky. 0E88
CL-ATTR
LD RRCA RRCA RRCA DEC OR LD EX LD LD ADD ADD ADD ADD ADD LD LD RET
A,H
Vyzvedni vyšší bajt adresy a vynásob toto číslo číslem 32.
A #50 H,A DE,HL H,C L,B HL,HL HL,HL HL,HL HL,HL HL,HL B,H C,L
Jdi zpátky na 8. mikrořádek. Adresuj oblast atributů. Vytvoř nový vyšší bajt a celou adresu převeď do DE. Zde je vždy nula a toto je číslo řádku.
Hodnotu vynásobenou číslem 32 převeď zpět do registrového páru BC před návratem.
PODPROGRAM CL-ADDR Pro zadané číslo řádku v registru B vytvoří v HL tento podprogram odpovídající adresu obrazové paměti. 0E9B
CL-ADDR
LD A,#18 SUB B LD D,A RRCA RRCA RRCA
Číslo řádku je převráceno a výsledek je uložen do registru D. Ve skutečnosti (A mod 8)*32. V každé třetině displeje má nižší bajt tyto hodnoty:
Komentovaný výpis paměti ROM
55
AND LD LD AND OR LD RET
#E0 L,A A,D #18 #40 H,A
1. řádek = #00, 2. řádek = #20,atd. Nižší bajt je uložen do L. Skutečné číslo řádku je vyzvednuto, ve skutečnosti se jedná o 64 + 8 * INT(A/8) Vyšší bajt horní třetiny displeje má hodnotu #40, bajt střední třetiny je #48 a nižší třetina je #50. Tyto hodnoty jsou uloženy do registru H a provede se návrat.
PODPROGRAM PŘÍKAZU COPY Tento podprogram obslouží 176 mikrořádků obrazovky, a to jeden po druhém. 0EAC
COPY
DI LD LD
B,#B0 HL,#4000
Po dobu provádění tohoto podprogramu je zakázáno maskované přerušení. Konstanta 176 řádků. Bázová adresa obrazovky.
Zde se vstupuje do smyčky. 0EB2
COPY-1
PUSH PUSH CALL POP POP INC LD AND JR
HL BC #0EF4,COPY-LINE BC HL H A,H #07 NZ,#0EC9,COPY-2
Uschovej bázovou adresu a počet řádků. Tento podprogram bude zavolán 176 krát. Vyzvedni číslo řádku a bázovou adresu. Bázová adresa je posunuta na další mikrořádek. Nebylo-li přeneseno ještě všech 8 mikrořádků, skoč dopředu.
Pro každý nový znakový řádek musí být bázová adresa upravena.
0EC9
COPY-2
LD ADD LD
A,L A,#20 L,A
CCF SBC AND
A,A #F8
ADD LD DJNZ JR
A,H H,A #0EB2,COPY-1 #0EDA,COPY-END
Vyzvedni nižší bajt. Zvyš ho o #20. CY flag bude nulový pohybuješ-li se uprostřed třetiny obrazovky. Neguj CY flag. Registr A bude obsahovat #F8, pokud jsi uvnitř třetiny, ale #00 pokud jdeš do nové třetiny. Vyšší bajt adresy je nyní upraven. Skoč zpět,dokud jsi nevytiskl 176 mikrořádků. Skoč na konec podprogramu COPY.
PODPROGRAM COPY-BUFF Tento podprogram je volán, kdykoliv je zapotřebí vyvolat obsah bafru na tiskárnu. 0ECD
0ED3
COPY-BUFF
COPY-3
DI LD LD PUSH CALL POP DJNZ
HL,#5B00 B,#08 BC #0EF4,COPY-LINE BC #0ED3,COPY-3
Maskované přerušení je zakázáno. Adresa prvního bajtu bafru. Je zde osm mikrořádků. Uschovej číslo řádku. Tento podprogram je volán 8-krát. Vyzvedni číslo řádku. Opakuj do vytištění osmi mikrořádků.
Pokračuj přes podprogram COPY-END.
56
Komentovaný výpis paměti ROM
0EDA
COPY-END
LD OUT EI
A,#04 (#FB),A
Zastav motor tiskárny. Povol nemaskovatelné přerušení a pokračuj přes podprogram CLEAR-PRB.
PODPROGRAM "VYČISTI BUFFER TISKÁRNY" Při zavolání tohoto podprogramu je vyčištěn bafr tiskárny. 0EDF
CLEAR-PRB
0EE7
PRB-BYTES
LD LD XOR LD LD INC DJNZ RES LD JP
HL,#5B00 (IY+70),L (PR-CC-lo) A B,A (HL),A HL #0EE7,PRB-BYTES 1,(IY+48) (FLAGS2) C,#21 #0DD9,CL-SET
Adresa prvního bajtu bafru tiskárny. Nastav tiskový sloupec na nulu. Vynuluj registr A a registr B (ve skutečnosti obsahuje dekadicky 256). Nyní je vyčištěno 256 bajtů bafru tiskárny, jeden po druhém. Signál: bafr je prázdný. Nastav tiskovou pozici a vrať se přes CL-SET a PO-STORE.
PODPROGRAM COPY-LINE Na vstupu do tohoto podprogramu obsahuje registrový pár HL adresu 32 bajtů, které představují mikrořádek a B obsahuje číslo mikrořádku. 0EF4
COPY-LINE
LD CP SBC AND OUT LD
A,B #03 A,A #02 (#FB),A D,A
Okopíruj číslo řádky. Registr A bude obsahovat #00 dokud se nebudou obsluhovat poslední dva řádky. Zpomal motor, ale pouze pro poslední dva mikrořádky. Registr D bude obsahovat buďto #00 nebo #02.
Před vykonáním jakéhokoliv tisku se musí provést tři testy. 0EFD
0F0C
COPY-L-1
COPY-L-2
CALL JR LD OUT EI CALL RST DEFB IN ADD RET JR LD
#1F54,BREAK-KEY C,#0F0C,COPY-L-2 A,#04 (#FB),A #0EDF,CLEAR-PRB #08,ERROR-1 #0C A,(#FB) A,A M NC,#0EFD,COPY-L-1 C,#20
Nebyl-li stlačen BREAK, skoč dopředu. Signál: motor stop. Povol maskované přerušení. Vyčisti bafr tiskárny a Ohlaš: D-BREAK-CONT repeats. Zjisti v jakém stavu se nachází tiskárna. Proveď okamžitý návrat, není-li tiskárna připojena. Počkej na jehlu. Konstanta pro 32 bajtů.
Nyní vstup do smyčky, která obsluhuje tyto bajty. 0F14
COPY-L-3
0F18
COPY-L-4
0F1E
COPY-L-5
LD INC LD RL RL RR IN RRA
E,(HL) HL B,#08 D E D A,(#FB)
Vyzvedni bajt. Posuň ukazatel. V jednom bajtu je 8 bitů. Posuň D doleva. Každý bit posuň do CY. Posuň D zpět a naber CY z E. Znovu otestuj stav tiskárny
Komentovaný výpis paměti ROM
57
JR LD OUT
tisk.
NC,#0F1E,COPY-L-5 A,D (#FB),A
Poznámka: bit 2=0 signál: zapni motor, bit 1=1 signál: zpomal motor, bit 7=1 signál: vlastní DJNZ #0F18,COPY-L-4 DEC C JR NZ,#0F14,COPY-L-3 RET
58
a čekej na signál. Nyní pokračuj a předej bit tiskárně.
Tiskni každý bit. Sniž čítač bajtů. Skoč zpět, jestli jsou zde ještě nějaké bajty. Jinak se vrať.
Komentovaný výpis paměti ROM
PODPROGRAMY EDITORU Editor se volá při dvou příležitostech: a) Z hlavní prováděcí procedury tak, aby mohl uživatel vložit řádek do programu. b) Z podprogramu příkazu INPUT. Nejprve je uložen chybový zásobník a podvržena alternativní adresa. 0F2C
EDITOR
0F30
ED-AGAIN
LD PUSH LD PUSH LD
HL,(#5C3D) (ERR-SP) HL HL,#107F HL (#5C3D),SP (ERR-SP)
Na zásobník je uložena aktuální adresa. Toto je adresa ED-ERRORu. Jakákoliv událost, která by vedla ke spuštění podpr. chybových hlášení, způsobí návrat do podprogramu ED-ERROR.
Nyní se vstupuje do smyčky, která obslouží každý úder na klávesu 0F38
ED-LOOP
CALL PUSH LD LD LD CALL POP LD PUSH
#15D4,WAIT-KEY AF D,#00 E,(IY-1) (PIP) HL,#00C8 #03B5,BEEPER AF HL,#0F38 HL
Z tohoto programu se vrať po stištění klávesy. Přechodně si uschovej kód. Vynuluj registr D a vyzvedni si trvání klávesového cvaknutí, jeho výšku a udělej píp. Obnov si kód a ulož na zásobník adresu ED-LOOP.
Nyní analyzuj získaný kód. CP JR CP JR CP JR
#18 NC,#0F81,ADD-CHAR #07 C,#0F81,ADD-CHAR #10 C,#0F92,ED-KEYS
Akceptuj všechny znakové kódy, grafický kód a a všechny tokens. Také akceptuj čárku "," (tisk v druhé polovině řádku). Akceptuj všechny editační klávesy.
Nyní jsou posouzeny klávesy od INK po TAB. LD LD CP JR
BC,#0002 D,A #16 C,#0F6C,ED-CONTR
INK a PAPER vyžadují dvě místa. Okopíruj kód do D. Skoč dopředu pro INK a PAPER.
Zde budou posuzovány AT a TAB: INC BIT JP CALL LD
BC 7,(IY+55) (FLAGX) Z,#101E,ED-IGNORE #15D4,WAIT-KEY E,A
Jsou požadována tři místa. Skoč dopředu, neobsluhuješ-li INPUT LINE ... Vezmi druhý kód a dej ho do E.
Jsou vyzvednuty ostatní bajty pro řídící znaky. 0F6C
ED-CONTR
CALL PUSH LD RES CALL
#15D4,WAIT-KEY DE HL,(#5C5B) (K-CUR) 0,(IY+7) (MODE) #1655,MAKE-ROOM
Vyzvedni další kód. Uschovej oba kódy. Vyzvedni K-CUR. Signál "K" mode. Vytvoř prostor dvou nebo tří bajtů.
Komentovaný výpis paměti ROM
59
POP INC LD INC LD
BC HL (HL),B HL (HL),C
JR
#0F8B,ADD-CH-1
Obnov předchozí kódy. Ukazuj na první místo a vlož tam první kód. Vlož druhý kód. Druhý kód bude přepsán, jedná-li se o INK a PAPER. Skoč dopředu.
PODPROGRAM ADD-CHAR Tento podprogram ve skutečnosti přidává kód znaku do současného EDIT nebo INPUT řádku. 0F81
ADD-CHAR
0F8B
ADD-CH-1
RES LD CALL LD INC LD RET
0,(IY+7) (MODE) HL,(#5C5B) (K-CUR) #1652,ONE-SPACE (DE),A DE (#5C5B),DE (K-CUR)
Signál "K mode". Vyzvedni pozici kurzoru. Udělej jednu mezeru. Vlož kód do této mezery a signalizuj, že kurzor se musí postavit na další místo. Pak se vrať do ED-LOOP.
Editační tlačítka jsou zpracována takto: 0F92
ED-KEYS
LD LD LD ADD LD ADD PUSH LD RET
E,A D,#00 HL,#0F99 HL,DE E,(HL) HL,DE HL HL,(#5C5B) (K-CUR)
Kód je převeden do registrového páru DE. Bázová adresa tabulky editačních kláves do HL. Vstupní bod je adresován a vyzvednut do E. Adresa obslužného podprogramu je uschována na zásobníku a do HL je uložena pozice kurzoru. Je proveden nepřímý skok do žádaného podprogramu.
TABULKA EDITAČNÝCH KLÁVES adresa 0FA0 0FA1 0FA2 0FA3 0FA4 0FA5 0FA6 0FA7 0FA8
doplněk 09 66 6A 50 B5 70 7E CF D4
znak EDIT kurzor vlevo kurzor vpravo kurzor dolů kurzor nahoru DELETE ENTER SYMBOL SHIFT GRAPHICS
PODPROGRAM TLAČÍTKA EDIT Je-li systém v editačním modu, způsobí stištění klávesy EDIT snesení aktuálního basicového řádku (tj. řádku, na který ukazuje programový kurzor). Je-li systém v modu INPUT je po stištění klávesy EDIT vymazán text, vložený uživatelem. 0FA9
60
ED-EDIT
LD BIT JP CALL CALL LD OR
HL,(#5C49) (E-PPC) 5,(IY+55) (FLAGX) NZ,#1097,CLEAR-SP #196E,LINE-ADDR #1695,LINE-NO A,D E
Vyzvedni číslo současného řádku, ale skoč dopředu, jestliže jsi v modu INPUT. Nalezni adresu začátku řádku a s ní i jeho číslo. Je-li obdržené číslo řádku nula,
Komentovaný výpis paměti ROM
JP PUSH INC LD INC LD LD ADD LD LD CALL CALL LD EX PUSH LD CALL POP DEC DEC
Z,#1097,CLEAR-SP HL HL C,(HL) HL B,(HL) HL,#000A HL,BC B,H C,L #1F05,TEST-ROOM #1097,CLEAR-SP HL,(#5C51) (CURCHL) (SP),HL HL A,#FF #1601,CHAN-OPEN HL HL (IY+15) (E-PPC-lo)
CALL #1855,OUT-LINE INC (IY+15) (E-PPC-lo)
vyčisti jen editační oblast. Uschovej adresu tohoto řádku. Ulož si do BC
jeho délku. Pak k této délce přičti 10 a výsledek opět ulož do BC. Testuj, je-li zde dostatek místa pro tento řádek. Nyní vyčisti editační oblast. Vyzvedni současnou adresu kanálu a zaměň ji s adresou tohoto řádku. Přechodně si ji ulož. Aby mohl být řádek okopírován do editační oblasti, otevři kanál "R". Vyzvedni adresu řádku a postup jeden bajt před řádek. Zmenši číslo současného řádku, aby se zabránilo vytisknutí kurzoru a vytiskni basicový řádek. Zvětši číslo řádku.
Poznámka: tyto úpravy někdy nesplní svou funkci a kurzor je vytisknut. LD INC INC INC INC LD POP CALL RET
HL,(#5C59) (E-LINE) HL HL HL HL (#5C5B),HL (K-CUR) HL #1615,CHAN-FLAG
Vyzvedni adresu řádky v editační oblasti a přeskoč číslo řádku a délku řádku tak, abys nalezl pozici kurzoru. Vyzvedni dřívější kanálovou adresu a nastav příslušné vlajky. Výstup do ED-LOOP.
EDITAČNÍ PODPROGRAM KURZOR DOLŮ 0FF3
ED-DOWN
1001
ED-STOP
BIT JR LD CALL JR LD JR
5,(IY+55) (FLAGX) NZ,#1001,ED-STOP HL,#5C49 #190F,LN-FETCH #106E,ED-LIST (IY+0),#10 (ERR-NR) #1024,ED-ENTER
V INPUT modu skoč dopředu. Toto je E-PPC. Je nalezeno číslo dalšího řádku a je proveden nový automatický výpis. Hlášení "STOP in INPUT". Skoč dopředu.
EDITAČNÍ PODPROGRAM KURZOR DOLEVA 1007
ED-LEFT
CALL #1031,ED-EDGE JR #1011,ED-CUR
Kurzor je posunut. Skok dopředu.
EDITAČNÍ PODPROGRAM KURZOR DOPRAVA 100C
ED-RIGHT
LD CP
A,(HL) #0D
Současný znak je testován a jednalo-li se o ENTER,
Komentovaný výpis paměti ROM
61
1011
ED-CUR
RET INC LD RET
Z HL (#5C5B),HL (K-CUR)
je proveden návrat. Postav kurzor za znak. Nastav systémovou proměnnou K-CUR.
PODPROGRAM DELETE V EDITU 1015
ED-DELETE
CALL #1031,ED-EDGE LD BC,#0001 JP #19E8,RECLAIM-2
Posuň kurzor doleva. zruš současný znak.
PODPROGRAM ED-IGNORE 101E
ED-IGNORE
CALL #15D4,WAIT-KEY CALL #15D4,WAIT-KEY
Další dva znaky z klávesnicového vstupního podprogramu budou ignorovány.
PODPROGRAM ENTER EDIT 1024
ED-ENTER
1026
ED-END
POP POP POP LD BIT RET LD RET
HL HL HL (#5C3D),HL (ERR-SP) 7,(IY+0) (ERR-NR) NZ SP,HL
Návratové adresy ED-LOOP a ED-ERROR jsou odhozeny. Původní hodnota ERR-SP je obnovena. Jestliže nebyly žádné chyby, vrať se. Jinak proveď nepřímý skok do chybového podprogramu.
PODPROGRAM ED-EDGE Adresa je v registrovém páru HL a bude zmenšena v případě, že kurzor nebude stát mezi řídícími znaky a jejich parametry. 1031
ED-EDGE
SCF CALL SBC ADD INC POP RET PUSH LD LD
#1195,SET-DE HL,DE HL,DE HL BC C BC B,H C,L
DE obsahuje E-LINE (při editaci), nebo WORKSP (při INPUTu). CY flag bude nastaven, má-li být kurzor na začátku řádku. Oprava po odečtení. Odhoď návratovou adresu a vrať se přes ED-LOOP, bylo-li nastaveno CY. Obnov návratovou adresu. Ulož současnou adresu kurzoru do registrového páru BC.
Tato smyčka zajistí, že řídící znaky nebudou odděleny od svých parametrů. 103E
62
ED-EDGE-1
LD LD INC LD
H,D L,E HL A,(DE)
AND CP JR INC LD
#F0 #10 NZ,#1051,ED-EDGE-2 HL A,(DE)
HL bude ukazovat na znak, který stojí za znakem, na který ukazuje DE. Vyzvedni kód znaku, který je adresován registrovým párem DE. Nejedná-li se o znaky od INK až TAB skoč dopředu. Překroč jeden znak a opět vyzvedni jeho kód. Komentovaný výpis paměti ROM
SUB ADC
#17 A,#00
Poznámka: Touto instrukcí implementovány, takže to nevadí.
1051
ED-EDGE-2
CY flag je při TAB. nulován. jsou
JR INC AND SBC ADD
NZ,#1051,ED-EDGE-2 HL A HL,BC HL,BC
EX JR RET
DE,HL C,#103E,ED-EDGE-1
odděleny
AT
a
TAB,
ale
ty
stejně
nejsou
v
této
formě
Skoč dopředu, pokud se nejedná o AT a TAB, které jsou-li použity, mají dva parametry. Připrav se na pravdivé odečtení. CY flag bude nastaven na nulu, když posouvaný ukazatel dosáhne K-CUR. Pro další smyčku použij posunutý ukazatel, ale skoč zpět, jestliže jsi překročil K-CUR.
Poznámka: Bude to řídící znak, který bude vymazán použitím DELETE.
PODPROGRAM EDITAČNÍ KURZOR NAHORU 1059
106E
ED-UP
ED-LIST
BIT RET LD CALL EX CALL LD CALL CALL LD JP
5,(IY+55) (FLAGX) NZ HL,(#5C49) (E-PPC) #196E,LINE-ADDR DE,HL #1695,LINE-NO HL,#5C4A #191C,LN-STORE #1795,AUTO-LIST A,#00 #1601,CHAN-OPEN
Vrať se, když jsi v modu INPUT. Zjisti číslo současného řádku a jeho počáteční adresu. HL nyní ukazuje na předchozí řádek. Číslo řádku je vyzvednuto. Toto je systémová proměnná E-PPC. Číslo řádku je uloženo. Automatický listing je znovu zavolán a potom otevřen kanál "K" před návratem do ED-LOOP.
PODPROGRAM ED-SYMBOL Jestliže byly použity kódy SYMBOL & GRAPHICS, budou ošetřeny následovně: 1076
ED-SYMBOL
107C
ED-GRAPH
BIT JR JP
7,(IY+55) (FLAGX) Z,#1024,ED-ENTER #0F81,ADD-CHAR
Skoč zpět, pokud nejsi v INPUT LINE. Skoč zpět.
PODPROGRAM ED-ERROR Toto je vstupní bod, došlo-li k nějaké chybě. 107F
ED-ERROR
BIT JR LD LD LD LD CALL JP
4,(IY+48) (FLAGS2) Z,#1026,ED-END (IY+0),#FF (ERR-NR) D,#00 E,(IY-2) (RASP) HL,#1A90 #03B5,BEEPER #0F30,ED-AGAIN
Skoč zpět, používáš-li jiný kanál než "K". Zruš číslo chyby a proveď zavrčení, než
se vrátíš do editoru.
PODPROGRAM CLEAR-SP Editační oblast nebo WORKSPACE jsou vyčištěny.
Komentovaný výpis paměti ROM
63
1097
CLEAR-SP
PUSH CALL DEC CALL LD LD POP RET
HL #1190,SET-HL HL #19E5,RECLAIM-1 (#5C5B),HL (K-CUR) (IY+7),#00 (MODE) HL
Uschovej ukazatel prostoru. DE bude ukazovat na první bajt a HL na poslední. Uprav hodnotu. Nyní se zruší potřebný počet bajtů. Systémové proměnné K-CUR a MODE "K mode" jsou nastaveny před vyzvednutím ukazatele a provedením návratu.
PODPROGRAM PRO VSTUP KLÁVESY Tento důležitý podprogram vrací kód poslední stištěné klávesy, ale povšimněte si, že klávesa CAPS LOCK, změny modů a změny barevných parametrů jsou v tomto podprogramu také zpracovány. 10A8
KEY-INPUT
BIT CALL AND BIT RET LD RES PUSH BIT CALL POP CP JR CP JR CP JR
3,(IY+2) (TV-FLAG) NZ,#111D,ED-COPY A 5,(IY+1) (FLAGS) Z A,(#5C08) (LAST-K) 5,(IY+1) (FLAGS) AF 5,(IY+2) (TV-FLAG) NZ,#0D6E,CLS-LOWER AF #20 NC,#111B,KEY-DONE #10 NC,#10FA,KEY-CONTR #06 NC,#10DB,KEY-M&CL
Okopíruj editační nebo inputový řádek na obrazovku, jestliže byl změněn mód. Vrať se s CY flag=0 a Z flag=0, jestliže nebyla stištěna žádná nová klávesa Jestliže byla, vyzvedni kód a poznač vyzvednutí. Přechodně si uschovej kód a smaž dolní část obrazovky a vyčisti dolní část obrazovky, pokud je třeba (např. po “scroll?“) Vyzvedni kód a akceptuj všechny znaky a kódy pro tokens. Skoč dopředu při téměř všech kódech pro řídící znaky. Skoč dopředu s kódem pro CAPS LOCK nebo pro změnu "mode".
Nyní se vypořádej s FLASH, BRIGHT a INVERSE. LD AND LD LD RRA ADD JR
B,A #01 C,A A,B A,#12 #1105,KEY-DATA
Ulož si kód. Ponech si pouze bit 0. C obsahuje #00 (=off) nebo #01 Vyzvedni kód. Jednou ho rotuj, čím přijdeš o Přičti #12 kvůli BRIGHT, FLASH a pokračuj dále s parametrem v
(=on). bit 0. a INVERSE C.
Kód pro CAPS LOCK a kód modů jsou ošetřeny místně. 10DB
KEY-M&CL
10E6
KEY-MODE
64
JR LD LD XOR LD JR CP RET SUB LD CP LD JR LD
NZ,#10E6,KEY-MODE HL,#5C6A A,#08 (HL) (HL),A #10F4,KEY-FLAG #0E C #0D HL,#5C41 (HL) (HL),A NZ,#10F4,KEY-FLAG (HL),#00
Skoč s kódy modů. Toto je FLAGS2. Flipuj bit 3 FLAGS2. Jedná se o vlajku CAPS LOCK. Skoč dopředu. Zkontroluj dolní limit. Sniž rozsah. Toto je MODE. Bylo změněno? Vlož kód nového mode a skoč, když bylo změněno. Jinak nastav "L" mode. Komentovaný výpis paměti ROM
10F4
KEY-FLAG
SET CP RET
3,(IY+2) (TV-FLAG) A
Signál mode mohlo být změněno. Nuluj CY flag a vrať se.
Nyní jsou zpracovány kódy řídících znaků (mimo FLASH, BRIGHT a INVERSE) pro barvy (16-23 INK a 24-31 PAPER). 10FA
KEY-CONTR
LD AND LD LD BIT JR INC
B,A #07 C,A A,#10 3,B NZ,#1105,KEY-DATA A
Uschovej kód. Nastav registr C na #00 až #07. Registr A nyní obsahuje kód pro INK. Ale nebyl-li kód definován pomocí SHIFTu, nastav registr A na hodnotu PAPER.
Parametr je nyní uschován v proměnné K-DATA a kanálová adresa je změněna z KEY-INPUT na KEY-NEXT. 1105
KEY-DATA
LD LD JR
(IY-45),C (K-DATA) DE,#110D #1113,KEY-CHAN
Ulož parametr. Toto je KEY-NEXT. Skoč dopředu.
Poznámka: Při prvním průchodu přes KEY-INPUT je v registru A vrácena hodnota kontrolního kódu. Při dalším vstupu přes KEY-NEXT se vrací parametr. 110D
KEY-NEXT
LD LD
A,(#5C0D) (K-DATA) DE,#10A8
Vyzvedni parametr. Toto je KEY-INPUT.
Nyní nastav vstupní adresu na první kanálovou oblast. 1113
KEY-CHAN
LD INC INC LD INC LD
HL,(#5C40) (CHANS) HL HL (HL),E HL (HL),D
Vyzvedni kanálovou adresu.
Nyní nastav vstupní adresu.
Konečně výstup s požadovaným kódem v registru A. 111B
KEY-DONE
SCF RET
Signalizuj, že kód byl nalezen a vrať se.
PODPROGRAM PRO OKOPÍROVÁNÍ DOLNÍ ČÁSTI OBRAZOVKY Tento podprogram je volán kdykoli má být řádek z editační oblasti nebo z oblasti INPUTu vytisknut na obrazovku. 111D
ED-COPY
CALL RES RES LD PUSH LD PUSH LD PUSH LD LD PUSH
#0D4D,TEMPS 3,(IY+2) (TV-FLAG) 5,(IY+2) (TV-FLAG) HL,(#5C8A) (S-POSNL) HL HL,(#5C3D) (ERR-SP) HL HL,#1167 HL (#5C3D),SP (ERR-SP) HL,(#5C82) (ECHO-E) HL
Použij permanentní barvy. Signál: mód nezměněn Signál: Nečistit dolní část obrazovky. Uschovej současnou hodnotu S-POSNL. Uschovej současnou hodnotu ERR-SP. Toto je ED-FULL. Uschovej tuto hodnotu na zásobník a tím se tato hodnota stane vstupním bodem při chybě. Ulož na zásobník hodnotu ECHO-E.
Komentovaný výpis paměti ROM
65
SCF CALL EX CALL EX CALL LD EX EX CALL
#1195,SET-HL DE,HL #187D,OUT-LINE2 DE,HL #18E1,OUT-CURS HL,(#5C8A) (S-POSNL) (SP),HL DE,HL #0D4D,TEMPS
Zbytek řádku, který permanentního PAPERu. 1150
ED-BLANK
115E
ED-SPACES
LD SUB JR JR LD SUB JR LD PUSH CALL POP JR
byl
právě
HL bude ukazovat na začátek prostoru a DE na jeho konec. Zaměň ukazatele. Vytiskni řádek. Opět zaměň ukazatele a vytiskni kurzor. Potom vyzvedni současnou hodnotu S-POSNL a zaměň ji s ECHO-E. Předej ECHO-E do DE. Opět vyzvedni permanentní barvy.
obsluhován
A,(#5C8B)(S-POSNL-hi) D C,#117C,ED-C-DONE NZ,#115E,ED-SPACES A,E (IY+80) (S-POSNL-lo) NC,#117C,ED-C-DONE A,#20 DE #09F4,PRINT-OUT DE #1150,ED-BLANK
je
nyní
vyplněn
mezerami,
tištěnými
v
barvách
Vyzvedni číslo současného řádku a odečti číslo starého řádku. Skoč vpřed, není-li třeba dodat mezery. Skoč vpřed, jestliže se nenacházíš na stejném řádku. Vyzvedni staré číslo sloupce a odečti ho od nového čísla sloupce. Skoč, když není zapotřebí mezerovat. Toto je mezera. Uschovej staré hodnoty. Vytiskni mezeru. Vyzvedni staré hodnoty. A skoč opět zpět.
Nyní ošetři jakoukoli chybu. 1167
ED-FULL
LD LD LD CALL LD LD JR
D,#00 E,(IY-2) (RASP) HL,#1A90 #03B5,BEEPER (IY+0),#FF (ERR-NR) DE,(#5C8A) (S-POSNL) #117E,ED-C-END
Zavrč. Zruš číslo chyby. Vyzvedni současnou hodnotu S-POSNL a skoč dopředu.
Zde je normální výstup po dokončení kopírování editačního řádku. 117C
ED-C-DONE
POP POP
DE HL
Hodnota nové pozice. a adresa chyby.
Sem ale přijde po chybě. 117E
ED-C-END
POP LD POP PUSH CALL POP LD LD RET
HL (#5C3D),HL (ERR-SP) BC DE #0DD9,CL-SET HL (#5C82),HL (ECHO-E) (IY+38),#00(X-PTR-hi)
Stará hodnota ERR-SP je obnovena. Vyzvedni starou hodnotu S-POSNL a uschovej hodnoty nové pozice. Nastav systémové proměnné a starou hodnotu S-POSNL dej do ECHO-E. X-PTR-hi je vynulována a je proveden návrat.
PODPROGRAM NA NASTAVENÍ "HL" A "DE" Tyto podprogramy vrací registry HL a DE tak, že HL ukazuje na první a DE na poslední lokaci editačního prostoru nebo WORKSPACE. 66
Komentovaný výpis paměti ROM
1190
SET-HL
1195
SET-DE
LD DEC AND LD BIT RET LD RET LD RET
HL,(#5C61) (WORKSP) HL A DE,(#5C59) (E-LINE) 5,(IY+55) (FLAGX) Z DE,(#5C61) (WORKSP) C HL,(#5C63) (STKBOT)
Ukazuj na poslední lokaci editační oblasti. Nuluj CY flag. Ukazuj na začátek editační oblasti a jsi-li v editačním módu, vrať se. Jinak změň DE a vrať se, bylo-li to úmyslem. Vyzvedni STKBOT a vrať se.
PODPROGRAM ODSTRANĚNÍ FP Tento podprogram odstraňuje skryté floating point formy z BASICového řádku. 11A7
REMOVE-FP
LD CP LD CALL LD INC CP JR RET
A,(HL) #0E BC,#0006 Z,#19E8,RECLAIM-2 A,(HL) HL #0D NZ,#11A7,REMOVE-FP
Všechny znaky jsou postupně ohledány. Je to značka čísla? Číslo zabírá šest míst. Zrušení FP čísla pokud je třeba. Vyzvedni opět tento kód. Posuň ukazatel. Je to CR? (=ENTER) Opakuj když ne, jinak proveď návrat.
Komentovaný výpis paměti ROM
67
PROVÁDĚCÍ PODPROGRAMY INICIAČNÍ PODPROGRAM Hlavní vstupní bod do tohoto podprogramu je na START/NEW (#11CB). Při vstupu ze startu (#0000), například je-li do systému při zapojení poprvé přivedeno napětí, registr A obsahuje #00 a registr DE obsahuje #FFFF. Nicméně vstupní bod může být též dosažen při vykonání příkazu NEW. PODPROGRAM PŘÍKAZU NEW 11B7
NEW
DI LD LD EXX LD LD LD EXX
Zakázáno maskované přerušení. Signál: NEW. Existující hodnota systémové proměnné RAMTOP vyzvednuta. Zrcadlové registry BC,(#5CB4) (P-RAMT) jsou naplněny DE,(#5C38) (RASP/PIP) těmito systémovými HL,(#5C7B) (UDG) proměnnými, které mají být rovněž uschovány. A,#FF DE,(#5CB2) (RAMTOP)
Hlavní vstupní bod. 11CB
START/NEW
LD LD OUT LD LD DEFB DEFB
B,A A,#07 (#FE),A A,#3F I,A #00,#00,#00 #00,#00,#00
Uschovej signál pro pozdější použití. Barva pro BORDER: bílá. Nastav registr I na hodnotu #3F. Čekej 24 T stavů.
Nyní se bude kontrolovat paměť. 11DA
RAM-CHECK
11DC
RAM-FILL
11E2
RAM-READ
11EF
RAM-DONE
LD LD LD DEC CP JR AND SBC ADD INC JR DEC JR
H,D L,E (HL),#02 HL H NZ,#11DC,RAM-FILL A HL,DE HL,DE HL NC,#11EF,RAM-DONE (HL) Z,#11EF,RAM-DONE
DEC JR DEC
(HL) Z,#11E2,RAM-READ HL
Přenes hodnotu v registrovém páru DE do HL (START = #FFFF, NEW = RAMTOP). Ulož hodnotu #02 do všech paměťových míst nad #3FFF. Připrav se pro pravdivý odečet. CY flag=0 při dosažení konce, Uprav ukazatel. Skoč, jsi-li na konci. #02 se mění na #01. Ale je-li zde nula, znamená to že paměť je vadná. Použij současnou hodnotu HL jako nejvyšší možnou adresu. #01 se mění na #00. Průchod dalším testem, dokud nedošlo k selhání. HL ukazuje na poslední provozuschopné místo.
Nyní budou obnoveny původní uschované systémové proměnné (což nemá žádný smysl jestliže program běží od STARTu). EXX LD LD LD EXX INC JR 68
Přepni registry. (#5CB4),BC (P-RAMT) Obnov P-RAMT (#5C38),DE (RASP/PIP) RASP/PIP a (#5C7B),HL (UDG) UDG. Přepni registry. B Testuj signál START/NEW. Z,#1219,RAM-SET Skoč dopředu, přicházíš-li z podprogramu NEW. Komentovaný výpis paměti ROM
Přepiš systémové proměnné, jestliže přicházíš od STARTu, a inicializuj oblast UDG. LD LD LD EX LDDR EX INC LD DEC LD LD
(#5CB4),HL (P-RAMT) DE,#3EAF BC,#00A8 DE,HL
To je maximální fyzická adresa RAM. Poslední bajt písmene "U" ve znakovém souboru. Toto je počet bajtů pro 21 písmen. Přepni ukazatele. Nyní okopíruj znakové formy písmen "A" až "U". Přepni zpět. Ukazuj na první bajt a nastav UDG. O jedno místo dolů.
DE,HL HL (#5C7B),HL (UDG) HL BC,#0040 (#5C38),BC (RASP/PIP) Nastav systémové proměnné RASP a PIP.
Zbytek tohoto podprogramu je společný jak pro START, tak pro NEW. 1219
RAM-SET
LD LD LD
(#5CB2),HL (RAMTOP) HL,#3C00 (#5C36),HL (CHARS)
Nastav RAMTOP a systémovou proměnnou CHARS.
Nyní nastav zásobník. LD LD DEC LD DEC DEC LD
HL,(#5CB2) (RAMTOP) (HL),#3E HL SP,HL HL HL (#5C3D),HL (ERR-SP)
Jeho nejvyšší místo bude obsahovat hodnotu #3E. Další místo je ponecháno, aby obsahovalo nulu. Tato dvě místa reprezentující poslední úložku. Přeskoč dvě místa, abys získal správnou hodnotu pro ERR-SP.
Iniciační podprogram pokračuje takto: IM LD EI
1 IY,#5C3A
LD LD LD LD EX LDIR EX DEC LD INC LD LD LD INC LD LD
HL,#5CB6 (#5C4F),HL (CHANS) DE,#15AF BC,#0015 DE,HL DE,HL HL (#5C57),HL HL (#5C53),HL (#5C4B),HL (HL),#80 HL (#5C59),HL (HL),#0D
INC LD INC LD
HL (HL),#80 HL (#5C61),HL (WORKSP)
(DATADD)
Přerušovací mód IM 1. IY obsahuje vždy hodnotu ERR-NR. Maskované přerušení bude povoleno, hodiny nastaveny a každou 1/50 sec. test klávesnice. Bázová adresa oblasti kanálových informací. Počáteční kanálová data jsou přesunuta z tabulky (na adrese #15AF) do oblasti kanálových informací. Systémová proměnná DATADD je nastavena tak, aby ukazovala na poslední místo oblasti kanálových dat. A proměnné PROG a VARS na místo za ní.
(PROG) (VARS)
(E-LINE)
Ulož koncový znak této oblasti. Jedno místo dopředu pro správnou hodnotu E-LINE. Zajisti, aby v editační oblasti byl pouze znak CR (=ENTER). Nyní vlož další koncový bajt a pohni se znovu dopředu, abys získal hodnoty pro WORKSP,
Komentovaný výpis paměti ROM
69
LD LD LD LD LD LD LD LD DEC DEC LD LD LD LDIR SET CALL LD CALL XOR LD CALL SET JR
(#5C63),HL (STKBOT) (#5C65),HL (STKEND) A,#38 (#5C8D),A (ATTR-P) (#5C8F),A (ATTR-T) (#5C48),A (BORDCR) HL,#0523 (#5C09),HL (REPDEL) (IY-58) (KSTATE0) (IY-54) (KSTATE4) HL,#15C6 DE,#5C10 BC,#000E
STKBOT a STKEND.
1,(IY+1) (FLAGS) #0EDF,CLEAR-PRB (IY+49),#02 (DF-SZ) #0D6B,CLS A DE,#1538 #0C0A,PO-MSG 5,(IY+2) (TV-FLAG) #12A9,MAIN-1
Signál: používá se tiskárna. Nuluj bafr tiskárny. Nastav velikost dolní části obrazovky a smaž celý displej. Tiskni sdělení '© 1982 Sinclair Research Ltd' na spodní řádek obrazovky. Signál: spodní část obrazovky bude třeba smazat. Skok do hlavní prováděcí smyčky.
Inicializuj systémové proměnné pro barvy na: BORDER 7, INK 0, PAPER 7, BRIGHT 0 a FLASH 0. Hodnota pro systémové proměnné REPDEL a REPPER. Na KSTATE0 ulož hodnotu #FF Na KSTATE4 #FF Přenes data z tab. proudových dat do informační oblasti proudových dat.
HLAVNÍ PROVÁDĚCÍ SMYČKA Tato smyčka se v paměti rozkládá od adresy #12A2 až do adresy #15AE a řídí editační mod, provádění přímých příkazů a výpisy sdělení. 12A2
MAIN-EXEC
12A9
MAIN-1
12AC
MAIN-2
LD (IY+49),#02 (DF-SZ) CALL #1795,AUTO-LIST CALL #16B0,SET-MIN LD CALL CALL CALL BIT JR BIT JR LD CALL LD JR
A,#00 #1601,CHAN-OPEN #0F2C,EDITOR #1B17,LINE-SCAN 7,(IY+0) (ERR-NR) NZ,#12CF,MAIN-3 4,(IY+48) (FLAGS2) Z,#1303,MAIN-4 HL,(#5C59) (E-LINE) #11A7,REMOVE-FP (IY+0),#FF (ERR-NR) #12AC,MAIN-2
Dolní část obrazovky bude velká dva řádky. Je proveden automatický výpis. Všechny oblasti od E-LINE dopředu budou mít minimální velikost. Kanál "K" je otevřen. Je zavolán editor, aby uživatel mohl vytvořit nový řádek, ve kterém je následovně ošetřena syntaxe. Je-li v pořádku, skok dopředu. Při použití jiného kanálu než "K" je proveden skok dopředu. Ukazuj na začátek řádku kde je chyba. Odstraň FP formy z tohoto řádku, nastav ERR-NR na "OK" a skoč na MAIN-2, aniž by se ve výpisu cokoliv změnilo.
Editovaný řádek prošel syntaxí a nyní je třeba rozlišit tři různé typy řádků. 12CF
70
MAIN-3
LD LD CALL LD OR JR RST CP JR
HL,(#5C59) (E-LINE) (#5C5D),HL (CH-ADD) #19FB,E-LINE-NO A,B C NZ,#155D,MAIN-ADD #18 #0D Z,#12A2,MAIN-EXEC
Ukazuj na začátek řádku a tam také nastav CH-ADD. Vyzvedni jakékoliv číslo řádku do BC a je-li to platné číslo řádku, skoč dopředu a zařaď jej do programu. Vyzvedni první znak tohoto řádku a podívej se, jestli jde o řádek nebo o pouhý CR (=ENTER). Skoč zpět, bylo-li tomu tak.
Komentovaný výpis paměti ROM
Editovaný řádek musí začínat přímým basicovým příkazem, takže tento se stává prvním, který bude interpretován. BIT CALL CALL LD SUB LD SET LD LD CALL
0,(IY+48) (FLAGS2) NZ,#0DAF,CL-ALL #0D6E,CLS-LOWER A,#19 (IY+79) (S-POSN-hi) (#5C8C),A (SCR-CT) 7,(IY+1) (FLAGS) (IY+0),#FF (ERR-NR) (IY+10),#01 (NSPPC) #1B8A,LINE-RUN
Celá obrazovka bude smazána v případě potřeby, jinak jen spodní část. Nastav příslušné hodnoty pro rolovací čítač. Signál: vykonání řádku. Zajištění hodnoty "OK", na ERR-NR a ošetření prvního příkazu v řádku. Nyní proveď tento řádek.
Poznámka: na zásobník bude uložena hodnota #1303 a bude adresována systémovou proměnnou ERR-SP. Po interpretaci řádku a po vykonání všech z toho vyplývajících akcí se program vrací do MAIN-4, aby mohlo být vytisknuto hlášení. 1303
1313
133C
MAIN-4
MAIN-G
MAIN-5
HALT RES BIT CALL LD INC PUSH LD LD LD LD LD LD CALL
5,(IY+1) (FLAGS) 1,(IY+48) (FLAGS2) NZ,#0ECD,COPY-BUFF A,(#5C3A) (ERR-NR) A AF HL,#0000 (IY+55),H (FLAGX) (IY+38),H (X-PTR-hi) (#5C0B),HL (DEFADD) HL,#0001 (#5C16),HL (STRMS+6) #16B0,SET-MIN
RES CALL SET POP LD CP JR ADD CALL LD RST LD LD CALL XOR LD CALL LD CALL LD RST LD LD CALL
5,(IY+55) (FLAGX) #0D6E,CLS-LOWER 5,(IY+2) (TV-FLAG) AF B,A #0A C,#133C,MAIN-5 A,#07 #15EF,OUT-CODE A,#20 #10,PRINT-A-1 A,B DE,#1391 #0C0A,PO-MSG A DE,#1536 #0C0A,PO-MSG BC,(#5C45) (PPC) #1A1B,OUT-NUM-1 A,#3A #10,PRINT-A-1 C,(IY+13) (SUBPPC) B,#00 #1A1B,OUT-NUM1
Musí být obnoveno maskované přerušení. Signál: možno další klávesu. Byl-li použit bafr tiskárny, bude vyčištěn. Vyzvedni číslo chyby a zvětši ho. Uschovej si tuto novou hodnotu. Nuluj systémové proměnné FLAGX, X-PTR-hi a DEFADD.
Zajisti, aby proud #00 ukazoval na kanál "K". Vyčisti všechny pracovní oblasti a kalkulátorový zásobník. Signál editační mód. Vyčisti dolní část obrazovky. Dolní část obrazovky bude potřeba vyčistit. Vyzvedni hodnotu hlášení, okopíruj ji do B a s čísly hlášení 0-9 skoč dopředu. Přičti doplněk ASCII znaku. Vytiskni kód sdělení a vlož mezeru. Vyzvedni znovu hodnotu sdělení a použij ji k identifikaci sdělení.
Vytiskni sdělení a udělej za ním čárku a mezeru. Vyzvedni číslo aktuálního řádku a také ho vytiskni. Dále vytiskni ":". Vyzvedni číslo aktuálního příkazu do registru BC a vytiskni ho.
Komentovaný výpis paměti ROM
71
1373 1376
1384 1386
MAIN-6 MAIN-7
MAIN-8 MAIN-9
CALL LD INC JR CP JR CP JR INC LD LD LD
#1097,CLEAR-SP A,(#5C3A) (ERR-NR) A Z,#1386,MAIN-9 #09 Z,#1373,MAIN-6 #15 NZ,#1376,MAIN-7 (IY+13) (SUBPPC) BC,#0003 DE,#5C70 HL,#5C44
BIT JR ADD LDDR LD RES JP
7,(HL) (NSPPC) Z,#1384,MAIN-8 HL,BC (IY+10),#FF (NSPPC) 3,(IY+1) (FLAGS) #12AC,MAIN-2
Vyčisti editační oblast. Vyzvedni opět číslo chyby a zvětši ho jako obvykle. Skoč dopředu, nedošlo-li k chybě. Byl-li program zastaven příkazem STOP či BREAK, skoč dopředu. Jinak bude proměnná SUBPPC nezměněna. Zvyš SUBPPC na následující příkaz. Systémové proměnné OLDPPC a OSPPC musí být upraveny tak, aby ukazovaly na číslo příkazu ve správném řádku, kde se bude pokračovat. Hodnoty, které budou použity, budou nalezeny v PPC a SUBPPC, pokud ovšem NSPPC neukazuje, že k BREAKu došlo při skoku (např. GOTO).
NSPPC je nastavena tak, aby ukazovala "žádný skok". Je nastaven "K" mod a je proveden skok,ale tak, aby nebyl proveden programový výpis, pokud to není třeba.
CHYBOVÁ HLÁŠENÍ Poslední znak každého hlášení je "invertován" (+#80). 1391 1392 1394 13A4 13B6 13C6 13D2 13DF 13ED 1401 140C 141A 142A 143E 144F 1463 146E 147F 148F 149C 14AC 14BE 14CC 14DE 14EC 14FA 1508 1516 1525
DEFB #80 Report 0 Report 1 Report 2 Report 3 Report 4 Report 5 Report 6 Report 7 Report 8 Report 9 Report A Report B Report C Report D Report E Report F Report G Report H Report I Report J Report K Report L Report M Report N Report O Report P Report Q Report R
-
zde se překročí počáteční bajt "OK" “NEXT without FOR“ “Variable not found“ "Subscript wrong" "Out of memory" "Out of screen" "Number too big" "RETURN without GOSUB" "End of file" "STOP statement" "Invalid argument" "Integer out of range" "Nonsense in BASIC" "BREAK - CONT repeats" "Out of DATA" "Invalid file name" "No room for line" "STOP in INPUT" "FOR without NEXT" "Invalid I/O device" "Invalid colour" "BREAK into program" "RAMTOP no good" "Statement lost" "Invalid stream" "FN without DEF" "Parameter error" "Tape loading error"
Jsou zde také ještě následující dvě sdělení: 1537 72
", "
-"čárka" a "mezera" Komentovaný výpis paměti ROM
1539
"© 1982 Sinclair Research Ltd"
1555
REPORT-G
LD LD JP
A,#10 BC,#0000 #1313,MAIN-G
"G" má kód "10+07+30" Nuluj BC. Skoč zpět na tisk hlášení G.
PODPROGRAM MAIN-ADD Tento podprogram umožňuje basicovému řádku, aby mohl být přidán do existujícího basicového programu v programové oblasti. Existuje-li jak nová, tak i stará verze řádku se stejným číslem, pak bude starý řádek zničen. Pokud nový řádek obsahuje pouze svoje číslo, nebude do programu zařazen. 155D
157D
MAIN-ADD
MAIN-ADD1
LD LD EX LD PUSH
(#5C49),BC (E-PPC) HL,(#5C5D) (CH-ADD) DE,HL HL,#1555 HL
LD SCF SBC, PUSH LD LD CALL JR CALL CALL POP LD DEC OR JR PUSH INC INC INC INC DEC LD PUSH CALL POP LD POP PUSH INC LD DEC DEC LDDR LD EX POP LD DEC LD
HL,(#5C61) (WORKSP) HL,DE HL H,B L,C #196E,LINE-ADDR NZ,#157D,MAIN-ADD1 #19B8,NEXT-ONE #19E8,RECLAIM-2 BC A,C A B Z,#15AB,MAIN-ADD2 BC BC BC BC BC HL DE,(#5C53) (PROG) DE #1655,MAKE-ROOM HL (#5C53),HL (PROG) BC BC DE HL,(#5C61) (WORKSP) HL HL HL,(#5C49) (E-PPC) DE,HL BC (HL),B HL (HL),C
Nechť je číslo nového řádku aktuálním číslem. Vyzvedni CH-ADD a uschovej její adresu v DE. Uschovej adresu hlášení "G" na zásobník, kam ukazuje i ERR-SP. Vyzvedni WORKSP. Najdi délku řádku od místa za číslem řádku až po znak CR (=ENTER) a tuto délku uschovej. Přenes číslo řádku do HL. Existuje již číslo takového řádku? Skoč, když ne. Najdi délku starého řádku a znič ho. Vyzvedni délku nového řádku, ale jednalo-li se pouze o číslo řádku +CR, skoč dopředu. Uschovej délku. Jsou zapotřebí čtyři místa navíc. Dvě pro číslo a dvě pro délku. Nastav HL tak, aby ukazovalo před místo určení. Uschovej současnou hodnotu PROG, aby se zabránilo zhroucení po přidání jednoho řádku. Místo pro přidání jednoho řádku je vytvořeno. Stará hodnota PROG je vyzvednuta a obnovena. Kopie délky řádku (bez parametrů) je vyzvednuta. DE ukazuje na poslední místo nové oblasti a HL na CR (=ENTER) v novém řádku, který je v editační oblasti. Nyní překopíruj celý řádek. Vyzvedni číslo nového řádku. Adresa určení jde do HL a číslo do DE. Vyzvedni délku nového řádku a ulož její vyšší a nižší bajt.
Komentovaný výpis paměti ROM
73
Nyní si povšimněte, že dvoubajtová hodnota udávající číslo řádku zde na rozdíl od systému procesoru Z80 ukládána v opačném pořadí.
15AB
MAIN-ADD2
DEC LD DEC LD POP JP
HL (HL),E HL (HL),D AF #12A2,MAIN-EXEC
Nižší bajt čísla řádku !! Vyšší bajt čísla řádku !! Odhoď adresu hlášení "G" a po odskoku zpět proveď i automatický výpis.
POČÁTEČNÍ KANÁLOVÉ INFORMACE Na počátku existují čtyři kanály "K", "S", "R" a "P" pro komunikaci s klávesnicí, obrazovkou, pracovním prostorem a tiskárnou. Data jsou uložena v tomto pořadí: adresa vstupního podprogramu, adresa výstupního podprogramu a kód kanálu. 15AF
15C3
DEFW DEFW DEFB DEFW DEFW DEFB DEFW DEFW DEFB DEFW DEFW DEFB DEFB
09F4 10A8 4B 09F4 15C4 53 0F81 15C4 52 09F4 15C4 50 80
15C4
REPORT-J
RST #08,ERROR-1 DEFB #12
15B4
15B9
15BE
PRINT-OUT KEY-INPUT 'K' PRINT-OUT REPORT-J 'S' ADD-CHAR REPORT-J 'R' PRINT-OUT REPORT-J 'P' Koncový znak. Ohlaš: J-Invalid I/O device
POČÁTEČNÍ PROUDOVÁ DATA Na počátků existuje sedm proudů: od #FD do #03. 15C6 15C8 15CA 15CC 15CE 15D0 15D2
DEFB DEFB DEFB DEFB DEFB DEFB DEFB
#01, #06, #0B, #01, #01, #06, #10,
#00 #00 #00 #00 #00 #00 #00
proud proud proud proud proud proud proud
#FD #FE #FF #00 #01 #02 #03
směřuje směřuje směřuje směřuje směřuje směřuje směřuje
ke ke ke ke ke ke ke
kanálu kanálu kanálu kanálu kanálu kanálu kanálu
'K' 'S' 'R' 'K' 'K' 'S' 'P'
PODPROGRAM ČEKEJ NA KLÁVESU Tento podprogram je řídící podprogram pro volání aktuálních vstupních podprogramů. 15D4
WAIT-KEY
15DE
WAIT-KEY1
BIT JR SET CALL RET JR
5,(IY+2) (TV-FLAG) NZ,#15DE,WAIT-KEY1 3,(IY+2) (TV-FLAG) #15E6,INPUT-AD C Z,#15DE,WAIT-KEY1
Není-li třeba čistit dolní část obrazovky skoč dopředu. Jinak signál: "posuzuj mód jako kdyby se změnil". Volej vstupní podprogram nepřímo přes INPUT-AD. Vrať se s akceptovatelnými kódy. Skoč, nebyla-li stištěna žádná klávesa.
Jsou-li CY i Z nastaveny na nulu, znamená to, že nebylo stištěno žádné tlačítko a došlo k nějaké chybě. 74
Komentovaný výpis paměti ROM
15E4
REPORT-8
RST #08,ERROR-1 DEFB #07
Ohlaš: 8-End of file.
PODPROGRAM INPUT-AD Registry jsou uschovány a HL ukazuje na adresu vstupního podprogramu. 15E6
INPUT-AD
EXX PUSH LD INC INC JR
HL HL,(#5C51) (CURCHL) HL HL #15F7,CALL-SUB
Uschovej registry. Vyzvedni bázovou adresu aktuální kanálové informace. Překroč výstupní adresu a skoč dopředu.
HLAVNÍ TISKOVÝ PODPROGRAM Tento podprogram je volán buď s absolutní hodnotou nebo řádným znakovým kódem v registru A. 15EF
OUT-CODE
15F2
PRINT-A-2
LD ADD EXX PUSH LD
E,#30 A,E HL HL,(#5C51) (CURCHL)
Hodnota v registru A je zvýšena o #30. Uschovej registry. Vyzvedni bázovou adresu aktuální kanálové informace. Tato ukazuje na výstupní podprogram.
Nyní volej skutečný podprogram. HL ukazuje na adresu vstupního nebo výstupního podprogramu. 15F7
CALL-SUB
LD INC LD EX CALL POP EXX RET
E,(HL) HL D,(HL) DE,HL #162C,CALL-JUMP HL
Vyzvedni nižší bajt. Vyzvedni vyšší bajt. Přenes adresu do HL. Zavolej požadovaný podprogram. Obnov registry. Odtud bude proveden návrat, pokud cestou nedošlo k chybě.
PODPROGRAM CHAN-OPEN Do tohoto podprogramu vstupuje v registru A platné číslo proudu (normálně #FD až #03) a v závislosti na tomto čísle je otevřen příslušný kanál. 1601
160E
CHAN-OPEN
REPORT-0
ADD ADD LD LD LD INC LD LD OR JR RST DEFB
A,A A,#16 L,A H,#5C E,(HL) HL D,(HL) A,D E NZ,#1610,CHAN-OP-1 #08,ERROR-1 #17
Hodnota v registru A je zdvojena a dále zvětšena o #16. Výsledek je předán do L. Adresa #5C16 je bázovou adresou pro proud #00. Vyzvedni první a druhý bajt požadovaných kanálových dat.
Skoč dopředu, nejsou-li oba bajty nulové, jinak ohlaš: O-Invalid stream
S použitím proudových dat nyní najdi bázovou adresu kanálové informace, která souvisí s daným kanálem. 1610
CHAN-OP-1
DEC
DE
Sniž proudová data.
Komentovaný výpis paměti ROM
75
LD ADD
HL,(#5C4F) (CHANS) HL,DE
Toto je bázová adresa informační oblasti kanálových dat v níž bude nyní nalezena požadovaná adresa.
PODPROGRAM CHAN-FLAG Tento podprogram nastavuje příslušné vlajky pro různé kanály. 1615
162C
CHAN-FLAG
CALL-JUMP
LD RES INC INC INC INC LD LD CALL RET LD LD ADD JP
(#5C51),HL (CURCHL) 4,(IY+48) (FLAGS2) HL HL HL HL C,(HL) HL,#162D #16DC,INDEXER NC D,#00 E,(HL) HL,DE (HL)
V HL je bázová adresa daného kanálu. Signál: používá se jiný kanál než "K". Překroč výstupní a vstupní adresy. Vyzvedni kód kanálu. Toto je bázová adresa tabulky kanálových kódů. Hledej v této tabulce a urči vhodný doplněk, ale vrať se v případě, že jsi nenalezl vhodný kanálový kód. Předej doplněk do registrového páru DE a skoč dopředu na příslušný podprogram, nastavující flag.
TABULKA KANÁLOVÝCH KÓDŮ 162D 162F 1631 1633
DEFB DEFB DEFB DEFB
4B 06 kanál 'K' ofset #06 53 12 kanál 'S' ofset #12 50 1B kanál 'P' ofset #1B 00 koncová značka.
adresa #1634 adresa #1642 adresa #164D
PODPROGRAM FLAG KANÁLU " K " 1634
CHAN-K
SET RES SET JR
0,(IY+2) (TV-FLAG) 5,(IY+1) (FLAGS) 4,(IY+48) (FLAGS2) #1646,CHAN-S-1
Signál: užita dolní část obrazovky. Signál: připraven přijmout další klávesu. Signál: použit kanál "S". Skok dopředu.
PODPROGRAM FLAG KANÁLU " S " 1642 1646
CHAN-S CHAN-S-1
RES RES JP
0,(IY+2) (TV-FLAG) 1,(IY+1) (FLAGS) #0D4D,TEMPS
Signál: užita hlavní část obrazovky. Signál: tiskárna není právě používána. Vrať se přes TEMPS, aby byly nastaveny správné barvy.
PODPROGRAM FLAG KANÁLU " P " 164D
76
CHAN-P
SET RET
1,(IY+1) (FLAGS)
Signál: nyní bude použita tiskárna.
Komentovaný výpis paměti ROM
PODPROGRAM "VYTVOŘ PROSTOR" Toto je velmi důležitý podprogram. Je volán při mnoha příležitostech, aby vytvořil nějaký prostor. Proto musí HL ukazovat na adresu za prvním bajtem požadovaného prostoru a v BC musí být délka požadovaného prostoru. Je-li vyžadován prostor o velikosti jediného bajtu, vstupuje se do tohoto podprogramu v bodě ONE-SPACE. 1652 1655
ONE-SPACE MAKE-ROOM
LD BC,#0001 PUSH HL CALL #1F05,TEST-ROOM POP CALL LD EX LDDR RET
HL #1664,POINTERS HL,(#5C65) (STKEND) DE,HL
Pouze jeden bajt. Uschovej ukazatel. Zjisti, zda je zde dost volné paměti pro požadovaný prostor. Obnov ukazatel. Změň všechny ukazatele, než vytvoříš žádaný prostor. Ulož do HL hodnotu STKEND. Zaměň "staré" a "nové". Nyní vytvoř prostor a vrať se.
Poznámka: Po návratu z tohoto podprogramu ukazuje registr HL na místo před novým prostorem a registr DE ukazuje na poslední bajt nově vytvořeného prostoru. Nový prostor může být popsán takto: od (HL)+1 až do (DE) včetně. Nicméně "nové místa" mají i své "staré adresy" a tak je možno popsat nový prostor také takto: od (HL)+2 až do (DE)+1. Ve skutečnosti se zdá, že programátor dával přednost druhému popisu, a to může být matoucí.
PODPROGRAM "UKAZATELÉ" Kdykoliv je vytvářen nebo rušen nějaký prostor, musí být všechny ukazatele, které nějak souvisí s tímto prostorem, nastaveny. Na vstupu obsahuje registrový pár BC počet bajtů, o které se bude jednat, a registrový pár HL adresu místa před novým prostorem. 1664
POINTERS
PUSH PUSH LD LD
AF HL HL,#5C4B A,#0E
Tyto registry jsou uschovány. Kopíruj adresu "pozice". Toto je VARS, první ze čtrnácti systémových ukazatelů (proměnných).
Tato smyčka sice obslouží všechny ukazatele, ale změněny budou jenom ty, které ukazují za danou "pozici". 166B
167F
PTR-NEXT
PTR-DONE
LD INC LD EX AND SBC ADD EX JR PUSH EX ADD EX LD DEC LD INC POP INC DEC JR
E,(HL) HL D,(HL) (SP),HL A HL,DE HL,DE (SP),HL NC,#167F,PTR-DONE DE DE,HL HL,BC DE,HL (HL),D HL (HL),E HL DE HL A NZ,#166B,PTR-NEXT
Vyzvedni dva bajty současného ukazatele.
Zaměň systémové proměnné s adresou "pozice". CY flag bude, nastaven jestliže má být hodnota této proměnné pozměněna. Obnov "pozici". Skoč dopředu, jestliže se nemá tento ukazatel měnit. Jinak uschovej starou hodnotu. Nyní k ní přičti hodnotu v BC a vlož tuto novou hodnotu do systémové proměnné. Nejprve vyšší bajt, pak nižší. Ukazuj znovu na první bajt. Vyzvedni starou hodnotu. Ukazuj na další systémovou proměnnou a jestliže nebylo posouzeno všech 14 syst. proměnných, vracej se zpět do smyčky.
Komentovaný výpis paměti ROM
77
Nalezení velikosti bloku, který se bude přesouvat. EX POP POP AND SBC LD LD INC ADD EX RET
DE,HL DE AF A HL,DE B,H C,L BC HL,DE DE,HL
Stará hodnota STKEND jde do HL a hodnoty ostatních registrů jsou obnoveny. Nyní nalezni rozdíl mezi starou hodnotou STKEND a "pozicí". Převeď výsledek do BC a zvyš o 1 pro bajt navíc. Uprav zpět na starou hodnotu STKEND a převeď ji do DE před návratem.
PODPROGRAM VYZVEDNUTÍ ČÍSLA ŘÁDKU Na vstupu ukazuje HL na místo, které má být posouzeno. Jestliže se na tomto místě nachází bajt, jehož hodnota je vyšší bajt čísla řádku, vrací se toto číslo v DE. V opačném případě se stejným způsobem otestuje lokace adresovaná DE a jestliže ani tato nesplňuje podmínku, vrací se číslo řádku 0. 168F
LINE-ZERO
1691
LINE-NO-A
DEFB DEFB EX LD
#00 #00 DE,HL DE,#168F
Číslo řádku 0. Posuzuj druhý ukazatel. Použij řádek číslo 0.
Obvyklý vstupní bod je na LINE-NO. 1695
LINE-NO
LD AND JR LD INC LD RET
A,(HL) #C0 NZ,#1691,LINE-NO-A D,(HL) HL E,(HL)
Vyzvedni vyšší bajt a testuj. Skoč, je-li nevhodný. Vyzvedni vyšší bajt. Vyzvedni nižší bajt. Vrať se.
PODPROGRAM "REZERVUJ MÍSTO" Tento podprogram je většinou volán použitím RST #30,BC-SPACES. V tomto vstupním bodě se však předpokládá, že na zásobníku je uložen WORKSP a pod ním počet míst, která mají být rezervována. Podprogram vytváří prostor mezi pracovním prostorem a zásobníkem kalkulátoru. 169E
RESERVE
LD DEC
HL,(#5C63) (STKBOT) HL
CALL INC INC POP LD POP EX INC RET
#1655,MAKE-ROOM HL HL BC (#5C61),BC (WORKSP) BC DE,HL HL
Vyzvedni aktuální hodnotu STKBOT a zmenši ji k získání poslední lokace pracovního prostoru. Vytvoř BC míst. Ukazuj na druhý bajt nového prostoru. Vyzvedni starou hodnotu WORKSP a obnov ji. Obnov BC, tedy počet míst. Zaměň ukazatele. HL ukazuje na první z přemístěných bajtů. Návrat.
Poznámka: Lze také tvrdit, že po návratu z podprogramu ukazuje DE na první bajt "navíc" a HL na poslední bajt "navíc", když tyto bajty navíc byly přidány za původní místo (HL)+1.
78
Komentovaný výpis paměti ROM
PODPROGRAM SET-MIN Tento podprogram nastavuje editační oblast a následné oblasti na jejich minimální hodnoty, tedy je vlastně "čistí". 16B0
SET-MIN
LD LD LD INC LD INC LD
HL,(#5C59) (E-LINE) (HL),#0D (#5C5B),HL (K-CUR) HL (HL),#80 HL (#5C61),HL (WORKSP)
Vyzvedni E-LINE. Editační oblast bude obsahovat pouze znak CR následovaný koncovým bajtem. Další pozice bude začátek WORKSP a pokračujeme čištěním.
Vstup zde způsobí "vyčištění" pracovního prostoru a zásobníku kalkulátoru. 16BF
SET-WORK
LD LD
HL,(#5C61) (WORKSP) (#5C63),HL (STKBOT)
Vyzvedni WORKSP. Toto čistí pracovní prostor.
Vstup zde způsobí "vyčištění" pouze zásobníku kalkulátoru. 16C5
SET-STK
LD LD
HL,(#5C63) (STKBOT) (#5C65),HL (STKEND)
Vyzvedni STKBOT. Toto "čistí" zásobník.
Ve všech případech nastav permanentní hodnotu MEM. PUSH LD LD POP RET
HL HL,#5C92 (#5C68),HL (MEM) HL
Uschovej STKEND. Na tuto adresu nastav MEM. Obnov STKEND do HL. Vrať se.
ZNIČENÍ EDITAČNÍHO ŘÁDKU 16D4
REC-EDIT
LD JP
DE,(#5C59) (E-LINE) #19E5,RECLAIM-1
Vyzvedni E-LINE. Proveď "zničení".
PODPROGRAM "INDEXER" Tento podprogram se používá ve více případech a slouží k prohledávání tabulek. Vstupní bod je INDEXER. 16DB 16DC
INDEXER-1 INDEXER
INC LD AND RET CP INC JR SCF RET
HL A,(HL) A Z C HL NZ,#16DB,INDEXER-1
Postup na posouzení dalšího páru. Vyzvedni první pár a je-li to koncový znak #00, vrať se. Porovnej s dodaným znakem. Ukazatel na další položku. Skákej zpět, když nebyla nalezena správná položka. Při úspěšném nálezu je nastaven CY a provede se návrat.
PODPROGRAM PŘÍKAZU CLOSE# Tento příkaz dává uživateli možnost zavírat proudy. Pro proudy #00 až #03 jsou jejich data neustále systémem obnovována, a proto je nelze zavřít. 16E5
CLOSE
CALL #171E,STR-DATA
Jsou vyzvednuta existující data proudu.
Komentovaný výpis paměti ROM
79
16FC
CLOSE-1
CALL LD LD EX ADD JR LD ADD LD INC LD EX LD INC LD RET
#1701,CLOSE-2 BC,#0000 DE,#A3E2 DE,HL HL,DE C,#16FC,CLOSE-1 BC,#15D4 HL,BC C,(HL) HL B,(HL) DE,HL (HL),C HL (HL),B
Ověř kód kanálu tohoto proudu. Připrav si nuly pro vynulování proudu. Připrav si hodnoty pro identifikaci použití proudů #00 až #03. Testuj. Pro proudy #04 až #0F se nastaví CY a provede skok. Jinak nalezni správné hodnoty v tabulce iniciačních proudových dat. Vyzvedni iniciační data pro proudy #00 až #03. Nyní vlož data, a to buď obě nuly, nebo iniciační hodnoty a vrať se.
PODPROGRAM CLOSE-2 Kód kanálu připojeného k zavíranému proudu musí být "K", "S", nebo "P". 1701
CLOSE-2
PUSH LD ADD INC INC INC LD EX LD CALL LD LD ADD JP
HL HL,(#5C4F) (CHANS) HL,BC HL HL HL C,(HL) DE,HL HL,#1716 #16DC,INDEXER C,(HL) B,#00 HL,BC (HL)
Uschovej adresu proudových dat. Vyzvedni bázovou adresu oblasti kanálových informací a nalezni kanálová data pro proud, který je právě zavírán. Uschovej ukazatel. Báze tabulky uzavírání proudů. Nalezni správný doplněk. Převeď doplněk do BC, přičti ho k bázi a skoč do příslušného podprogramu.
TABULKA UZAVÍRÁNÍ PROUDŮ 1716 1718 171A
DEFB #4B #05 DEFB #53 #03 DEFB #50 #01
kanál 'K', doplněk #05, adresa 171C kanál 'S', doplněk #03, adresa 171C kanál 'P', doplněk #01, adresa 171C
Poznámka: Tato tabulka nemá koncový bajt.
PODPROGRAM ZAVŘI PROUD 171C
CLOSE-STR
POP RET
HL
Vyzvedni ukazatel oblasti kanálových dat a vrať se.
PODPROGRAM PROUDOVÁ DATA Podprogram vrací proudová data pro daný proud v registrovém páru DE. 171E
80
STR-DATA
CALL #1E94,STK-TO-A CP #10 JR C,#1727,STR-DATA1
Číslo proudu jde ze zásobníku kalkulátoru do registru A. Jestliže je číslo proudu větší než #0F, vyvolá se chybové hlášení. Komentovaný výpis paměti ROM
1725
REPORT-0
RST #08,ERROR-1 DEFB #17
Ohlaš: O-Invalid stream.
Zde se pokračuje s platnými čísly proudů. 1727
STR-DATA1
ADD RLCA LD LD LD ADD LD INC LD DEC RET
A,#03
Úprava na rozsah #03 až #12. Úprava na rozsah #06 až #24. Bázová adresa oblasti proudových dat. Kode proudu jde do BC. Výpočet adresy v oblasti proudových dat a přenesení nalezených dat do BC. Ukazatel zpět na první bajt dat. Návrat.
HL,#5C10 C,A B,#00 HL,BC C,(HL) HL B,(HL) HL
PODPROGRAM PŘÍKAZU OPEN# Tento příkaz poskytuje uživateli možnost otevírat proudy. Musí být udán kód kanálu, a to "K", "k", "S", "s", "P", nebo "p". Povšimněte si, že není snaha přidělit proudům #00 až #03 jejich iniciační hodnoty. 1736
1756
OPEN
OPEN-1
RST DEFB DEFB CALL LD OR JR EX LD ADD INC INC INC LD EX CP JR CP JR CP JR CALL LD INC LD RET
#28,FP-CALC #01,záměna #38, konec výpočtu #171E,STR-DATA A,B C Z,#1756,OPEN-1 DE,HL HL,(#5C4F) (CHANS) HL,BC HL HL HL A,(HL) DE,HL #4B Z,#1756,OPEN-1 #53 Z,#1756,OPEN-1 #50 NZ,#1725,REPORT-0 #175D,OPEN-2 (HL),E HL (HL),D
PODPROGRAM OPEN-2 Podprogram nalezne otevíranému proudu. 175D
OPEN-2
příslušné
Použij kalkulátor. Záměna čísla proudu a kód kanálu. Vyzvedni data pro proud. Jsou-li datové bajty nulové, znamená to že proud byl uzavřen a provede se skok. Uschovej DE. Vyzvedni bázovou adresu oblasti kanálových informací a nalezni kód kanálu, který je připojen k právě otevíranému proudu. Obnov DE. Získaný kód musí být "K", nebo "S", nebo "P", jinak skok na chybové hlášení. Vyzvedni příslušná data do DE. Vlož tyto data do dvou bajtů v oblasti proudových dat a vrať se.
proudové
PUSH HL CALL #2BF1,STK-FETCH
datové
bajty
pro
kanál,
který
je
připojen
k
právě
Uschovej HL. Vyzvedni parametry kódu kanálu.
Komentovaný výpis paměti ROM
81
1765
REPORT-F
LD OR JR RST DEFB
A,B C NZ,#1767,OPEN-3 #08,ERROR-1 #0E
Jestliže výraz má nulovou hodnotu, vyvolej chybové hlášení. Ohlaš: F-Invalid file name.
Pokračuj zde, pokud se nevyskytla žádná chyba. 1767
OPEN-3
PUSH LD AND LD LD CALL JR LD LD ADD POP JP
BC A,(DE) #DF C,A HL,#177A #16DC,INDEXER NC,#1765,REPORT-F C,(HL) B,#00 HL,BC BC (HL)
Je uschována délka výrazu. Vyzvedni první znak. Převeď malá písmena na velká a přenos kódu do C. Bázová adresa tabulky otevírání proudů. Vyhledej požadovaný doplněk. Skoč zpět, nebyl-li nalezen. Převeď doplněk do BC. HL nyní ukazuje na začátek příslušného podprogramu. Vyzvedni délku výrazu a skoč do příslušného podprogramu.
DEFB DEFB DEFB DEFB
#4B #06 #53 #08 #50 #0A #00
kanál 'K', doplněk #06, adresa 1781 kanál 'S', doplněk #08, adresa 1785 kanál 'P', doplněk #0A, adresa 1789 koncový znak.
LD JR
E,#01 #178B,OPEN-END
Datové bajty budou #01 a #00.
LD JR
E,#06 #178B,OPEN-END
Datové bajty budou #06 a #00.
LD DEC LD OR JR LD POP RET
E,#10 BC A,B C NZ,#1765,REPORT-F D,A HL
Datové bajty budou #10 a #00. Zkrať délku výrazu a pokud se nejednalo o jediný znak, skoč na chybové hlášení. Vynuluj D, vyzvedni HL a vrať se.
TABULKA OTVÍRÁNÍ PROUDŮ 177A 177C 177E 1780
PODPROGRAM OPEN-K 1781
OPEN-K
PODPROGRAM OPEN-S 1785
OPEN-S
PODPROGRAM OPEN-P 1789 178B
OPEN-P OPEN-END
PŘÍKAZY CAT, ERASE, FORMAT & MOVE V systému standardního SPECTRA vede použití těchto příkazů k vyvolání chybového hlášení. Podrobné informace lze najít v knize "Komentovaný výpis strojového kódu stínové ROM v Interface 1".
82
Komentovaný výpis paměti ROM
1793
CAT-ETC
JR
#1725,REPORT-0
Skok na chybové hlášení.
PŘÍKAZY LIST & LLIST Podprogramy v této části monitoru produkují výpis aktuálního programu. U každého řádku je posouzeno číslo, jsou expandovány tokens a umístěn aktuální programový kurzor. Vstupní bod AUTO-LIST je používán jak podprogramem hlavní prováděcí smyčky, tak editorem k vytvoření jedné stránky výpisu. Ukazatel zásobníku je uschován, což umožňuje opětné nastavení zásobníkové paměti po vykonání výpisu (viz. PO-SCR,#0C55). 1795
AUTO-LIST
LD LD CALL SET LD CALL RES SET LD LD AND SBC ADD JR
(#5C3F),SP (LIST-SP) (IY+2),#10 (TV-FLAG) #0DAF,CL-ALL 0,(IY+2) (TV-FLAG) B,(IY+49) (DF-SZ) #0E44,CL-LINE 0,(IY+2) (TV-FLAG) 0,(IY+48) (FLAGS2) HL,(#5C49) (E-PPC) DE,(#5C6C) (S-TOP) A HL,DE HL,DE C,#17E1,AUTO-L-2
Uschovej ukazatel zásobníku. Signál: automatický výpis na hlavní obrazovce. Vyčisti tuto část obrazovky. Přepni na editační oblast. Vyčisti také dolní část obrazovky. Přepni zpět z editační oblasti. Signál: obrazovka je čistá. Vyzvedni číslo aktuálního řádku a číslo "automatického" řádku. Jestliže číslo aktuálního řádku je menší než číslo "automatického" řádku, skoč dopředu.
Je třeba upravit "automatické" číslo tak, aby se aktuální řádek objevil na spodní části hlavní obrazovky. PUSH CALL LD EX SBC EX
DE #196E,LINE-ADDR DE,#02C0 DE,HL HL,DE (SP),HL
CALL #196E,LINE-ADDR POP BC
Uschovej "automatické" číslo. Najdi adresu začátku aktuálního řádku a vytvoř adresu zhruba jednu "obrazovku" před ním a výsledek uschovej na zásobníku a vyzvedni číslo "automatického" řádku. Adresa "automatického" řádku do HL. "Výsledek" jde do BC.
Vstup do smyčky. Při každém průchodu smyčkou je zvýšeno číslo "automatického" řádku dokud se aktuální řádek neobjeví ve výpisu. 17CE
AUTO-L-1
PUSH BC CALL #19B8,NEXT-ONE POP ADD JR EX LD INC LD DEC LD JR
BC HL,BC C,#17E4,AUTO-L-3 DE,HL D,(HL) HL E,(HL) HL (#5C6C),DE (S-TOP) #17CE,AUTO-L-1
Uschovej "výsledek". Najdi adresu řádku následujícího za "automatickým" řádkem (v DE). Vyzvedni výsledky, proveď výpočet a skoč dopředu, je-li hotovo. Převeď adresu dalšího řádku do HL a vyzvedni jeho číslo do DE. Nastav S-TOP a pokračuj s tímto dalším řádkem.
Nyní může dojít k automatickému výpisu.
Komentovaný výpis paměti ROM
83
17E1 17E4
AUTO-L-2 AUTO-L-3
17ED
AUTO-L-4
LD LD CALL JR EX CALL RES RET
(#5C6C),HL (S-TOP) HL,(#5C6C) (S-TOP) #196E,LINE-ADDR Z,#17ED,AUTO-L-4 DE,HL #1833,LIST-ALL 4,(IY+2) (TV-FLAG)
Pro případ, že E-PPC je menší než S-TOP. Vyzvedni číslo nejvyššího řádku a jeho adresu. Nebyla-li nalezena, použij adresu v DE. Výpis. Do tohoto místa se provede návrat, pokud nebylo zapotřebí rolování k vypsání aktuálního řádku.
VSTUPNÍ BOD LLIST Je nutné otevření kanálu pro tiskárnu. 17F5
LLIST
LD JR
A,#03 #17FB,LIST-1
Proud #03 a skok dopředu.
VSTUPNÍ BOD LIST Je nutné otevření kanálu pro obrazovku. 17F9 17FB
LIST LIST-1
1814
LIST-2
181A
LIST-3
181F 1822
LIST-4 LIST-5
1833
LIST-ALL
LD LD CALL CALL RST CALL JR RST CP JR CP JR RST CALL JR CALL JR CALL CALL CALL LD AND LD LD LD CALL LD
A,#02 (IY+2),#00 (TV-FLAG) #2530,SYNTAX-Z NZ,#1601,CHAN-OPEN #18,GET-CHAR #2070,STR-ALTER C,#181F,LIST-4 #18,GET-CHAR #3B Z,#1814,LIST-2 #2C NZ,#181A,LIST-3 #20,NEXT-CHAR #1C82,EXPT-1NUM #1822,LIST-5 #1CE6,USE-ZERO #1822,LIST-5 #1CDE,FETCH-NUM #1BEE,CHECK-END #1E99,FIND-INT2 A,B #3F H,A L,C (#5C49),HL (E-PPC) #196E,LINE-ADDR E,#01
Proud #02 a signál: Obyčejný výpis v hlavní části obrazovky. Při kontrole syntaxe kanál neotvírej. Vyzvedni aktuální znak do A a podívej se, je-li nutné měnit proud. Skoč, když proud nebyl změněn. Vyzvedni aktuální znak do A. Je-li to středník, skoč. Je-li to čárka, neskoč. Vyzvedni další znak a zvyš CH-ADD. Musí následovat číselný výraz (například LIST #5,20). Skoč s tímto dopředu. Použij nulu a skoč dopředu. Vyzvedni jakýkoliv řádek pokud nebyl zadán. V případě kontroly syntaxe, přejdi na další příkaz. Číslo řádku do BC. Vyšší bajt do A. Limitace vyššího bajtu na správnou velikost a převedení celého čísla řádku do HL. Nastav E-PPC. Najdi adresu tohoto nebo nejbližšího existujícího řádku. Signál: "před aktuálním řádkem".
Vstup do řídící smyčky pro výpis série řádků. 1835
84
LIST-ALL-1
CALL RST BIT JR LD SUB JR XOR
#1855,OUT-LINE #10,PRINT-A-1 4,(IY+2) (TV-FLAG) Z,#1835,LIST-ALL-1 A,(#5C6B) (DF-SZ) (IY+79) (S-POSN-hi) NZ,#1835,LIST-ALL-1 E
Vypiš celý basicový řádek. "Návrat vozíku". Pokud neprovádíš automatický výpis skoč zpět. Zbývá-li ještě místo v hlavní části obrazovky, rovněž skoč. Jestliže obrazovka je již plná a aktuální řádek Komentovaný výpis paměti ROM
RET PUSH PUSH LD CALL POP POP JR
Z HL DE HL,#5C6C #190F,LN-FETCH DE HL #1835,LIST-ALL-1
byl vytištěn, vrať se. Nicméně pokud aktuální řádek vytištěn nebyl, je potřeba zvýšit S-TOP a tisknout další řádek při použití rolování. Skok zpět do smyčky.
VYPSÁNÍ CELÉHO BASICOVÉHO ŘÁDKU Na vstupu ukazuje HL na začátek řádku, tedy na vyšší bajt čísla řádku. Než bude číslo vypsáno, zjistí se, zdali řádek stojí před a nebo za aktuálním řádkem. 1855
OUT-LINE
1865
OUT-LINE1
187D 1881
OUT-LINE2 OUT-LINE3
LD CALL LD JR LD
BC,(#5C49) (E-PPC) #1980,CP-LINES D,#3E Z,#1865,OUT-LINE1 DE,#0000
RL
E
LD LD CP POP RET PUSH CALL INC INC INC RES LD AND JR RST SET PUSH EX RES LD RES BIT JR SET
(IY+45),E (BREG) A,(HL) #40 BC NC BC #1A28,OUT-NUM-2 HL HL HL 0,(IY+1) (FLAGS) A,D A Z,#1881,OUT-LINE3 #10,PRINT-A-1 0,(IY+1) (FLAGS) DE DE,HL 2,(IY+48) (FLAGS2) HL,#5C3B 2,(HL) 5,(IY+55) (FLAGX) Z,#1894,OUT-LINE4 2,(HL)
Vyzvedni číslo aktuálního řádku a porovnávej. Kurzor aktuálního řádku do D. Skok dopředu, tiskneš aktuální řádek. Nuly do DE a E na #01, jestliže řádek stojí před aktuálním řádkem a E na #00,stojí-li na něm nebo za (CY flag přichází z CP-LINES). Uschovej značku. Vyzvedni vyšší bajt čísla řádku a je-li výpis u konce, zahoď návratovou adresu a proveď plný návrat. Vrať návratovou adresu a tiskni číslo řádku včetně úvodních mezer. Posuň ukazatel na první příkazový kód v řádku. Signál: Úvodní mezera povolena. Vyzvedni kód kurzoru a pokud jej není třeba tisknout, skoč dopředu. Tiskni kurzor. Signál: už žádná mezera. Úschova DE. Ukazatel do DE. Signál: ne v uvozovkách. Toto je FLAGS. Signál: tisk v modu K. Pokud nejsi v inputu, skoč dopředu. Signál: tisk v modu L.
Zde je vstup do smyčky, která tiskne všechny znaky až do konce basicového řádku a v případě potřeby přeskočí čísla v FP formě. 1894
OUT-LINE4
18A1
OUT-LINE5
LD AND SBC JR LD CALL CALL EX LD
HL,(#5C5F) (X-PTR) A HL,DE NZ,#18A1,OUT-LINE5 A,#3F #18C1,OUT-FLASH #18E1,OUT-CURS DE,HL A,(HL)
Vyzvedni ukazatel syntaktické chyby a v případě, že není potřeba tisknout chybový znak, skoč dopředu. Nyní tiskni chybový znak. Je to blikající otazník. Případný tisk kurzoru. Ukazatel do HL. Vyzvedni znak.
Komentovaný výpis paměti ROM
85
CALL INC CP JR EX CALL JR
#18B6,NUMBER HL #0D Z,#18B4,OUT-LINE6 DE,HL #1937,OUT-CHAR #1894,OUT-LINE4
Jedná-li se o FP identifikační bajt,nebude číslo vypsáno. Posuň ukazatel pro další průchod. Je-li aktuální znak "CR", skoč dopředu. Ukazatel do DE. Tiskni znak. Zpět do smyčky.
Řádek byl vytisknut. 18B4
OUT-LINE6
POP RET
PODPROGRAM "NUMBER" Jestliže registr reprezentaci čísla. 18B6
NUMBER
CP RET INC INC INC INC INC INC LD RET
DE
A
Obnovení DE a návrat.
obsahuje
příznak
#0E NZ HL HL HL HL HL HL A,(HL)
čísla
t.j.
#0E,
potom
bude
HL
ukazovat
za
vnitřní
Je to příznak čísla ? Pokud ne vrať se. Posuň ukazatel o šest bajtů dopředu. Tím se přeskočí příznak čísla a pět bajtů vnitřní reprezentace čísla v pohyblivé řádová čárce.
Před návratem vyzvedni kód za číslem.
PODPROGRAM PRO TISK BLIKAJÍCÍHO ZNAKU Tímto podprogramem jsou tisknuty kurzory - normální i chybový. 18C1
OUT-FLASH
EXX LD PUSH RES SET LD LD LD PUSH LD CALL POP LD POP LD EXX RET
HL,(#5C8F) (ATTR-T) HL 7,H 7,L (#5C8F),HL HL,#5C91 D,(HL) DE (HL),#00 #09F4,PRINT-OUT HL (IY+87),H (P-FLAG) HL (#5C8F),HL (ATTR-T)
Schovej registry. Ulož ATTR-T a MASK-T na zásobník. Poznač blikání jako aktivní. Tyto hodnoty dej jako aktivní do ATTR-T a MASK-T. Tahle adresa je P-FLAG. Ulož P-FLAG na zásobník. Nastav standardní hodnoty Vytiskni znak. Obnov hodnotu P-FLAG. Obnov hodnoty ATTR-T a MASK-T. Obnov registry. Návrat.
PODPROGRAM PRO TISK KURZORU Pokud je nastavena správná pozice pro tisk kurzoru, vytiskne 'C','E','G','K' nebo 'L'. V případě nesprávné pozice se provede návrat. 18E1
86
OUT-CURS
LD AND
HL,(#5C5B) (K-CUR) A
se
jeden
z
kurzorů
Vyzvedni adresu kurzoru a pokud není na správném Komentovaný výpis paměti ROM
18F3
OUT-C-1
1909
OUT-C-2
SBC RET LD RLC JR ADD JR LD RES LD BIT JR SET INC BIT JR LD PUSH CALL POP RET
HL,DE NZ A,(#5C41) (MODE) A Z,#18F3,OUT-C-1 A,#43 #1909,OUT-C-2 HL,#5C3B 3,(HL) A,#4B 2,(HL) Z,#1909,OUT-C-2 3,(HL) A 3,(IY+72) (FLAGS) Z,#1909,OUT-C-2 A,#43 DE #18C1,OUT-FLASH DE
místě, proveď návrat. Vyzvedni platnou hodnotu režimu a vynásob ji 2. Skoč dopředu pokud není režim EXTEND nebo GRAPHICS. Přičti ofset - získá se znak 'E' nebo 'G'. Jdi ho vytisknout. Tohle je adresa FLAGS. Režim 'K'. Vezmi znak "K". Skoč vytisknout "K", pokud je ovšem nastaven režim 'K'. Je tedy režim 'L' nebo 'C'. Uprav znak na "L". Pokud je nastaven režim 'C', vezmi jako kurzor znak "C". Ulož DE registr. Tiskni blikající znak kurzoru. Obnov DE. Vrať se.
PODPROGRAM VYZVEDNUTÍ ČÍSLA ŘÁDKU Na vstupu adresuje HL systémovou proměnnou S-TOP nebo E-PPC. Po návratu obsahuje S-TOP nebo E-PPC číslo následujícího řádku. 190F
LN-FETCH
LD INC LD PUSH EX INC CALL CALL POP
E,(HL) HL D,(HL) HL DE,HL HL #196E,LINE-ADDR #1695,LINE-NO HL
Vyzvedni číslo řádku z dané systémové proměnné a uschovej ukazatel. Nalezená hodnota jde do HL a je zvětšena. Je nalezena adresa tohoto, nebo následujícího řádku a jeho číslo. Obnovení ukazatele na systémovou proměnnou.
Tento vstupní bod je používán editorem. 191C
LN-STORE
BIT RET LD DEC LD RET
5,(IY+55) (FLAGX) NZ (HL),D HL (HL),E
Pokud jsi v modu INPUT, vrať se. Ulož číslo řádku na požadovanou systémovou proměnnou a vrať se.
TISK ZNAKŮ BASICOVÉHO ŘÁDKU Opakovaným voláním tohoto podprogramu je zajištěn tisk všech znaků a tokens v basicovém řádku. Vstupní bod OUT-SP-NO se používá pro tisk čísel řádků, která vyžadují úvodní mezery. 1925
OUT-SP-2
192A
OUT-SP-NO
LD AND RET JR XOR
A,E A M #1937,OUT-CHAR A
A obsahuje #20 pro mezeru a #FF pro "mezeru". Testuj tuto hodnotu a vrať se, nemá-li být mezera. Skoč na vytisknutí mezery. Vynuluj A.
HL obsahuje číslo řádku a BC hodnotu pro opakované odčítání. (BC=-1000, -100 nebo -10). Komentovaný výpis paměti ROM
87
192B
OUT-SP-1
ADD INC JR SBC DEC JR JP
HL,BC A C,#192B,OUT-SP-1 HL,BC A Z,#1925,OUT-SP-2 #15EF,OUT-CODE
Pokusné odečtení. Počítej každý pokus. Skoky zpět do vyčerpání. Vrať poslední odečet a nepočítej ho. Jestliže nebylo možné provést odečítání, skoč zpět na případný tisk mezery. Jinak vytiskni číslici.
Vstupní bod OUT-CHAR se používá pro tisk znaků, tokens a řídících znaků. 1937
OUT-CHAR
195A
OUT-CH-1
1968 196C
OUT-CH-2 OUT-CH-3
CALL JR CP JR RES CP JR CP JR BIT JR BIT JR JR CP JR PUSH LD XOR LD POP SET RST RET
#2D1B,NUMERIC NC,#196C,OUT-CH-3 #21 C,#196C,OUT-CH-3 2,(IY+1) (FLAGS) #CB Z,#196C,OUT-CH-3 #3A NZ,#195A,OUT-CH-1 5,(IY+55) (FLAGX) NZ,#1968,OUT-CH-2 2,(IY+48) (FLAGS2) Z,#196C,OUT-CH-3 #1968,OUT-CH-2 #22 NZ,#1968,OUT-CH-2 AF A,(#5C6A) (FLAGS2) #04 (#5C6A),A (FLAGS2) AF 2,(IY+1) (FLAGS) #10,PRINT-A-1
CY=0, jednalo-li se o číslici. Skoč dopředu a tiskni číslici. Také všechny řídící znaky a mezeru. Signál: tisk v modu K. Jedná-li se o token THEN, skoč dopředu. Pokud se nejedná o dvojtečku, skoč dopředu. Jsi-li v modu INPUT skoč dopředu a tiskni dvojtečku. Pokud dvojtečka není v uvozovkách, skoč dopředu (jedná se o oddělovač příkazů). Skoč na tisk dvojtečky, která byla v uvozovkách. Akceptuj všechny znaky, kromě " (uvozovka). Uschovej kód znaku. Otoč bit 2 systémové proměnné FLAGS2. Obnov kód znaku. Signál: další znak bude vytisknut v modu L. Vlastní tisk znaku. Vrať se.
Poznámka: Je to právě toto pořadí testů, které určuje, v jakém modu má být vytištěn následující znak. Také si povšimněte, že program neobsahuje dvojtečky v řádcích REM.
ADRESA ŘÁDKU Pro dané číslo řádku v HL vrací tento podprogram počáteční adresu tohoto nebo následujícího řádku v HL a v DE adresu předchozího řádku. Pokud hledané číslo řádku existuje bude Z flag=1, avšak při nahrazování číslem následujícího řádku bude Z flag=0. 196E
LINE-ADDR
PUSH LD LD LD
HL HL,(#5C53) (PROG) D,H E,L
Uschovej číslo řádku. Vyzvedni hodnotu PROG a převeď ji do DE.
Nyní vstup do smyčky, která testuje čísla všech programových řádků, dokud nenalezne shodné nebo vyšší číslo. 1974
88
LINE-AD-1
POP CALL RET PUSH CALL
BC #1980,CP-LINES NC BC #19B8,NEXT-ONE
Dané číslo řádku. Porovnej číslo daného řádku s číslem adresovaného řádku a vrať se když CY=0. Jinak adresuj číslo dalšího řádku.
Komentovaný výpis paměti ROM
EX JR
DE,HL #1974,LINE-AD-1
Zaměň ukazatele a skoč zpět na posouzení dalšího programového řádku.
PODPROGRAM POROVNÁNÍ ŘÁDKU Číslo řádku v BC se porovná s číslem řádku jehož adresa je v HL. 1980
CP-LINES
LD CP RET INC LD DEC CP RET
A,(HL) B NZ HL A,(HL) HL C
Vyzvedni vyšší bajt adresovaného čísla řádku a porovnej. Vrať se pokud se neshodují. Dále porovnej nižší bajt
a vrať se s CY=1, jestliže nebylo dosaženo hledané číslo.
NALEZENÍ JEDNOTLIVÝCH PŘÍKAZŮ Tento podprogram plní dvě rozličné funkce. a) Může být použit k nalezení "D-tého" příkazu v basicovém řádku, kdy v HL bude adresa před začátkem tohoto příkazu a Z=1. b) Vyhledá adresu příkazu, jehož token je v registru E. (Pokud takový příkaz existuje). 1988
198B
EACH-STMT
INC INC INC LD LD
HL HL HL (#5C5D),HL (CH-ADD) C,#00
Nevyužito.
Nastav CH-ADD na aktuální bajt. Nastav signál: " uvozovky pryč ".
Vstup do smyčky, která zkoumá každý příkaz v řádku. 1990
EACH-S-1
DEC RET RST CP JR AND RET
D Z #20,NEXT-CHAR E NZ,#199A,EACH-S-3 A
Dekrementuj D a vrať se, jestliže byl nalezen požadovaný příkaz. Vyzvedni kód dalšího znaku a pokud neodpovídá danému token, skoč dopředu. V případě shody nuluj CY a vrať se též s nulovým Z flag.
Tato smyčka posuzuje jednotlivé znaky v řádku, aby nalezla kde příkaz končí. 1998
EACH-S-2
199A
EACH-S-3
19A5
EACH-S-4
19AD
EACH-S-5
19B1
EACH-S-6
INC LD CALL LD CP JR DEC CP JR CP JR BIT JR CP JR
HL A,(HL) #18B6,NUMBER (#5C5D),HL (CH-ADD) #22 NZ,#19A5,EACH-S-4 C #3A Z,#19AD,EACH-S-5 #CB NZ,#19B1,EACH-S-6 0,C Z,#1990,EACH-S-1 #0D NZ,#1998,EACH-S-2
Posuň ukazatel a vyzvedni další kód. Překračuj všechna čísla a obnovuj CH-ADD. Jestliže znak není uvozovka, skoč dopředu. Nastav signál: "uvozovky ano". Jestliže znak je dvojtečka, skoč dopředu. Jestliže znak není token pro THEN, skoč dopředu. Přečti signál "uvozovky" a skoč na konci každého příkazu. (A to i po THEN ). Pokud se nenacházíš na konci řádku, skoč zpět.
Komentovaný výpis paměti ROM
89
DEC SCF RET
D
Zmenši čítač příkazů a nastav CY=1. Vrať se.
PODPROGRAM NEXT-ONE Tento podprogram umí nalézt další řádek v programu, nebo další proměnnou v oblasti VARS. 19B8
NEXT-ONE
19C7
NEXT-O-1
19CE
NEXT-O-2
PUSH LD CP JR BIT JR ADD JP CCF LD JR LD RLA INC LD JR JR INC INC LD INC LD INC
HL A,(HL) #40 C,#19D5,NEXT-O-3 5,A Z,#19D6,NEXT-O-4 A,A M,#19C7,NEXT-O-1 BC,#0005 NC,#19CE,NEXT-O-2 C,#12 HL A,(HL) NC,#19CE,NEXT-O-2 #19DB,NEXT-O-5 HL HL C,(HL) HL B,(HL) HL
Uschovej adresu aktuálního řádku nebo proměnné. Vyzvedni první bajt. Jestliže hledáš řádek, skoč dopředu. Jedná-li se o řetězec nebo pole, skoč dopředu. Jedná-li se o jednopísmennou číselnou proměnnou a proměnnou FOR-NEXT, skoč dopředu. Pouze číselné proměnné s dlouhými názvy. Číselná proměnná zabírá pět míst, ale řídící proměnná FOR-NEXT potřebuje 18 míst. CY bude 0 pro proměnné s dlouhými názvy, dokud nebude nalezen poslední znak. Zvyš ukazatel a vyzvedni další znak. Skok zpět, pokud nejsi na konci. Skok dopředu (BC=#0005 nebo #0012). Krok za nižší bajt čísla řádku. Nyní ukazuj na nižší bajt délky. Vyzvedni délku řádku do BC. Ukazuj na obsah Basicového řádku/proměnné.
19D5 19D6
NEXT-O-3 NEXT-O-4
19DB
"Další" adresa je nalezena ve všech případech. NEXT-O-5 ADD HL,BC Ukazuj na první bajt dalšího řádku nebo proměnné. POP DE Vyzvedni adresu předchozího a pokračuj.
PODPROGRAM DIFFERENCE V registru BC se vrací délka mezi dvěma ukazateli. Ukazatele se vrací zaměněné. 19DD
DIFFER
AND SBC LD LD ADD EX RET
A HL,DE B,H C,L HL,DE DE,HL
Příprava pravdivého odečítání. Nalezenou délku předej do BC a obnov ukazatel. Zaměň ukazatele a vrať se.
PODPROGRAM RECLAIMING Vstupní bod RECLAIM-1 se používá v případě, kdy DE ukazuje na první místo, které má být "zrušeno" a HL ukazuje na první místo, které má být ponecháno. Vstupní bod RECLAIM-2 se používá v případě, kdy HL ukazuje na první místo, které má být "zrušeno" a v BC je počet bajtů, které mají být "zrušeny". 19E5 19E8
90
RECLAIM-1 RECLAIM-2
CALL PUSH LD CPL LD
#19DD,DIFFER BC A,B B,A
K získání potřebných hodnot použij DIFFERENCE. Uschovej počet bajtů. Všechny systémové ukazatele nad touto oblastí musí být sníženy o "BC", Komentovaný výpis paměti ROM
LD CPL LD INC CALL EX POP ADD PUSH LDIR POP RET
A,C C,A BC #1664,POINTERS DE,HL HL HL,DE DE HL
a proto je jeho obsah komplementován. Vrať adresu prvního místa do DE a vypočti adresu prvního místa, které má být ponecháno. Uschovej adresu prvního místa po dobu reklamace vyzvedni ji do HL a vrať se.
PODPROGRAM E-LINE-NO Podprogram vyzvedne číslo řádku v editační oblasti. Pokud řádek nemá číslo (přímý příkaz), bude se považovat za řádek 0. Ve všech případech se číslo řádku vrací v BC. 19FB
E-LINE-NO
1A15
E-L-1
LD DEC LD RST LD LD CALL CALL JR LD ADD JP JP
HL,(#5C59) (E-LINE) HL (#5C5D),HL (CH-ADD) #20,NEXT-CHAR HL,#5C92 (#5C65),HL (STKEND) #2D3B,INT-TO-FP #2DA2,FP-TO-BC C,#1A15,E-L-1 HL,#D8F0 HL,BC C,#1C8A,REPORT-C #16C5,SET-STK
Vyzvedni ukazatel editovaného řádku. Nastav ukazatel CH-ADD tak, aby ukazoval před číslo. Vyzvedni první kód. Předtím ale inicializuj zásobník kalkulátoru. Nyní přečti číslice čísla řádky. Z=0 pokud číslo není. Převeď číslo řádky do registru BC. Skoč na chybu pokud je číslo řádky větší než 65535. Jinak porovnej s číslem 10000 tj. přičti -10000. Chybné číslo řádky (větší než 9999). Obnovit kalkulátorový zásobník.
PODPROGRAM PRO TISK HLÁŠENÍ A ČÍSLA ŘÁDKU Vstupní bod OUT-NUM-1 vyžaduje číslo v registru BC. Pokud bude hodnota čísla větší než 9999, nebude správně vytištěno. Vstupní bod OUT-NUM-2 vyžaduje číslo v paměti, adresované registrem HL. I v tomto případě nelze tisknout číslo větší než 9999. 1A1B
1A28
OUT-NUM-1
OUT-NUM-2
PUSH PUSH XOR BIT JR LD LD LD JR
DE HL A 7,B NZ,#1A42,OUT-NUM-4 H,B L,C E,#FF #1A30,OUT-NUM-3
PUSH LD INC LD PUSH EX LD
DE D,(HL) HL E,(HL) HL DE,HL E,#20
Ulož registry. Vynuluj registr A. Pokud je číslo záporné tiskni raději nulu. Přesuň číslo do HL. Poznač že zatím nebudou úvodní mezery. Jdi vytisknout číslo. Ulož DE. Vyzvedni číslo do DE.
Uschovej ukazatel. Číslo do HL. Poznač že se bude tisknout úvodní mezera.
Komentovaný výpis paměti ROM
91
Nyní se vytiskne celé číslo obsažené v registru HL. 1A30
OUT-NUM-3
LD CALL LD CALL LD CALL LD
1A42
OUT-NUM-4
CALL #15EF,OUT-CODE POP HL POP DE RET
92
BC,#FC18 #192A,OUT-SP-NO BC,#FF9C #192A,OUT-SP-NO C,#F6 #192A,OUT-SP-NO A,L
Tohle je -1000. Tiskni první číslici. Tohle je -100. Tiskni druhou číslici. Tohle je -10. Tiskni třetí číslici. Vezmi zbytek do A. Tiskni číslici. Obnov registry HL a DE. Návrat.
Komentovaný výpis paměti ROM
INTERPRETACE PŘÍKAZŮ V BASICOVÉM ŘÁDKU
SYNTAKTICKÉ TABULKY a) TABULKA DOPLŇKŮ: V této tab.je doplňková hodnota pro každý z 50 Basic. příkazů.
1A48 1A49 1A4A 1A4B 1A4C 1A4D 1A4E 1A4F 1A50 1A51 1A52 1A53 1A54 1A55 1A56 1A57 1A58 1A59 1A5A 1A5B 1A5C 1A5D 1A5E 1A5F 1A60
token
příkaz
adr.
DEFB #B1 DEFB #CB DEFB #BC DEFB #BF DEFB #C4 DEFB #AF DEFB #B4 DEFB #93 DEFB #91 DEFB #92 DEFB #95 DEFB #98 DEFB #98 DEFB #98 DEFB #98 DEFB #98 DEFB #98 DEFB #98 DEFB #7F DEFB #81 DEFB #2E DEFB #6C DEFB #6E DEFB #70 DEFB #48
DEF FN CAT FORMAT MOVE ERASE OPEN# CLOSE# MERGE VERIFY BEEP CIRCLE INK PAPER FLASH BRIGHT INVERSE OVER OUT LPRINT LLIST STOP READ DATA RESTORE NEW
1AF9 1B14 1B06 1B0A 1B10 1AFC 1B02 1AE2 1AE1 1AE3 1AE7 1AEB 1AEC 1AED 1AEE 1AEF 1AF0 1AF1 1AD9 1ADC 1A8A 1AC9 1ACC 1ACF 1AA8
1A61 1A62 1A63 1A64 1A65 1A66 1A67 1A68 1A69 1A6A 1A6B 1A6C 1A6D 1A6E 1A6F 1A70 1A71 1A72 1A73 1A74 1A75 1A76 1A77 1A78 1A79
token
příkaz
adr.
DEFB #94 DEFB #56 DEFB #3F DEFB #41 DEFB #2B DEFB #17 DEFB #1F DEFB #37 DEFB #77 DEFB #44 DEFB #0F DEFB #59 DEFB #2B DEFB #43 DEFB #2D DEFB #51 DEFB #3A DEFB #6D DEFB #42 DEFB #0D DEFB #49 DEFB #5C DEFB #44 DEFB #15 DEFB #5D
BORDER CONTINUE DIM REM FOR GO TO GO SUB INPUT LOAD LIST LET PAUSE NEXT POKE PRINT PLOT RUN SAVE RANDOMIZE IF CLS DRAW CLEAR RETURN COPY
1AF5 1AB8 1AA2 1AA5 1A90 1A7D 1A86 1A9F 1AE0 1AAE 1A7A 1AC5 1A98 1AB1 1A9C 1AC1 1AAB 1ADF 1AB5 1A81 1ABE 1AD2 1ABB 1A8D 1AD6
b) TABULKA PARAMETRŮ V této je až 8 položek pro každý z 50 Basic. příkazů. Tyto položky obsahují údaje o třídě příkazu, o požadovaných separátorech a je-li to potřeba, též adresy příkazových podprogramů. 1A7A
P-LET
1A7D
P-GO-TO
1A81
P-IF
1A86
P-GO-SUB
1A8A
P-STOP
1A8D
P-RETURN
DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB
#01 #3D #02 #06 #00 #67,#1E #06 #CB #05 #F0,#1C #06 #00 #ED,#1E #00 #EE,#1C #00 #23,#1F
CLASS-01 rovnítko '=' CLASS-02 CLASS-06 CLASS-00 GO-TO,1E67 CLASS-06 THEN CLASS-05 IF,1CF0 CLASS-06 CLASS-00 GO-SUB,1EED CLASS-00 STOP,1CEE CLASS-00 RETURN,1F23
Komentovaný výpis paměti ROM
93
1A90
P-FOR
1A98
P-NEXT
1A9C
P-PRINT
1A9F
P-INPUT
1AA2
P-DIM
1AA5
P-REM
1AA8
P-NEW
1AAB
P-RUN
1AAE
P-LIST
1AB1
P-POKE
1AB5
P-RANDOM
1AB8
P-CONT
1ABB
P-CLEAR
1ABE
P-CLS
1AC1
P-PLOT
1AC5
P-PAUSE
1AC9
P-READ
1ACC
P-DATA
1ACF
P-RESTORE
1AD2
P-DRAW
1AD6
P-COPY
1AD9
P-LPRINT
1ADC
P-LLIST
1ADF 1AE0
P-SAVE P-LOAD
94
DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB
#04 #3D #06 #CC #06 #05 #03,#1D #04 #00 #AB,#1D #05 #CD,#1F #05 #89,#20 #05 #02,#2C #05 #B2,#1B #00 #B7,#11 #03 #A1,#1E #05 #F9,#17 #08 #00 #80,#1E #03 #4F,#1E #00 #5F,#1E #03 #AC,#1E #00 #6B,#0D #09 #00 #DC,#22 #06 #00 #3A,#1F #05 #ED,#1D #05 #27,#1E #03 #42,#1E #09 #05 #82,#23 #00 #AC,#0E #05 #C9,#1F #05 #F5,#17 #0B #0B
CLASS-04 rovnítko '=' CLASS-06 TO CLASS-06 CLASS-05 FOR,1D03 CLASS-04 CLASS-00 NEXT,1DAB CLASS-05 PRINT,1FCD CLASS-05 INPUT,2089 CLASS-05 DIM,2C02 CLASS-05 REM,1BB2 CLASS-00 NEW,11B7 CLASS-03 RUN,1EA1 CLASS-05 LIST,17F9 CLASS-08 CLASS-00 POKE,1E80 CLASS-03 RANDOMIZE,1E4F CLASS-00 CONTINUE,1E5F CLASS-03 CLEAR,1EAC CLASS-00 CLS,0D6B CLASS-09 CLASS-00 PLOT,22DC CLASS-06 CLASS-00 PAUSE,1F3A CLASS-05 READ,1DED CLASS-05 DATA,1E27 CLASS-03 RESTORE,1E42 CLASS-09 CLASS-05 DRAW,2382 CLASS-00 COPY,0EAC CLASS-05 LPRINT,1FC9 CLASS-05 LLIST,17F5 CLASS-0B CLASS-0B Komentovaný výpis paměti ROM
1AE1 1AE2 1AE3
P-VERIFY P-MERGE P-BEEP
1AE7
P-CIRCLE
1AEB 1AEC 1AED 1AEE 1AEF 1AF0 1AF1
P-INK P-PAPER P-FLASH P-BRIGHT P-INVERSE P-OVER P-OUT
1AF5
P-BORDER
1AF9
P-DEF-FN
1AFC
P-OPEN
1B02
P-CLOSE
1B06
P-FORMAT
1B0A
P-MOVE
1B10
P-ERASE
1B14
P-CAT
DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB
#0B #0B #08 #00 #F8,#03 #09 #05 #20,#23 #07 #07 #07 #07 #07 #07 #08 #00 #7A,#1E #06 #00 #94,#22 #05 #60,#1F #06 #2C #0A #00 #36,#17 #06 #00 #E5,#16 #0A #00 #93,#17 #0A #2C #0A #00 #93,#17 #0A #00 #93,#17 #00 #93,#17
CLASS-0B CLASS-0B CLASS-08 CLASS-00 BEEP,03F8 CLASS-09 CLASS-05 CIRCLE,2320 CLASS-07 CLASS-07 CLASS-07 CLASS-07 CLASS-07 CLASS-07 CLASS-08 CLASS-00 OUT,1E7A CLASS-06 CLASS-00 BORDER,2294 CLASS-05 DEF-FN,1F60 CLASS-06 čárka ',' CLASS-0A CLASS-00 OPEN,1736 CLASS-06 CLASS-00 CLOSE,16E5 CLASS-0A CLASS-00 CAT,atd,1793 CLASS-0A čárka ',' CLASS-0A CLASS-00 CAT,atd,1793 CLASS-0A CLASS-00 CAT,atd,1793 CLASS-00 CAT atd.,1793
Poznámka: Požadavky různých tříd jsou tyto: CLASS-00 01 02 03 04 05 06 07 08 09 0A 0B
bez dalších operandů použito pro LET, vyžaduje se proměnná " , musí následovat výraz numerický či řetězcový může následovat numerický výraz, použije se nula pokud není musí následovat jednoznaková proměnná může následovat soubor položek musí následovat numerický výraz pro obsluhu barevných položek musí následovat 2 numerické výrazy, oddělené čárkou jako 08, ale mohou předcházet barevné položky musí následovat řetězcový výraz obsluha kazetového MGF Komentovaný výpis paměti ROM
95
HLAVNÍ "VĚTNÝ ROZBOR" V BASICOVÉM INTERPRETU Do tohoto podprogramu se vstupuje v bodě LINE-SCAN při kontrole syntaxe a v bodě LINE-RUN, jestliže má být proveden Basicový program, nebo jeden, či více příkazů. Každý příkaz je posuzován postupně a systémová proměnná CH-ADD je použita jako ukazatel na jednotlivé kódy příkazů tak, jak se vyskytují v programové, či editační zóně.
1B17
LINE-SCAN
RES CALL XOR LD DEC LD JR
7,(IY+1) (FLAGS) #19FB,E-LINE-NO A (#5C47),A (SUBPPC) A (#5C3A),A (ERR-NR) #1B29,STMT-L-1
Signál: kontrola syntaxe. CH-ADD nastaven na první znak za jakýmkoliv číslem řádku SUBPPC nastav na hodnotu #00 a ERR-NR na #FF. Skoč na posouzení prvního příkazu v řádce.
PŘÍKAZOVÁ SMYČKA Jsou posouzeny všechny příkazy, dokud není dosaženo konce řádky. 1B28 1B29
STMT-LOOP STMT-L-1
RST CALL INC JP RST LD CP JR CP JR
#20,NEXT-CHAR #16BF,SET-WORK (IY+13) (SUBPPC) M,#1C8A,REPORT-C #18,GET-CHAR B,#00 #0D Z,#1BB3,LINE-END #3A Z,#1B28,STMT-LOOP
Posun CH-ADD po řádce. Pracovní prostor je vyčištěn. Každým průchodem smyčkou je zvětšena proměnná SUBPPC, ale v jednom řádku je povoleno pouze 127 příkazů. Vyzvedni znak a vyčisti registr B. Je to CR? (ENTER). ANO: skoč. Je to ":"? ANO: vrať se do smyčky.
Příkaz je identifikován, takže nyní se posoudí jeho 1.část. LD PUSH LD RST LD SUB JP LD LD ADD LD ADD JR
HL,#1B76 HL C,A #20,NEXT-CHAR A,C #CE C,#1C8A,REPORT-C C,A HL,#1A48 HL,BC C,(HL) HL,BC #1B55,GET-PARAM
Návratová adresa STMT-RET je uložena na TOP. Ulož si přechodně příkaz do registru C, zatímco opět posuneš CH-ADD redukuj kód příkazu. Konst. #CE,tím dosáhneš rozsah od 0 do #31 pro 50 příkazů Chyba, není-li kód příkazem. Kód příkazu do registrového páru BC. Bázová adresa tabulky syntaxe. Požadovaný doplněk je předán do registru C a použit k výpočtu báz. adr. pro položky v tab. parametrů a s touto adresou skoč do prohlížecí smyčky.
Všechny programy pro posouzení třídy daného příkazu jsou postupně vykonány a všechny požadované separátory jsou též posouzeny. 1B52 1B55
96
SCAN-LOOP GET-PARAM
LD LD INC LD LD PUSH LD
HL,(#5C74) (T-ADDR) A,(HL) HL (#5C74),HL (T-ADDR) BC,#1B52 BC C,A
Přechodný ukazatel na položku v tabulce parametrů. Vyzvedni postupně všechny položky. Posuň ukazatel na položku pro další průchod. Ulož na TOP návratovou adresu SCAN-LOOP. Okopíruj položku do C.
Komentovaný výpis paměti ROM
CP JR LD LD ADD LD ADD PUSH RST DEC RET
#20 NC,#1B6F,SEPARATOR HL,#1C01 B,#00 HL,BC C,(HL) HL,BC HL #18,GET-CHAR B
Je položka separátor? ANO:skoč. Bázová adresa tabulky příkazových tříd. Vynuluj registr B a hledej v této tabulce a doplněk do registru C. Vypočítej startovní adresu požadovaného podprogramu a ulož ji na TOP. Před nepřímým skok. do podpr. pro zjišťování tříd příkazů předej příkazový kód do reg.A a nastav reg.B na #FF.
PODPROGRAM SEPARÁTOR Hlášení "Nonsense in BASIC" je vypsáno, jestliže požadovaný separátor není přítomen. povšimněte si, že při kontrole syntaxe není toto hlášení tištěno, pouze se objeví blikající "?". 1B6F
SEPARATOR
RST CP JP RST RET
#18,GET-CHAR C NZ,#1C8A,REPORT-C #20,NEXT-CHAR
Ale
Aktuální znak je vyzvednut a porovnán s parametrem v tabulce. Chyba při neshodě. Postup na správný znak a vrať se.
PODPROGRAM STMT-RET Po správné interpretaci příkazu se program navrací na toto místo. 1B76
STMT-RET
1B7B
REPORT-L
CALL JR RST DEFB
#1F54,BREAK-KEY C,#1B7D,STMT-R-1 #08,ERROR-1 #14
Po každém příkazu je otestována klávesa BREAK. NE: skok. ANO: ohlaš L-BREAK into program.
Zde se pokračuje, nebyl-li BREAK stisknut. 1B7D
STMT-R-1
BIT JR LD BIT JR
7,(IY+10) (NSPPC) NZ,#1BF4,STMT-NEXT HL,(#5C42) (NEWPPC) 7,H Z,#1B9E,LINE-NEW
Není-li potřeba žádný "skok", pokračuj na NEXT. Číslo nového řádku a pokud neobsluhuješ další příkaz v editační oblasti, skoč dopředu.
VSTUPNÍ BOD LINE-RUN Tento vstupní bod je používán, kdykoliv má být řádek v editační oblasti spuštěn příkazem RUN. V tomto případě bude nastaven bit 7 ve FLAGS jako signál, že se provádí RUN (a ne SYNTAX). Tento vstupní bod je též používán při kontrole řádku v editační oblasti, který obsahuje víc než jeden příkaz (bit 7 FLAGS=0). 1B8A
LINE-RUN
LD LD LD DEC LD DEC LD JR
HL,#FFFE (#5C45),HL (PPC) HL,(#5C61) (WORKSP) HL DE,(#5C59) (E-LINE) DE A,(#5C44) (NSPPC) #1BD1,NEXT-LINE
Řádek v editační oblasti je posuzován jako řádek "-2". HL=koncový byte v editační oblasti a DE na byte před editační oblastí. Vezmi číslo dalšího příkazu, který má být zpracován, než skočíš dopředu.
Komentovaný výpis paměti ROM
97
PODPROGRAM LINE NEW V programu byl proveden skok a počáteční adresa nového řádku bude nalezena. 1B9E
LINE-NEW
1BB0
REPORT-0
CALL LD JR AND JR LD LD AND LD JR RST DEFB
#196E,LINE-ADDR A,(#5C44) (NSPPC) Z,#1BBF,LINE-USE A NZ,#1BEC,REPORT-N B,A A,(HL) #C0 A,B Z,#1BBF,LINE-USE #08,ERROR-1 #FF
Je nalezena adresa následujícího řádku. Vezmi číslo příkazu. Skoč, byl-li požadovaný řádek nalezen, jinak zkontroluj platnost čísla příkazu, musí to být 0. Zkontroluj není-li "následující" řádek za skutečným "koncem" programu. Skoč s platnými adresami. Jinak ohlaš: 0-OK
Poznámka: toto není chyba v normálním smyslu chápání, ale skok na konec programu.
PODPROGRAM PŘÍKAZU REM Návratová adresa do STMT-RET je odložena, čímž je program donucen ignorovat konec řádku. 1BB2
REM
POP
BC
Odhoď adresu STMT-RET.
PODPROGRAM "KONEC ŘÁDKU" Při kontrole syntaxe se provede jednoduchý návrat, ale pokud je program v běhu, musí být zkontrolována adresa na NXTLIN než bude použita. 1BB3
LINE-END
CALL RET LD LD AND RET XOR
#2530,SYNTAX-Z Z HL,(#5C55) (NXTLIN) A,#C0 (HL) NZ A
Při kontrole syntaxe se vrať, jinak vyzvedni adresu na NXTLIN a je-li tato za koncem programu vrať se též, čímž je příkaz RUN vykonán. Signál: příkaz 0, než postoupíš dále.
PODPROGRAM POUŽITÍ ŘÁDKU Tato krátký podprogram má 3 funkce: a) změní příkaz "0" na "1" b) najde číslo nového řádku a vloží do systémové proměnné PPC c) vytvoří adresu začátku následujícího řádku 1BBF
98
LINE-USE
CP ADC LD INC LD LD INC LD INC LD EX
#01 A,#00 D,(HL) HL E,(HL (#5C45),DE (PPC) HL E,(HL) HL D,(HL) DE,HL
Z příkazu "0" se stává příkaz "1". Číslo aktuálního řádku se vyzvedne a předá do PPC. Nyní je nalezena délka řádku.
Záměna hodnot a
Komentovaný výpis paměti ROM
ADD INC
HL,DE HL
vytvoření adresy následujícího řádku v HL přičemž pozice před 1.znakem následujícího řádku je v DE.
PODPROGRAM DALŠÍ ŘÁDEK Na vstupu ukazuje HL za poslední místo "dalšího" řádku a DE ukazuje na místo před prvním bajtem tohoto řádku. Týká se řádků, které jsou v programové oblasti a též řádků v editační oblasti, kdy "další řádek" je ten samý řádek a zbývají zde ještě příkazy, které je nutno přeložit. 1BD1
NEXT-LINE
1BEC
REPORT-N
LD EX LD LD LD LD DEC LD JP INC CALL JR RST DEFB
(#5C55),HL (NXTLIN) DE,HL (#5C5D),HL (CH-ADD) D,A E,#00 (IY+10),#FF (NSPPC) D (IY+13),D (SUBPPC) Z,#1B28,STMT-LOOP D #198B,EACH-STMT Z,#1BF4,STMT-NEXT #08,ERROR-1 #16
Nastav NXTLIN pro další použití. CH-ADD ukazuje jako obvykle na pozici před znakem, který má být posouzen. Číslo příkazu je vyzvednuto. Nulován E při použití EACH-STMT. Signál: žádný skok. Číslo příkazu - 1 jde do SUBPPC. Nyní může být posouzen 1.příkaz. Avšak pro další příkaz musí být nalezena počáteční adresa. Existuje-li - skoč. Ohlaš: N-Statement lost
PODPROGRAM "KONTROLA KONCE" Toto je velmi důležitý podprogram, který je volán z mnoha míst monitorového programu při kontrole syntaxe, nebo editačního řádku. Úkolem tohoto podprogramu je vypsat chybové hlášení, jestliže nebyl nalezen konec příkazu a přesunout se na další příkaz, byla-li syntaxe O.K. 1BEE
CHECK-END
CALL RET POP POP
#2530,SYNTAX-Z NZ BC BC
Nepokračuj, dokud nezkontroluješ syntaxi. Odhoď adresy SCAN-LOOP a STMT-RET před pokračováním do STMT-NEXT.
PODPROGRAM "DALŠÍ PŘÍKAZ" Jestliže aktuální znak je CR (ENTER), pak "další příkaz" je na "dalším řádku". Je-li to ":", je další příkaz na tom samém, ale je-li zde jakýkoliv jiný znak, jedná se o syntaktickou chybu. 1BF4
STMT-NEXT
RST CP JR CP JP JP
#18,GET-CHAR #0D Z,#1BB3,LINE-END #3A Z,#1B28,STMT-LOOP #1C8A,REPORT-C
Vyzvedni aktuální znak a jedná-li se o ENTER, jdi na "další řádek". Je-li to ":" jdi na "další příkaz", jinak je syntaktická chyba.
TABULKY TŘÍD PŘÍKAZŮ 1C01 1C02 1C03 1C04 1C05 1C06
0F 1D 4B 09 67 0B
CLASS-00-1C10 CLASS-01-1C1F CLASS-02-1C4E CLASS-03-1C0D CLASS-04-1C6C CLASS-05-1C11
1C07 1C08 1C09 1C0A 1C0B 1C0C
7B 8E 71 B4 81 CF
Komentovaný výpis paměti ROM
CLASS-06-1C82 CLASS-07-1C96 CLASS-08-1C7A CLASS-09-1CBE CLASS-0A-1C8C CLASS-0B-1CDB
99
PŘÍKAZOVÉ TŘÍDY 00, 03 A 05 Příkazy, které mají třídu 03 mohou, ale nemusí být následovány číslem (např. RUN a RUN 200) 1C0D
CLASS-03
CALL #1CDE,FETCH-NUM
Číslo je zjištěno, ale neexistuje-li použije se 0.
Příkazy třídy 00 nesmí být následovány operandy (COPY ap.) 1C10
CLASS-00
CP
A
Nastav Z flag pro pozdější využití.
Příkazy třídy 05 mohou být následovány parametry (PRINT ap.) 1C11
CLASS-05
POP BC CALL Z,#1BEE,CHECK-END
Ve všech případech odhoď adresu SCAN-LOOP.
U přík.třídy 00 a 03 se po kontrole syntaxe pokračuje v posouzení dalšího příkazu. EX
DE,HL
Do DE uschovej ukazatel řádku.
PODPROGRAM "SKOK C-R" Po posouzení všech tříd příkazů a všech oddělovacích znaků se provede skok do příslušného příkazového podprogramu. 1C16
JUMP-C-R
LD LD INC LD EX PUSH RET
HL,(#5C74) C,(HL) HL B,(HL) DE,HL BC
(T-ADDR)
Vyzvedni ukazatel na položku v tabulce parametrů a vyzvedni adresu požadovaného příkazového podprogramu. Zaměň ukazatele a proveď nepřímý skok do příkazového podprogramu.
PŘÍKAZOVÉ TŘÍDY 01,02 A 04 Tyto třídy jsou používány pro příkazy, které pracují s proměnnými (LET, FOR,.. a nepřímo též READ, INPUT). Příkaz třídy 01 je volán při identifikaci proměnné pro přík. LET, READ a INPUT. 1C1F
CLASS-01
CALL #28B2,LOOK-VARS
Urči, zda proměnná již byla či nebyla definována.
PROMĚNNÁ V PŘIDĚLENÍ Tento podprogram vytváří příslušné hodnoty pro systémové proměnné DEST a STRLEN. 1C22
VAR-A-1
1C2E
REPORT-2
LD JR SET JR RST DEFB
(IY+55),#00 (FLAGX) NC,#1C30,VAR-A-2 1,(IY+55) (FLAGX) NZ,#1C46,VAR-A-3 #08,ERROR-1 #01
Nastav FLAGX. Skoč, když proměnná už existuje. Signál: nová proměnná. Ohlaš chybu, jestliže dochází k pokusu užít nedim. pole. Ohlaš: 2-Variable not found
Zde pokračuj, jestliže obsluhuješ existující proměnnou. 1C30
100
VAR-A-2
CALL BIT JR XOR CALL CALL LD
Z,#2996,STK-VAR 6,(IY+1) (FLAGS) NZ,#1C46,VAR-A-3 A #2530,SYNTAX-Z NZ,#2BF1,STK-FETCH HL,#5C71
Parametry řetězců a všech polí jsou předány na kalkul. zásobník (STK-VAR odkrojí konec řetězce,je-li to třeba) Skoč dopředu, obsluhuješ-li číselnou proměnnou. Vynuluj registr A. Parametry řetězce nebo řetězcového pole jsou vyzvednuty v případě, že se nekontroluje syntaxe. Toto je FLAGX. Komentovaný výpis paměti ROM
OR LD EX
(HL) (HL),A DE,HL
Bit 0 je nastaven v tom případě, kdy se jedná o úplný jednoduchý řetězec, což signalizuje: smazat starou kopii. HL nyní ukazuje na řetězec nebo část pole.
Obě cesty programu se zde opět stýkají, aby STRLEN a DEST byly nastaveny na požadované hodnoty. Pro všechny numerické proměnné a nové řetězce a řetězcová pole obsahuje STRLEN-lo znak názvu proměnné. Ale pro staré řetězce a řetězcová pole, ať už jsou seříznuty nebo kompletní, obsahuje tato systémová proměnná délku přidělení. 1C46
VAR-A-3
DEST proměnné.
LD
obsahuje
(#5C72),BC (STRLEN) "cílovou"
LD RET
adresu
(#5C4D),HL (DEST)
Nastav STRLEN na požadovanou hodnotu.
"staré"
proměnné,
ale
zároveň
i
"zdrojovou"
adresu
"nové"
Nastav DEST na požadovanou hodnotu a vrať se.
Příkazy třídy 02 jsou doplněny aktuálním výpočtem hodnoty, která je přidělena v příkazu LET. 1C4E
CLASS-02
POP BC CALL #1C56,VAL-FET-1 CALL #1BEE,CHECK-END RET
Adresa SCAN-LOOP je odhozena. Je provedeno přidělení. Přesun na další příkaz, buď přes CHECK-END při kontrole syntaxe, nebo přes STMT-RET při programovém běhu.
PODPROGRAM "VYZVEDNI HODNOTU" Tento podprogram se využívá pro LET, READ a INPUT, aby ohodnotil a přidělil hodnoty deklarovaným proměnným. Vstupní bod VAL-FET-1 je používán příkazy LET a READ a posuzuje FLAGS, zatímco vstupní bod VAL-FET-2 je využíván příkazem INPUT a posuzuje FLAGX. 1C56 1C59
VAL-FET-1 VAL-FET-2
LD PUSH CALL POP LD XOR AND JR BIT JP RET
A,(#5C3B) (FLAGS) AF #24FB,SCANNING AF D,(IY+1) (FLAGS) D #40 NZ,#1C8A,REPORT-C 7,D NZ,#2AFF,LET
Použij FLAGS. Uschovej hodnocení dalšího příkazu. Proveď hodnocení dalšího příkazu. Vyzvedni starou hodnotu FLAGS nebo FLAGX. Vyzvedni novou hodnotu FLAGS. Typ proměnné numerické nebo řetězcové se musí shodovat s typem výrazu, není-li tomu tak, vypiš hlášení C. Pokud nekontroluješ syntaxi, skoč dopředu k provedení vlastního přidělení, jinak se vrať.
PŘÍKAZY TŘÍDY 04 Tento vstupní bod se používá pro příkazy FOR a NEXT. 1C6C
CLASS-04
CALL PUSH LD OR INC JR POP JR
#28B2,LOOK-VARS AF A,C #9F A NZ,#1C8A,REPORT-C AF #1C22,VAR-A-1
Zjisti zda je tato proměnná používána. Uschovej registrový pár AF zatímco budeš testovat diskriminační bajt. Ověř si také, že se jedná o smyčku FOR NEXT. Obnov podmínkový registr a skoč zpět, abys zjistil, že nalezená proměnná bude přidělena.
Komentovaný výpis paměti ROM
101
PODPROGRAM "OČEKÁVEJ ČÍSELNÝ NEBO ŘETĚZCOVÝ VÝRAZ" Toto jsou sledy krátkých podprogramů, které jsou používány k vyzvednutí výsledků dalšího ohodnoceného výrazu. Výsledek jednoduchého výrazu je vrácen jako poslední hodnota na zásobníku kalkulátoru. Vstupní bod NEXT-2NUM se používá, když je třeba upravit CH-ADD tak, aby ukazovala na začátek prvního výrazu. 1C79
NEXT-2NUM
RST
#20,NEXT-CHAR
Posuň CH-ADD.
Vstupní bod EXPT-2NUM (odpovídá třídě 8) umožňuje dvěma číselným výrazům odděleným čárkou, aby byly ohodnoceny. 1C7A
EXPT-2NUM (CLASS-08)
CALL #1C82,EXPT-1NUM
Ohodnoť oba výrazy po sobě.
CP JR RST
Není-li separátor čárka, ohlaš chybu. Posuň CH-ADD
#2C NZ,#1C8A,REPORT-C #20,NEXT-CHAR
Vstupní bod EXPT-1NUM (odpovídá třídě 6) umožňuje ohodnocení jednoho číselného výrazu. 1C82
1C8A
EXPT-1NUM (CLASS-06)
REPORT-C
CALL #24FB,SCANNING
Ohodnoť další výraz.
BIT RET RST DEFB
Byl-li výsledek číselný vrať se, jinak ohlaš: C-Nonsense in BASIC.
6,(IY+1) (FLAGS) NZ #08,ERROR-1 #0B
Vstupní bod EXPT-EXP (odpovídá třídě 0A) umožňuje ohodnocení jednoho řetězcového výrazu. 1C8C
EXPT-EXP (CLASS-0A)
CALL #24FB,SCANNING
Ohodnoť další výraz.
BIT RET JR
Je-li indikován řetězec, vrať se, jinak ohlaš chybu.
6,(IY+1) (FLAGS) Z #1C8A,REPORT-C
PODPROGRAM "NASTAVENÍ PERMANENTNÍCH BAREV" (= TŘÍDA 07) Tento podprogram umožňuje nastavení aktuálních přechodných barev. Jakožto příkaz třídy 07 představuje ve skutečnosti příkazový podprogram pro šest barevných příkazů. 1C96
PERMS (CLASS-07)
BIT RES CALL POP LD SUB CALL CALL LD LD LD LD
7,(IY+1) (FLAGS) 0,(IY+2) (TV-FLAG) NZ,#0D4D,TEMPS AF A,(#5C74) (T-ADDR) #13 #21FC,CO-TEMP-4 #1BEE,CHECK-END HL,(#5C8F) (ATTR-T) (#5C8D),HL (ATTR-P) HL,#5C91 A,(HL)
Je testována vlajka "syntaxe/run". Signál: hlavní obrazovka. V případě RUN uprav podle přech. barev barvy obrazovky. Odhoď návratovou adresu SCAN-LOOP. Vyzvedni nižší bajt T-ADDR a odečti #13 - rozsah #D9 až #DE což jsou INK až OVER. Skoč dopředu k výměně barev podle basicového příkazu. Přesuň se na další příkaz, jestliže kontroluješ syntaxi. Nyní se přechodné barvy stanou permanentními. A to jak ATTR-T tak i MASK-P. Toto je P-FLAG a ten musí být také posouzen.
Následující instrukce velmi rafinovaně okopírují liché bity na místa sudých bajtů, což ve skutečnosti způsobí, že permanentní barvy budou mít hodnoty přechodných barev. RLCA XOR (HL) AND #AA 102
Posuň masku doleva a výsledek nechť se projeví pouze na lichých bitech tohoto bajtu. Komentovaný výpis paměti ROM
XOR LD RET
(HL) (HL),A
Obnov výsledek a vrať se.
PODPROGRAM PŘÍKAZŮ TŘÍDY 09 Tento podprogram se používá pro příkazy PLOT, DRAW a CIRCLE, aby určil konstantní hodnoty pro "FLASH 8, BRIGHT 8 a PAPER 8", které jsou nastaveny ještě předtím, než budou posouzeny případné barevné položky. 1CBE
1CD6
CLASS-09
CL-09-1
CALL JR RES CALL LD LD OR LD RES RST CALL JR
#2530,SYNTAX-Z Z,#1CD6,CL-09-1 0,(IY+2) (TV-FLAG) #0D4D,TEMPS HL,#5C90 A,(HL) #F8 (HL),A 6,(IY+87) (P-FLAG) #18,GET-CHAR #21E2,CO-TEMP #1C7A,EXPT-2NUM
Skoč dopředu při kontrole syntaxe. Signál: hlavní obrazovka. Nastav přechodné barvy pro hlavní obrazovku. Toto je MASK-T. Vyzvedni jeho hodnotu a vezmi z ní pouze část odpovídající nemaskovanému INK. Obnov hodnotu, která indikuje FLASH 8,INK 8,PAPER 8. Také zajisti, že nebude PAPER 9. Vyzvedni znak před obsluhou dalších barevných položek. Zpracuj místně dominantní barevnou položku. Nyní vyzvedni první dva operandy pro PLOT, DRAW a CIRCLE.
PŘÍKAZY TŘÍDY 0B Tento podprogram je používán příkazy SAVE, LOAD, VERIFY a MERGE. 1CDB
CLASS-0B
JP
#0605,SAVE-ETC
Skoč do kazetových podprogramů.
PODPROGRAM "VYZVEDNUTÍ ČÍSLA" Tento podprogram způsobí, že následující číselný výraz bude vyhodnocen, ale jestliže neexistuje, bude nahrazen nulou. 1CDE
FETCH-NUM
CP JR CP JR
#0D Z,#1CE6,USE-ZERO #3A NZ,#1C82,EXPT-1NUM
Jedná-li se o konec řádku skoč dopředu. Nejde-li o konec příkazu skoč na EXPT-1NUM.
Nyní je použit kalkulátor, aby uložil nulu na zásobník. 1CE6
USE-ZERO
CALL RET RST DEFB DEFB RET
#2530,SYNTAX-Z Z #28,FP-CALC #A0,stk-nula #38,konec výpočtu
Neprováděj tuto operaci při kontrole syntaxe. Použij kalkulátor. "Poslední hodnota" je nyní nula. Návrat s nulou na zásobníku kalkulátoru.
Komentovaný výpis paměti ROM
103
PŘÍKAZOVÉ PODPROGRAMY Tato sekce 16k monitorového programu od adresy #1CEE až do adresy #23FA obsahuje většinu příkazových programů pro basicový interpret.
PŘÍKAZ "STOP" Podprogram příkazu STOP obsahuje pouze volání chybového hlášení. 1CEE
STOP (REPORT-9)
RST #08,ERROR-1 DEFB #08
Ohlaš: 9-STOP statement
PŘÍKAZ "IF" Hodnota výrazu mezi IF a THEN se stane "poslední hodnotou" na kalkulátorovém zásobníku. Je-li logicky pravdivá, bude se posuzovat další výraz a v ostatních případech je řádek považován za skončený. 1CF0
IF
POP BC CALL #2530,SYNTAX-Z JR Z,#1D00,IF-1
Odhoď návratovou adresu STMT-RET. Skoč dopředu při kontrole syntaxe.
Nyní použij kalkulátor k vymazání poslední položky na zásobníku kalkulátoru, ale nech DE, aby adresoval první bajt této hodnoty.
1D00
IF-1
RST DEFB DEFB EX CALL JP JP
#28,FP-CALC #02,výmaz #38,konec výpočtu DE,HL #34E9,TEST-ZERO C,#1BB3,LINE-END #1B29,STMT-L-1
Použij kalkulátor. Poslední hodnota je vymazána. HL ukazuje na první bajt a je zavolán TEST-ZERO. Byla-li hodnota "nepravda", skoč na další řádek. Ale byla-li "pravda" skoč na další příkaz po THEN.
PŘÍKAZ "FOR" Do tohoto příkazového podprogramu se vstupuje s hodnotami VALUE a LIMIT již na zásobníku kalkulátoru. 1D03
FOR
CP JR RST CALL CALL JR
#CD NZ,#1D10,F-USE-1 #20,NEXT-CHAR #1C82,EXPT-1NUM #1BEE,CHECK-END #1D16,F-REORDER
Pokud není udán krok skoč dopředu. Posuň CH-ADD a vyzvedni hodnotu pro krok. Při kontrole syntaxe se posuň na další příkaz, jinak skoč dopředu.
Nebyl-li specifikován krok, použij hodnotu "1". 1D10
F-USE-1
CALL RST DEFB DEFB
#1BEE,CHECK-END #28,FP-CALC #A1,stk-jedna #38,konec výpočtu
Další příkaz jestliže kontroluješ syntaxi, jinak použij kalkulátor a ulož hodnotu "1" na jeho zásobník.
Tři hodnoty na zásobníku kalkulátoru jsou nyní VALUE(v), LIMIT(l) a STEP(s). Tyto hodnoty budou nyní posouzeny. 1D16
104
F-REORDER
RST #28,FP-CALC DEFB #C0,st-mem-0 DEFB #02,výmaz
v,l,s v,l,s (paměť č.0=s) v,l Komentovaný výpis paměti ROM
DEFB DEFB DEFB DEFB
#01,výměna #E0,get-mem-0 #01,výměna #38,konec výpočtu
l,v l,v,s l,s,v
Řídící proměnná FOR je nyní vytvořena a považována za přechodnou oblast kalkulátorové paměti. CALL #2AFF,LET LD (#5C68),HL (MEM)
Proměnná je nalezena nebo vytvořena (má hodnotu v). Udělej z ní paměťovou oblast.
Proměnná, která byla nalezena může být pouze jednoduchá číselná proměnná používající pouze šest míst a nyní pro ni bude vyhrazeno místo. DEC LD SET LD ADD RLCA JR LD CALL INC
HL A,(HL) 7,(HL) BC,#0006 HL,BC C,#1D34,F-L&S C,#0D #1655,MAKE-ROOM HL
Vyzvedni jednopísmenný název proměnné. Zajisti, že bit 7 v názvu je nastaven. Bude třeba šest míst. HL nechť ukazuje za ně. Rotuj název a skoč byla-li to již proměnná FOR. V opačném případě vytvoř dalších 13 míst. HL ukazuje opět za pozici LIMIT.
Počáteční hodnoty pro LIMIT a STEP jsou nyní sečteny. 1D34
F-L&S
PUSH RST DEFB DEFB DEFB POP EX LD LDIR
HL #28,FP-CALC #02,výmaz #02,výmaz #38,konec výpočtu HL DE,HL C,#0A
Je uschován ukazatel. l,s l DE stále ukazuje na "l". Ukazatel je obnoven a ukazatele zaměněny. Deset bajtů LIMITu a STEPu je přesunuto.
Nyní jsou vložena čísla "smyčkovacího" řádku a příkazu. LD EX LD INC LD LD INC INC LD
HL,(#5C45) (PPC) DE,HL (HL),E HL (HL),D D,(IY+13) (SUBPPC) D HL (HL),D
Číslo aktuálního řádku. Zaměň registry před přidáním čísla řádku k řídící proměnné FOR. "Smyčkovací" příkaz je vždy dalším příkazem ať již existuje, nebo ne.
Podprogram NEXT-LOOP se volá aby testoval možnost "průběhu" a jestliže je to možné, provede se návrat. Jinak se identifikuje příkaz za smyčkou FOR-NEXT. CALL RET LD LD LD LD NEG
#1DDA,NEXT-LOOP NC B,(IY+56) (STRLEN-lo) HL,(#5C45) (PPC) (#5C42),HL (NEWPPC) A,(#5C47) (SUBPPC)
Je "průběh" možný? Jestliže ano vrať se. Vyzvedni název proměnné. Kopíruj číslo aktuálního řádku do NEWPPC. Vyzvedni číslo aktuálního příkazu a kompletuj ho.
Komentovaný výpis paměti ROM
105
LD LD LD
D,A HL,(#5C5D) (CH-ADD) E,#F3
Převeď výsledek do D. Vyzvedni hodnotu CH-ADD. Bude se hledat "NEXT".
Nyní se vzestupně prohledává programová oblast, dokud není nalezen první NEXT následovaný správnou proměnnou. 1D64
F-LOOP
PUSH LD CALL LD POP JR RST OR CP JR RST JR
BC BC,(#5C55) (NXTLIN) #1D86,LOOK-PROG (#5C55),BC (NXTLIN) BC C,#1D84,REPORT-I #20,NEXT-CHAR #20 B Z,#1D7C,F-FOUND #20,NEXT-CHAR #1D64,F-LOOP
Uschovej název proměnné. Vyzvedni aktuální hodnotu NXTLIN. Programová oblast je prohledávána a BC se bude měnit s každým novým řádkem. Obnov název proměnné. Nebylo-li NEXT nalezeno, skoč na chybové hlášení. Přejdi za nalezené NEXT. Akceptuj malá i velká písmena. Testuj název proměnné a skoč dopředu v případě shody. Opět posuň CH-ADD a nejedná-li se o správnou proměnnou, skoč zpět.
NEWPPC obsahuje číslo řádku, ve kterém byl nalezen příkaz NEXT. Musí být nalezena pozice příkazu v řádku a uložena v NSPPC. 1D7C
F-FOUND
1D84
REPORT-I
RST LD SUB LD RET RST DEFB
#20,NEXT-CHAR A,#01 D (#5C44),A (NSPPC) #08,ERROR-1 #11
Posuň CH-ADD. Počítadlo příkazů v registru D počítalo příkazy od nuly a proto musí být odečteno od jedné. Výsledek je uschován. Vrať se do STMT-RET. Ohlaš: I-FOR without NEXT
PODPROGRAM "LOOK-PROG" Tento podprogram se používá k vyhledávání příkazů DATA, DEF FN nebo příslušný kód tokenu v registru E a HL ukazuje na začátek prohledávané oblasti. 1D86
LOOK-PROG
LD CP JR
A,(HL) #3A Z,#1DA3,LOOK-P-2
NEXT.
Na
vstupu
je
Vyzvedni aktuální znak, je-li to dvojtečka, (více příkazů v řádku) skoč dopředu.
Vstup do smyčky, která prozkoumá každý další řádek. 1D8B
106
LOOK-P-1
INC LD AND SCF RET LD INC LD LD INC LD INC LD PUSH ADD LD
HL A,(HL) #C0
Vyzvedni vyšší bajt čísla řádku a nejsou-li v programu další řádky
NZ B,(HL) HL C,(HL) (#5C42),BC HL C,(HL) HL B,(HL) HL HL,BC B,H
vrať se s CY=1. Číslo řádku je vyzvednuto a
(NEWPPC)
předáno do NEWPPC.
Pak je vyzvednuta jeho délka. Ukazatel je uschován zatímco adresa konce řádku
Komentovaný výpis paměti ROM
1DA3
LOOK-P-2
LD POP LD PUSH CALL POP RET JR
C,L HL D,#00 BC #198B,EACH-STMT BC NC #1D8B,LOOK-P-1
je vytvořena v BC. Ukazatel je obnoven. Nastav počítadlo příkazů na nulu. Ukazatel na konec řádku je uschován zatímco jsou prozkoumávány příkazy v řádku. Obnovení ukazatele. Vrať se nebyl-li zde žádný výskyt, jinak posuzuj další řádek.
PŘÍKAZ "NEXT" Proměnná "v přidělení" byla již stanovena (viz TŘÍDA 04,#1C6C) a zbývá změnit její hodnotu, jak je požadováno. 1DAB
NEXT
BIT JP LD BIT JR
1,(IY+55) (FLAGX) NZ, #1C2E,REPORT-2 HL,(#5C4D) (DEST) 7,(HL) Z, #1DD8,REPORT-1
Nebyla-li proměnná nalezena ohlaš chybu. Adresa proměnné je vyzvednuta a její název je dále testován. Pokud je špatný typ proměnné, ohlaš chybu.
VALUE (hodnota) a STEP (krok) jsou upravovány pomocí kalkulátoru. INC LD RST DEFB DEFB DEFB DEFB DEFB DEFB
HL (#5C68),HL (MEM) #28,FP-CALC #E0,get-mem-0 #E2,get-mem-2 #0F,sčítání #C0,st-mem-0 #02,výmaz #38,konec výpočtu
Překroč jméno a vytvoř z proměnné přechodnou "paměťovou oblast". v v,s v+s v+s -
Výsledek sečtení hodnot VALUE + STEP je nyní porovnán s hodnotou LIMIT voláním podprogramu NEXT-LOOP. CALL #1DDA,NEXT-LOOP RET C
Testuj novou hodnotu VALUE proti hodnotě LIMIT. Byla-li smyčka FOR-NEXT již dokončena, vrať se.
Jinak vyzvedni "číslo smyčkovacího řádku a příkazu". LD LD ADD LD INC LD INC LD EX JP 1DD8
REPORT-1
HL,(#5C68) (MEM) DE,#000F HL,DE E,(HL) HL D,(HL) HL H,(HL) DE,HL #1E73,GO-TO-2
RST #08,ERROR-1 DEFB #00
Nalezni adresu nižšího bajtu čísla "smyčkovacího řádku". Nyní toto číslo vyzvedni do DE. Vyzvedni také číslo příkazu. Zaměň čísla před skokem dopředu, kde budou zpracovány jako GO-TO. Ohlaš: 1-NEXT without FOR
Komentovaný výpis paměti ROM
107
PODPROGRAM "NEXT-LOOP" Tento podprogram testuje, byl-li překročen LIMIT hodnotou VALUE. Musí se přihlédnout znaménku hodnoty STEP. Tento podprogram nastaví CY flag na hodnotu 1, byl-li LIMIT překročen. 1DDA
NEXT-LOOP
RST DEFB DEFB DEFB DEFB DEFB DEFB DEFB
#28,FP-CALC #E1,get-mem-1 #E0,get-mem-0 #E2,get-mem-2 #36,<0 #00,skok-pravda #02,na NEXT-1 #01,záměna
l l,v l,v,s l,v,(1 nebo 0) l,v,(1 nebo 0) l,v,(1 nebo 0) v,l
1DE2
NEXT-1
DEFB DEFB DEFB DEFB DEFB AND RET
#03,odečítání #37,>0 #00,skok-pravda #04,na NEXT-2 #38,konec výpočtu A
v-l nebo l-v (1 nebo 0) (1 nebo 0) Vyčisti CY flag a vrať se-smyčka je možná.
ke
Ovšem, není-li možné smyčku provést, nastav CY flag. 1DE9
NEXT-2
DEFB #38,konec výpočtu SCF RET
Nastav CY flag a vrať se.
PODPROGRAM PŘÍKAZU READ Příkaz READ umožňuje načítání seznamů dat a ve skutečnosti je podobný sérii příkazů LET. Systémová proměnná X-PTR se využívá k úschově ukazatele na příkaz READ, zatímco CH-ADD slouží ke krokování seznamu DATA. 1DEC 1DED
READ-3 READ
1E08
REPORT-E
RST CALL CALL JR RST LD LD LD CP JR LD CALL JR RST DEFB
#20,NEXT-CHAR #1C1F,CLASS-01 #2530,SYNTAX-Z Z,#1E1E,READ-2 #18,GET-CHAR (#5C5F),HL (X-PTR) HL,(#5C57) (DATADD) A,(HL) #2C Z,#1E0A,READ-1 E,#E4 #1D86,LOOK-PROG NC,#1E0A,READ-1 #08,ERROR-1 #0D
Posun na další znak a jeho vyzvednutí v A. Zjištění zdali proměnná existuje a její vyhledání. Při kontrole syntaxe skok dopředu. Vyzvedni znak. Úschova CH-ADD v X-PTR. Vyzvedni ukazatel na seznam DATA, načti další znak a pokud nebyl nalezen nový příkaz DATA, skoč dopředu. Hledá se token DATA. Skoč dopředu při úspěšném nálezu. Ohlaš: E-Out of DATA
Pokračování - vybírání hodnot ze seznamu DATA. 1E0A
108
READ-1
CALL CALL RST LD LD LD CALL
#0077,TEMP-PTR1 Posunuj ukazatel po seznamu a nastav CH-ADD. #1C56,VAL-FET-1 Vyzvedni hodnotu a přiděl ji proměnné. #18,GET-CHAR Vyzvedni aktuální hodnotu CH-ADD (#5C57),HL (DATADD) a ulož ji v DATADD. HL,(#5C5F) (X-PTR) Vyzvedni ukazatel příkazu READ (IY+38),#00 (X-PTR-hi) a vynuluj X-PTR. #0078,TEMP-PTR2 CH-ADD ještě jednou ukazuje na příkaz READ. Komentovaný výpis paměti ROM
1E1E
READ-2
RST CP JR
#18,GET-CHAR #2C Z,#1DEC,READ-3
CALL #1BEE,CHECK-END RET
Vyzvedni aktuální znak a testuj na čárku. Je-li to čárka, skoč zpět, protože existují další položky. Při kontrole syntaxe se vrať přes CHECK-END, anebo do STMT-RET.
PODPROGRAM PŘÍKAZU DATA Při kontrole syntaxe je příkaz DATA testován, zdali obsahuje sérii platných výrazů, oddělených čárkami. Ale při běhu programu se tento příkaz vynechá. 1E27
DATA
1E2C
DATA-1
CALL JR CALL CP CALL RST JR
#2530,SYNTAX-Z NZ,#1E37,DATA-2 #24FB,SCANNING #2C NZ,#1BEE,CHECK-END #20,NEXT-CHAR #1E2C,DATA-1
Pokud nekontroluješ syntaxi, skoč dopředu. Kontroluj další výraz a správný oddělovač. Posuň se na další příkaz, pokud nesouhlasí. Další znak. Pokračuj ve smyčce.
Při běhu programu se příkaz data překročí. 1E37
DATA-2
LD
A,#E4
Token DATA.
PODPROGRAM VYNECHÁNÍ Na vstupu je v registru A kód příkazu, který má být vynechán. (DATA nebo DEF FN, podle momentálního použití tohoto podprogramu). 1E39
PASS-BY
LD B,A CPDR LD DE,#0200 JP #198B,EACH-STMT
BC ať obsahuje nějaké dosti vysoké číslo. Vzestupné hledání token. Nyní najdi následující příkaz. (D mínus prvý).
PODPROGRAM PŘÍKAZU RESTORE Operand pro RESTORE se považuje za číslo řádku a pokud není uveden, dosadí se nula. Vstupní bod REST-RUN se použije za chodu. 1E42 1E45
RESTORE REST-RUN
CALL LD LD CALL DEC LD RET
#1E99,FIND-INT2 H,B L,C #196E,LINE-ADDR HL (#5C57),HL (DATADD)
Kompresuj operand do BC. Převeď výsledek do HL. Najdi adresu tohoto nebo následujícího řádku. DATADD bude ukazovat na jednu pozici před řádek. Hotovo - vrať se.
PODPROGRAM PŘÍKAZU RANDOMIZE Operand je kompresován do BC a uložen do příslušné systémové proměnné. Není-li operand uveden, použijí se hodnoty z FRAMES 1 a FRAMES 2. 1E4F
RANDOMIZE
1E5A
RAND-1
CALL LD OR JR LD LD
#1E99,FIND-INT2 A,B C NZ,#1E5A,RAND-1 BC,(#5C78) (FRAMES) (#5C76),BC (SEED)
Vyzvedni operand do BC a pokud se nejedná o nulovou hodnotu, skoč dopředu. Vyzvedni dva nižší bajty FRAMES a ulož je do systémové proměnné SEED.
Komentovaný výpis paměti ROM
109
RET
Vrať se.
PODPROGRAM PŘÍKAZU CONTINUE Příslušná čísla řádku a příkazu se stanou předmětem skoku. 1E5F
CONTINUE
LD LD JR
HL,(#5C6E) (OLDPPC) D,(IY+54) (OSPPC) #1E73,GO-TO-2
Číslo řádku. Číslo příkazu. Skok dopředu.
PODPROGRAM PŘÍKAZU GO TO Operandem musí být číslo řádku v rozsahu 1 až 9999. Ale vzhledem k "obrácené" logice číslování se testuje na číslo 61439. 1E67
GO-TO
CALL LD LD LD LD CP JR
#1E99,FIND-INT2 H,B L,C D,#00 A,H #F0 NC,#1E9F,REPORT-B
Vyzvedni operand převeď jej do HL. Nastav číslo příkazu na nulu. Jestliže hodnota přesahuje 61439, skoč na chybové hlášení.
Vstupní bod GO-TO-2 se používá v četných případech při určování čísla následujícího řádku. 1E73
GO-TO-2
LD LD RET
(#5C42),HL (NEWPPC) (IY+10),D (NSPPC)
Vlož číslo řádku a číslo příkazu. Vrať se.
PODPROGRAM PŘÍKAZU OUT Oba parametry jsou vyzvednuty ze zásobníku kalkulátoru a vyslány. 1E7A
OUT
CALL #1E85,TWO-PARAM OUT (C),A RET
Vyzvedni operandy. Skutečná instrukce OUT. Hotovo.
PODPROGRAM PŘÍKAZU POKE POKE se provede obdobně. 1E80
POKE
CALL #1E85,TWO-PARAM LD (BC),A RET
Vyzvedni operandy. Skutečná instrukce POKE. Hotovo.
PODPROGRAM TWO-PARAM První parametr na zásobníku kalkulátoru musí být kompresovatelný do jednoduchého registru a je-li záporný, bude komplementován. Druhý parametr na zásobníku kalkulátoru musí být kompresovatelný do registrového páru. 1E85
TWO-PARAM
1E8E
TWO-P-1
110
CALL JR JR NEG PUSH CALL POP
#2DD5,FP-TO-A C,#1E9F,REPORT-B Z,#1E8E,TWO-P-1 AF #1E99,FIND-INT2 AF
Vyzvedni parametr a skoč na chybu,je-li příliš vysoký. Skoč dopředu s kladnými čísly, ale komplementuj záporná čísla. Uschovej první parametr a vyzvedni druhý. Vyzvedni první parametr Komentovaný výpis paměti ROM
RET
a vrať se.
PODPROGRAMY NALEZENÍ INTEGERŮ "Poslední hodnota" na zásobníku registru nebo registrového páru. 1E94
FIND-INT1
1E99 1E9C
FIND-INT2 FIND-I-1
1E9F
REPORT-B
CALL JR CALL JR RET RST DEFB
kalkulátoru
#2DD5,FP-TO-A #1E9C,FIND-I-1 #2DA2,FP-TO-BC C,#1E9F,REPORT-B Z #08,ERROR-1 #0A
je
vyzvednuta
a
kompresována
do
jednoduchého
Vyzvedni hodnotu do A a skoč. Vyzvedni hodnotu do BC a v obou případech skoč na chybu, je-li CY = 1. Vrať se s pozitivními čísly, která jsou v rozsahu. Ohlaš: B-Integer out of range
PODPROGRAM PŘÍKAZU RUN Parametry příkazu RUN jsou předány do NEWPPC voláním příkazového podprogramu GO TO. Před návratem se provede RESTORE 0 a CLEAR 0. 1EA1
RUN
CALL LD CALL JR
#1E67,GO-TO BC,#0000 #1E45,REST-RUN #1EAF,CLEAR-1
Nastav NEWPPC na hodnotu operandu. Proveď RESTORE 0. Výstup přes příkaz CLEAR.
PODPROGRAM PŘÍKAZU CLEAR Podprogram způsobí vyčištění oblasti proměnných, obrazovky a nastavení RAMTOP. Následkem této poslední operace je znovu nastaven zásobník a tím také vyčištěn zásobník GO SUB. 1EAC 1EAF
CLEAR CLEAR-RUN
1EB7
CLEAR-1
CALL LD OR JR LD PUSH LD LD DEC CALL CALL
#1E99,FIND-INT2 A,B C NZ,#1EB7,CLEAR-1 BC,(#5CB2) (RAMTOP) BC DE,(#5C4B) (VARS) HL,(#5C59) (E-LINE) HL #19E5,RECLAIM-1 #0D6B,CLS
Vyzvedni operand a použij 0, neexistuje-li. Pokud operand není nulový, skoč dopředu. (Při volání z RUN, ke skoku nedojde). Použij stávající hodnotu RAMTOP. Uschovej ji. Zruš oblast proměnných. Vyčisti obrazovku.
Hodnota v BC je testována na přípustné minimum a maximum.
1EDA
REPORT-M
LD LD ADD POP SBC JR LD AND SBC JR RST DEFB
HL,(#5C65) (STKEND) DE,#0032 HL,DE DE HL,DE NC,#1EDA,REPORT-M HL,(#5CB4) (P-RAMT) A HL,DE NC,#1EDC,CLEAR-2 #08,ERROR-1 #15
Aktuální hodnota zásobníku je zvýšena o 50 bajtů, což bude představovat dolní limit. RAMTOP je příliš nízký. Je vyzvednuta hodnota P-RAMT a testována proti RAMTOP. Skok dopředu, je-li hodnota přijatelná. Ohlaš: M-RAMTOP no good
Pokračuj operací CLEAR. Komentovaný výpis paměti ROM
111
1EDC
CLEAR-2
EX LD POP POP LD DEC LD PUSH LD EX JP
DE,HL (#5CB2),HL DE BC (HL),#3E HL SP,HL BC (#5C3D),SP DE,HL (HL)
(RAMTOP)
(ERR-SP)
Skutečné nastavení RAMTOP. Vyzvedni adresu STMT-RET. Vyzvedni "chybovou" adresu. Vlož koncový znak pro zásobník GO SUB. Vynech jedno místo. Nastav ukazatel zásobníku na prázdný zásobník GO SUB. Ulož "chybovou" adresu na zásobník a uschovej jeho adresu do ERR-SP. Zaměň adresy a proveď nepřímý návrat do STMT-RET.
Poznámka: Je-li CLEAR volán příkazem RUN, je třeba najít další řádek skokem do STMT-RET, protože hodnoty NEWPPC a NSPPC byly již změněny.
PODPROGRAM PŘÍKAZU GO SUB Aktuální hodnota PPC a zvýšená hodnota SUBPPC jsou uloženy na zásobník GO SUB. 1EED
GO-SUB
POP LD INC EX INC LD PUSH PUSH LD PUSH CALL LD
DE H,(IY+13) (SUBPPC) H (SP),HL SP BC,(#5C45) (PPC) BC HL (#5C3D),SP (ERR-SP) DE #1E67,GO-TO BC,#0014
Vyzvedni návratovou adresu k uschování v DE. Vyzvedni číslo příkazu a zvětši jej. Zaměň "chybovou adresu" s číslem příkazu a reklamuj tuto lokaci. Dále ulož číslo aktuálního řádku. Vrať "chybovou" adresu na zásobník a nastav ERR-SP, aby na ní ukazoval. Vrať adresu STMT-RET. Nyní nastav NEWPPC & NSPPC na potřebné hodnoty. Připrav hodnotu na testování prostoru.
PODPROGRAM TESTOVÁNÍ PROSTORU Provádí řadu testů je-li dostatečný prostor volné paměti pro vykonání prováděného úkolu. 1F05
TEST-ROOM
LD ADD JR EX LD ADD JR SBC RET
HL,(#5C65) (STKEND) HL,BC C, #1F15,REPORT-4 DE,HL HL, #0050 HL,DE C, #1F15,REPORT-4 HL,SP C
Vezmi hodnotu STKEND a zvyš ji o hodnotu vstupující v BC. Skoč na chybové hlášení, došlo-li k přetečení. Další pokus s přičtením 80 bajtů. Skoč na chybové hlášení, došlo-li k přetečení. Testuj proti adrese zásobníku a vrať se, pokud vyhovuje.
1F15
REPORT-4
LD JP
L, #03 #0055,ERROR-3
Toto je chyba za běhu a proto nikdy nebude použit chybový znak (otazník)
ZJIŠTĚNÍ VOLNÉ PAMĚTI SPECTRUM sice nemá basicový příkaz "FREE", ale protože zde existuje tento podprogram, lze velikost volné paměti zjistit použitím : PRINT 65536-USR 7962. 1F1A
112
FREE-MEM
LD BC, #0000 CALL #1F05,TEST-ROOM LD B,H
Nepovoluje se "nic navíc". Vlastní test. Převedení
Komentovaný výpis paměti ROM
LD RET
C,L
do BC a návrat.
PODPROGRAM PŘÍKAZU RETURN Ze zásobníku GO SUB se vyzvedne číslo řádku a příkazu. 1F23
RETURN
POP POP POP LD CP JR DEC EX EX LD PUSH JP
BC HL DE A,D #3E Z, #1F36,REPORT-7 SP (SP),HL DE,HL (#5C3D),SP (ERR-SP) BC #1E73,GO-TO-2
Vyzvedni adresu STMT-RET. Vyzvedni "chybovou" adresu. Vyzvedni poslední položku ze zásobníku GO SUB. Testuj, jestli se jedná o koncový znak zásobníku GO SUB, a v tom případě skoč do podprogramu chybových hlášení. Celý údaj potřebuje tři bajty. Zaměň číslo příkazu za "chybovou" adresu a převeď do DE. Nastav chybový ukazatel. Vrať adresu STMT-RET na zásobník. Skok na změnu NEWPPC & NSPPC.
1F36
REPORT-7
PUSH PUSH RST DEFB
DE HL #08,ERROR-1 #06
Vlož koncový znak a chybovou adresu. Ohlaš: 7-RETURN without GOSUB
PODPROGRAM PŘÍKAZU PAUSE Trvání pauzy je dáno čítáním maskovaných přerušení, ke kterým dochází každou 1/50 tinu sekundy. PAUSE je ukončena buď po načtení příslušného počtu přerušení, nebo při stisku některé klávesy. 1F3A 1F3D
PAUSE PAUSE-1
1F49
PAUSE-2
1F4F
PAUSE-END
CALL HALT DEC LD OR JR LD AND INC JR INC BIT JR RES RET
#1E99,FIND-INT2 BC A,B C Z, #1F4F,PAUSE-END A,B C A NZ,#1F49,PAUSE-2 BC 5,(IY+1) (FLAGS) Z,#1F3D,PAUSE-1 5,(IY+1) (FLAGS)
Vyzvedni operand. Čekej na maskované přerušení. Zmenši čítač. Je-li nulový, příkaz PAUSE končí. Jestliže byl operand nula, BC bude obsahovat #FFFF a tato je opět upravena na nulu. Skok se všemi ostatními hodnotami. Nebyla-li stištěna žádná klávesa, skok zpět. Signál: nebyla stištěna žádná klávesa. Návrat do STMT-RET.
PODPROGRAM BREAK Podprogram zjistí stištění klávesy BREAK, což signalizuje nastavením CY=0. 1F54
BREAK-KEY
LD IN RRA RET LD IN RRA RET
A, #7F A,(#FE) C A, #FE A,(#FE)
Vytvoř adresu portu #7FFE a načti bajt. Testuj pouze bit 0, jeho rotací do CY. Vrať se, pokud klávesa BREAK nebyla stištěna. Vytvoř adresu portu #FEFE a načti bajt. Testuj pouze bit 0, jeho rotací do CY. Vrať se s CY=0, pokud došlo k současnému stištění.
Komentovaný výpis paměti ROM
113
PODPROGRAM PŘÍKAZU DEF FN Při kontrole syntaxe se testuje, zdali má příkaz správnou formu. Také se vytvoří prostor pro výsledek ohodnocení funkce. Ale pokud je program v běhu, tento příkaz se vynechá. 1F60
DEF-FN
CALL JR LD JP
#2530,SYNTAX-Z Z, #1F6A,DEF-FN-1 A, #CE #1E39,PASS-BY
Při kontrole syntaxe skok dopředu. Jinak vynechání příkazu.
Nejdříve se posuzuje proměnná této funkce. 1F6A
DEF-FN-1
1F7D
DEF-FN-2
SET CALL JR RST CP JR RES RST CP JR RST CP JR
6,(IY+1) (FLAGS) #2C8D,ALPHA NC,#1F89,DEF-FN-4 #20,NEXT-CHAR #24 NZ,#1F7D,DEF-FN-2 6,(IY+1) (FLAGS) #20,NEXT-CHAR #28 NZ,#1FBD,DEF-FN-7 #20,NEXT-CHAR #29 Z,#1FA6,DEF-FN-6
Signál: číselná proměnná. Je aktuální znak v registru A písmeno? Skok dopředu, jestliže ne. Vyzvedni další znak. Nejedná-li se o $, skoč dopředu. Změň bit 6, protože se jedná o řetězcovou proměnnou. Vyzvedni další znak. Závorka musí následovat za názvem proměnné. "(". Skok na chybu. Vyzvedni další znak. Test na závorku ")". Skoč, jestliže funkce nemá parametry.
Zde se vstupuje do smyčky, která postupně ošetří všechny parametry. 1F86 1F89
DEF-FN-3 DEF-FN-4
1F94
DEF-FN-5
CALL JP EX RST CP JR EX RST EX LD CALL INC INC LD CP JR RST JR
#2C8D,ALPHA NC,#1C8A,REPORT-C DE,HL #20,NEXT-CHAR #24 NZ,#1F94,DEF-FN-5 DE,HL #20,NEXT-CHAR DE,HL BC,#0006 #1655,MAKE-ROOM HL HL (HL),#0E #2C NZ,#1FA6,DEF-FN-6 #20,NEXT-CHAR #1F86,DEF-FN-3
Je aktuální znak v registru A písmeno? Skok na chybu, jestliže ne. Uschovej ukazatel v DE. Vyzvedni další znak. Nejedná-li se o $, skoč dopředu. Uschovej nový ukazatel v DE. Vyzvedni další znak. Předej ukazatel na poslední písmeno názvu do HL a vytvoř prostor 6 bajtů za tímto posledním znakem názvu. Do první z nových lokací ulož znak uvádějící FP číslo. Není-li aktuální znak čárka, opusť smyčku, protože nejsou další parametry. Vyzvedni další znak a skoč zpět pro další parametry.
Dále je posouzena definice funkce. 1FA6
114
DEF-FN-6
CP JR RST CP JR RST LD PUSH
#29 NZ,#1FBD,DEF-FN-7 #20,NEXT-CHAR #3D NZ,#1FBD,DEF-FN-7 #20,NEXT-CHAR A,(#5C3B) (FLAGS) AF
Kontrola, že závorka ")" skutečně existuje. Skok na chybu. Vyzvedni další znak a není-li to rovnítko, skoč na chybu. Vyzvedni další znak. Vyzvedni jeho typ (číselná/řetězcová proměnná) a uschovej.
Komentovaný výpis paměti ROM
1FBD
DEF-FN-7
CALL POP XOR AND JP CALL
#24FB,SCANNING AF (IY+1) (FLAGS) #40 NZ,#1C8A,REPORT-C #1BEE,CHECK-END
Posuď definici jako výraz. Vyzvedni typ proměnné a testuj je-li stejného typu jako proměnná nalezená pro definici. Pokud je to třeba, skoč na chybu. Výstup přes CHECK-END a tím posun na hodnocení dalšího příkazu.
PODPROGRAM UNSTACK-Z Tento podprogram je volán v mnoha případech k provedení "dřívějšího" návratu z podprogramu při kontrole syntaxe. Tím se zabrání nežádoucím tiskům a přesouvání hodnot na zásobníku kalkulátoru. 1FC3
UNSTACK-Z
CALL POP RET JP
#2530,SYNTAX-Z HL Z (HL)
Jde o kontrolu syntaxe? Vyzvedni návratovou adresu a ignoruj ji při kontrole syntaxe. Za běhu programu proveď obyčejný návrat.
PODPROGRAMY PŘÍKAZU LPRINT & PRINT Otevře se příslušný kanál a potom se postupně zkoumají jednotlivé položky, které mají být vytisknuty. 1FC9
LPRINT
1FCD 1FCF
PRINT PRINT-1
LD JR LD CALL CALL CALL CALL CALL RET
A, #03 #1FCF,PRINT-1 A, #02 #2530,SYNTAX-Z NZ,#1601,CHAN-OPEN #0D4D,TEMPS #1FDF,PRINT-2 #1BEE,CHECK-END
Příprava na otevření kanálu P. Skok dopředu. Příprava na otevření kanálu S. Pokud nekontroluješ syntaxi, skoč na otevření kanálu. Nastav přechodné barvy. Volej tiskový podprogram. Při kontrole syntaxe se posuň na další příkaz. Vrať se.
Tiskový podprogram je volán z programu PRINT, LPRINT & INPUT. 1FDF
PRINT-2
RST #18,GET-CHAR CALL #2045,PR-END-Z JR Z,#1FF2,PRINT-4
Vyzvedni první znak a jsi-li již na konci seznamu položek, skoč dopředu.
Nyní vstup do smyčky, která obsluhuje poziční znaky a tiskové položky. 1FE5
PRINT-3
1FF2
PRINT-4
CALL JR CALL CALL JR CP RET
#204E,PR-POSN-1 Z,#1FE5,PRINT-3 #1FFC,PR-ITEM-1 #204E,PR-POSN-1 Z,#1FE5,PRINT-3 #29 Z
Obsluž všechny následovné poziční znaky. Obsluž jednoduché tiskové položky. Testuj, jestli jsou další položky a tiskni všechny až do konce Je-li aktuální znak závorka ")", vrať se. Jinak postup do podprogramu CR.
PODPROGRAM "CR - NÁVRAT VOZÍKU" 1FF5
PRINT-CR
CALL #1FC3,UNSTACK-Z LD A,#0D RST #10,PRINT-A-1 RET
Vrať se při kontrole syntaxe. Proveď CR a vrať se.
Komentovaný výpis paměti ROM
115
PODPROGRAM TISKU POLOŽEK Podprogram je volán z programu PRINT, LPRINT & INPUT. 1FFC
PR-ITEM-1
200E
PR-ITEM-2
RST CP JR CALL CALL CALL LD JR CP JR RST CALL CALL CALL LD
#18,GET-CHAR #AC NZ,#200E,PR-ITEM-2 #1C79,NEXT-2NUM #1FC3,UNSTACK-Z #2307,STK-TO-BC A,#16 #201E,PR-AT-TAB #AD NZ,#2024,PR-ITEM-3 #20,NEXT-CHAR #1C82,EXPT-1NUM #1FC3,UNSTACK-Z #1E99,FIND-INT2 A,#17
Vyzvedni první znak. Pokud to není token AT, skoč dopředu. Předej dva parametry na zásobník kalkulátoru. Návrat při kontrole syntaxe. Parametry do BC. Řídící znak AT do registru A a skok na provedení. Pokud to není token TAB, skoč dopředu. Vyzvedni další znak. Předej jeden parametr na zásobník kalkulátoru. Návrat při kontrole syntaxe. Parametr do BC. Řídící znak TAB do registru A.
AT a TAB se provedou třemi voláními PRINT-OUT. 201E
PR-AT-TAB
RST LD RST LD RST RET
#10,PRINT-A-1 A,C #10,PRINT-A-1 A,B #10,PRINT-A-1
Tiskni řídící znak. Následuje hodnota prvního parametru. A hodnota druhého parametru. Vrať se.
Dále posuzuj "implantované informace" o barvách. 2024
PR-ITEM-3
CALL RET CALL RET
#21F2,CO-TEMP-3 NC #2070,STR-ALTER NC
Pokud je taková informace obsažena, vrať se CY=0. Posuzuj, má-li být změněn proud. Pokračuj, pokud ne.
Tisková informace musí být číselný nebo řetězcový výraz. CALL CALL BIT CALL JP
#24FB,SCANNING #1FC3,UNSTACK-Z 6,(IY+1) (FLAGS) Z,#2BF1,STK-FETCH NZ,#2DE3,PRINT-FP
Proveď hodnocení výrazu, ale vrať se, pokud provádíš kontrolu syntaxe. Test typu výrazu. Je-li to řetězec, vyzvedni potřebné parametry. Je-li to číslo, vystup přes PRINT-FP.
Následující smyčka zpracuje postupně všechny znaky v řetězci. 203C
PR-STRING
LD OR DEC RET LD INC RST JR
A,B C BC Z A,(DE) DE #10,PRINT-A-1 #203C,PR-STRING
Pokud jsou všechny znaky vypsány, vrať se. Vyzvedni kód a posuň ukazatel. Tiskni znak. A skoč na další posouzení.
PODPROGRAM "KONEC TISKU" Z flag = 1, není-li co tisknout.
116
Komentovaný výpis paměti ROM
2045
PR-END-Z
2048
PR-ST-END
CP RET CP RET CP RET
#29 Z #0D Z #3A
Je-li znak závorka ")", vrať se. Je-li znak CR, vrať se. Před návratem testuj znak dvojtečky.
PODPROGRAM "TISK POZICE" Tento podprogram zpracuje různé znaky řídící tiskovou pozici. 204E
PR-POSN-1
2061
PR-POSN-2
2067
PR-POSN-3
206E
PR-POSN-4
RST CP JR CP JR CALL JR LD RST JR CP RET CALL RST CALL JR POP CP RET
#18,GET-CHAR #3B Z,#2067,PR-POSN-3 #2C NZ,#2061,PR-POSN-2 #2530,SYNTAX-Z Z,#2067,PR-POSN-3 A,#06 #10,PRINT-A-1 #2067,PR-POSN-3 #27 NZ #1FF5,PRINT-CR #20,NEXT-CHAR #2045,PR-END-Z NZ,#206E,PR-POSN-4 BC A
Vyzvedni aktuální znak. Je-li to středník, skoč dopředu. Je-li to čárka, skoč dopředu. Ale při kontrole syntaxe znak netiskni. Dej do A řídící kód čárky vytiskni ji a skoč dopředu. Testuj apostrof " ' " a vrať se pokud to nebyl některý z pozičních znaků. Pokud nekontroluješ syntaxi, tiskni CR. Vyzvedni další znak. Nejsi-li na konci tiskového příkazu, skoč dopředu. Jinak se vrať do volajícího podprogramu. Nebylo-li dosaženo konce příkazu, nastaví se Z flag=0.
PODPROGRAM "ZMĚNA PROUDU" Kdykoliv je třeba posoudit, jestli uživatel chce použít odlišný proud, volá se tento podprogram. 2070
STR-ALTER
CP SCF RET RST CALL AND CALL CALL CP JP CALL AND RET
#23 NZ #20,NEXT-CHAR #1C82,EXPT-1NUM A #1FC3,UNSTACK-Z #1E94,FIND-INT1 #10 NC,#160E,REPORT-0 #1601,CHAN-OPEN A
Testuj znak " # " a pokud není, vrať se s CY=1. Vyzvedni další znak. Parametr na zásobník kalkulátoru. CY=0. Vrať se při kontrole syntaxe. Vyzvedni hodnotu do A. Pokud je hodnota větší než #0F, skoč na chybové hlášení. Otevři kanál pro daný proud. CY=0 a vrať se.
PODPROGRAM PŘÍKAZU INPUT Tento podprogram umožňuje přidělení hodnot vstupujících z klávesnice do dané proměnné. Současně zajišťuje aby tisková informace se zobrazovala do dolní části obrazovky. 2089
INPUT
CALL JR LD CALL
#2530,SYNTAX-Z Z,#2096,INPUT-1 A,#01 #1601,CHAN-OPEN
Při kontrole syntaxe skoč dopředu. Kanál K a jeho otevření.
Komentovaný výpis paměti ROM
117
2096
INPUT-1
20AD
INPUT-2
CALL LD CALL CALL LD LD CP JR LD LD LD LD SUB LD RES CALL JP
#0D6E,CLS-LOWER (IY+2),#01 (TV-FLAG) #20C1,IN-ITEM-1 #1BEE,CHECK-END BC,(#5C88) (S-POSN) A,(#5C6B) (DF-SZ) B C,#20AD,INPUT-2 C,#21 B,A (#5C88),BC (S-POSN) A,#19 B (#5C8C),A (SCR-CT) 0,(IY+2) (TV-FLAG) #0DD9,CL-SET #0D6E,CLS-LOWER
Smazání dolní části obrazovky. Nastav dolní část obrazovky na velikost jednoho řádku. Volej obsluhu vložených tisků. Při kontrole syntaxe postup na další příkaz. Vyzvedni aktuální tiskovou pozici a pokud se tato nachází nad dolní částí obrazovky, skoč dopředu. Jinak nastav tiskovou pozici na nejvyšší řádek dolní části obrazovky. Nyní nastav čítač rolování. Signál: hlavní obrazovka. Nastav systémové proměnné a proveď výstup přes CLS-LOWER.
Tato smyčka se zabývá položkami INPUT a PRINT. 20C1
IN-ITEM-1
CALL JR CP JR RST CALL RST CP JP RST JP
#204E,PR-POSN-1 Z,#20C1,IN-ITEM-1 #28 NZ,#20D8,IN-ITEM-2 #20,NEXT-CHAR #1FDF,PRINT-2 #18,GET-CHAR #29 NZ,#1C8A,REPORT-C #20,NEXT-CHAR #21B2,IN-NEXT-2
Nejprve posuzuj poziční znaky. Jestliže aktuální znak není závorka " ( ", skoč dopředu. Vyzvedni další znak. Vytiskni položky uvnitř závorek. Vyzvedni znak a pokud to není závorka " ) ", skoč na chybové hlášení. Vyzvedni další znak a skoč na posouzení dalších případných položek.
Nyní posuzuj, je-li použito INPUT LINE. 20D8
IN-ITEM-2
CP JR RST CALL SET BIT JP JR
#CA NZ,#20ED,IN-ITEM-3 #20,NEXT-CHAR #1C1F,CLASS-01 7,(IY+55) (FLAGX) 6,(IY+1) (FLAGS) NZ,#1C8A,REPORT-C #20FA,IN-PROMPT
Nejedná-li se o LINE, skoč dopředu. Vyzvedni další znak. Určení cílové adresy pro proměnnou. Signál: INPUT LINE. Nejedná-li se o řetězcovou proměnnou, skoč dopředu. Skok na vypsání náznaku.
Zpracování proměnných INPUT. 20ED
IN-ITEM-3
20FA
IN-PROMPT
118
CALL JP CALL RES CALL JP CALL LD RES SET LD BIT JR
#2C8D,ALPHA NC,#21AF,IN-NEXT-1 #1C1F,CLASS-01 7,(IY+55) (FLAGX) #2530,SYNTAX-Z Z,#21B2,IN-NEXT-2 #16BF,SET-WORK HL,#5C71 6,(HL) 5,(HL) BC,#0001 7,(HL) NZ,#211C,IN-PR-2
Není-li aktuální znak písmeno, skoč zpět do smyčky. Určení cílové adresy proměnné. Signál: Nejedná se o INPUT LINE. Jestliže kontroluješ syntaxi, skoč dopředu. Pracovní prostor je nastaven na nulu. Toto je FLAGX. Signál: řetězcový výsledek. Signál: INPUT mode. Náznak zabere jedno místo. Při použití LINE skoč dopředu. Komentovaný výpis paměti ROM
211A
IN-PR-1
211C
IN-PR-2
2129
IN-PR-3
LD AND JR LD OR LD RST LD LD RRCA RRCA JR LD LD DEC LD LD
A,(#5C3B) (FLAGS) #40 NZ,#211A,IN-PR-1 C,#03 (HL) (HL),A #30,BC-SPACES (HL),#0D A,C
NC,#2129,IN-PR-3 A,#22 (DE),A HL (HL),A (#5C5B),HL (K-CUR)
Očekáváš-li číselný vstup, skoč dopředu. Řetězcová náznak zabere tři místa. Pro číselnou položku bude nastaven bit 6 FLAGX. Je vytvořen požadovaný prostor. Znak CR na poslední místo. Testováním bitu 6 registru C se zjistí bylo-li vytvořeno pouze jedno místo a v tom případě se provede skok. Znak uvozovek přijde na první a druhé místo. Je uschována pozice kurzoru.
V případě INPUT LINE může být editor volán bez další přípravy, ale pro ostatní typy INPUTů musí být pozměněn chybový zásobník, aby zachytával případně chyby.
213A
IN-VAR-1
2148
IN-VAR-2
215E
IN-VAR-3
BIT JR LD PUSH LD PUSH LD PUSH BIT JR LD LD CALL LD CALL RES CALL JR CALL
7,(IY+55) (FLAGX) NZ,#215E,IN-VAR-3 HL,(#5C5D) (CH-ADD) HL HL,(#5C3D) (ERR-SP) HL HL,#213A HL 4,(IY+48) (FLAGS2) Z,#2148,IN-VAR-2 (#5C3D),SP (ERR-SP) HL,(#5C61) (WORKSP) #11A7,REMOVE-FP (IY+0),#FF (ERR-NR) #0F2C,EDITOR 7,(IY+1) (FLAGS) #21B9,IN-ASSIGN #2161,IN-VAR-4 #0F2C,EDITOR
Pokud jde o INPUT LINE, skok dopředu. Uschovej aktuální hodnotu CH-ADD na zásobníku. Uschovej aktuální hodnotu ERR-SP na zásobníku. Toto bude bod návratu v případě výskytu chyby. Pokud používáš kanál K, přeskoč dopředu. Nastav ukazatel chyby. Nastav HL na začátek řádku INPUT a odstraň FP formy. Signál: zatím žádná chyba. Nyní vezmi INPUT a nastav signál : kontrola syntaxe. Testuj INPUT na chyby a skoč, je-li vše v pořádku. Vem LINE.
Všechny systémové proměnné musí být nastaveny, než se provede skutečné přidělení hodnoty. 2161
IN-VAR-4
2174
IN-VAR-5
LD CALL JR CALL LD CALL LD RES BIT RES JR POP POP LD POP
(IY+34),#00 (K-CUR-hi) Adresa kurzoru je resetována. #21D6,IN-CHAN-K Pokud se používá jiný kanál než K NZ,#2174,IN-VAR-5 provede se skok. #111D,ED-COPY Inputový řádek je vypsán na obrazovku BC,(#5C82) (ECHO-E) a pozice z ECHO-E se stane aktuální tiskovou pozicí #0DD9,CL-SET v dolní části obrazovky. HL,#5C71 Toto je FLAGX. 5,(HL) Signál: edit mode. 7,(HL) Pokud se jedná 7,(HL) o INPUT LINE, NZ,#219B,IN-VAR-6 skoč dopředu. HL Zahoď adresu IN-VAR-1. HL Vyzvedni (#5C3D),HL (ERR-SP) a obnov původní adresu pro ERR-SP. HL Vyzvedni původní adresu CH-ADD
Komentovaný výpis paměti ROM
119
219B
IN-VAR-6
LD SET CALL LD LD LD JR LD LD SCF SBC LD LD CALL CALL JR
(#5C5F),HL (X-PTR) a uschovej ji v X-PTR. 7,(IY+1) (FLAGS) Signál: běh programu. #21B9,IN-ASSIGN Proveď přidělení. HL,(#5C5F) (X-PTR) Původní adresa CH-ADD do HL. (IY+38),#00 (X-PTR-hi) Vynulování X-PTR-hi (#5C5D),HL (CH-ADD) a obnovení CH-ADD. #21B2,IN-NEXT-2 Skok na posouzení případných dalších položek. HL,(#5C63) (STKBOT) Konec LINE do HL. DE,(#5C61) (WORKSP) Začátek LINE do DE. HL,DE B,H C,L #2AB2,STK-STO-$ #2AFF,LET #21B2,IN-NEXT-2
Výpočet délky a převod do BC. Tyto parametry jdou na zásobník a provede se přidělení. Skok na posouzení případných dalších položek.
Jsou posuzovány další položky. 21AF 21B2
IN-NEXT-1 IN-NEXT-2
CALL #1FFC,PR-ITEM-1 CALL #204E,PR-POSN-1 JP Z,#20C1,IN-ITEM-1 RET
Ošetři jakoukoliv tiskovou položku. Ošetři jakoukoliv poziční položku. Případný skok na posouzení dalších položek. Návrat.
PODPROGRAM "IN ASIGN" Tento podprogram je volán dvakrát pro každý INPUT. Jednou při "kontrole syntaxe" a jednou za běhu programu. 21B9
IN-ASSIGN
21CE
REPORT-C
LD LD RST CP JR LD CALL RST CP RET RST DEFB
HL,(#5C61) (WORKSP) (#5C5D),HL (CH-ADD) #18,GET-CHAR #E2 Z,#21D0,IN-STOP A,(#5C71) (FLAGX) #1C59,VAL-FET-2 #18,GET-CHAR #0D Z #08,ERROR-1 #0B
Nastav CH-ADD, aby ukazovala na první místo pracovního prostoru. Vyzvedni znak. Je to token STOP? Skoč, jestliže ano. Jinak přiřaď proměnné její hodnotu. Vyzvedni znak a pokud se jedná o CR, vrať se. Ohlaš: C-Nonsense in BASIC.
Do tohoto bodu se skočí v případě, že INPUT začíná příkazem STOP. 21D0
IN-STOP
21D4
REPORT-H
CALL RET RST DEFB
#2530,SYNTAX-Z Z #08,ERROR-1 #10
Ale při kontrole syntaxe nebude ohlášena "chyba". Ohlaš: H-Stop in INPUT.
PODPROGRAM "IN-CHAN-K" Podprogram vrací Z flag=0, jedině když se používá kanál K. 21D6
120
IN-CHAN-K
LD INC INC INC INC
HL,(#5C51) HL HL HL HL
(CURCHL)
Je vyzvednuta bázová adresa kanálových informací a kód aktuálního kanálu Komentovaný výpis paměti ROM
LD CP RET
A,(HL) #4B
je testován proti znaku K. Návrat.
PODPROGRAMY "BAREVNÝCH POLOŽEK" Tento soubor podprogramů lze rozdělit na dvě části: a) Část obsluhující "implementované" barevné informace. b) Část obsluhující systémové proměnné ATTR-T,MASK-T a P-FLAG. Barevné informace budou zpracovány postupně. Vstupní bod je CO-TEMP-2. 21E1 21E2
CO-TEMP-1 CO-TEMP-2
21F2
CO-TEMP-3
RST CALL RET RST CP JR CP JR JP CP RET CP CCF RET PUSH RST POP
#20,NEXT-CHAR #21F2,CO-TEMP-3 C #18,GET-CHAR #2C Z,#21E1,CO-TEMP-1 #3B Z,#21E1,CO-TEMP-1 #1C8A,REPORT-C #D9 C #DF C AF #20,NEXT-CHAR AF
Vyzvedni další znak. Posuď, je-li tento znak vloženou barevnou informací. Vrať se s CY=1, pokud není. Vyzvedni aktuální znak. Je-li to čárka, skoč zpět. Je-li to středník, skoč zpět. Jinak ohlaš chybu. Jestliže testovaný kód není v rozsahu #D9 až #DD (INK až OVER), vracej se s CY=1. Uschovej kód barevné informace a posuň ukazatel na parametr. Obnov kód.
Kód barevné informace a jeho parametry jsou nyní vytisknuty voláním podprogramu PRINT-OUT. 21FC
CO-TEMP-4
SUB
#C9
PUSH CALL POP AND CALL PUSH CALL LD POP RST LD RST RET
AF #1C82,EXPT-1NUM AF A #1FC3,UNSTACK-Z AF #1E94,FIND-INT1 D,A AF #10,PRINT-A-1 A,D #10,PRINT-A-1
Kód token je snížen na hodnotu řídícího znaku (#10 až #15). Uschovej kód. Předej parametr na zásobník kalkulátoru. Obnov kód a pokud kontroluješ syntaxi, vrať se pomocí UNSTACK-Z. Uschovej kód. Vyzvedni parametr a převeď do D. Obnov kód a vytiskni jej. Parametr do A a vytiskni jej. Vrať se.
B) Barevné systémové proměnné (ATTR-T, MASK-T & P-FLAG) jsou upraveny na požadované hodnoty. Podprogram je volán z podprogramu PRINT-OUT. Na vstupu je kód řídícího znaku v registru A a jeho parametr v registru D. Všechny změny barev jsou pouze "přechodné". 2211
CO-TEMP-5
SUB ADC JR SUB ADC JR
#11 A,#00 Z,#2234,CO-TEMP-7 #02 A,#00 Z,#2273,CO-TEMP-C
Snižuj rozsah a skoč dopředu při INK & PAPER. Ještě sniž rozsah a skoč dopředu při FLASH & BRIGHT.
Komentovaný výpis paměti ROM
121
Kód řídícího znaku je nyní #01 pro INVERSE a #02 pro OVER. Podle toho bude nastavena systémová proměnné P-FLAG.
2228
CO-TEMP-6
CP LD LD JR RLCA RLCA LD LD LD CP JR LD LD JR
#01 A,D B,#01 NZ,#2228,CO-TEMP-6
B,#04 C,A A,D #02 NC,#2244,REPORT-K A,C HL,#5C91 #226C,CO-CHANGE
Příprava na skok pro OVER. Vyzvedni parametr. Připrav masku pro OVER. Skoč, jde-li o OVER. Pro INVERSE 0 musí být bit 2 registru A nastaven na nulu. Pro INVERSE 1 musí být bit 2 reg. A nastaven na jedničku. Maska má bit 2 nastaven na jedničku. Uschovej obsah A. Povolený rozsah parametru je pouze #00 až #01. Skok na chybu, jeli mimo rozsah. Vyzvedni zpět A. Toto je P-FLAG, který se bude měnit. Výstup přes CO-CHANGE se změnou P-FLAG maskou v registru B.
V této části se zpracuje PAPER a INK. Na vstupu je CY=1 pro INK. 2234
CO-TEMP-7
223E
CO-TEMP-8
2244
REPORT-K
LD LD JR RLCA RLCA RLCA LD LD LD CP JR RST DEFB
A,D B,#07 C,#223E,CO-TEMP-8
Vyzvedni parametr. Připrav masku pro INK. Skoč dopředu s INK. Vynásob parametr osmi.
B,#38 C,A A,D #0A C,#2246,CO-TEMP-9 #08,ERROR-1 #13
Připrav masku pro PAPER. Uschovej parametr v C. Povolený rozsah parametru. je pouze #00 až #09. Skoč, je-li rozsah dodržen. Ohlaš: K-Invalid colour
Pokračuj zpracováním řádek PAPER & INK. 2246
2257
CO-TEMP-9
CO-TEMP-A
LD CP JR LD JR OR CPL AND JR LD LD
HL,#5C8F #08 C,#2258,CO-TEMP-B A,(HL) Z,#2257,CO-TEMP-A B #24 Z,#2257,CO-TEMP-A A,B C,A
Příprava na změnu ATTR-T, MASK-T & P-FLAG. Skoč dopředu s PAPER/INK 0 až 7. Vyzvedni hodnotu ATTR-T a pokud je PAPER/INK 8, skoč dopředu (barva se nemění). Ale pro PAPER/INK 9 budou barvy černá a bílá. Skoč s černými INK/PAPER. Pokračuj s bílými INK/PAPER. Převeď hodnotu do C.
Nyní jsou použity maska B a hodnota C ke změně ATTR-T. 2258
122
CO-TEMP-B
LD CALL LD CP SBC CALL
A,C #226C,CO-CHANGE A,#07 D A,A #226C,CO-CHANGE
Hodnota zpět do A. Změna ATTR-T. Bity MASK-T se budou měnit pouze pro PAPER/INK 8 nebo 9.
Komentovaný výpis paměti ROM
RLCA RLCA AND LD LD CP SBC
#50 B,A A,#08 D A,A
Pro P-FLAG je příslušná maska vytvořena v registru B. Bit 4 a 6 bude změněn jedině v případě že PAPER/INK je 9. Pokračuj přes CO-CHANGE na zpracování P-FLAG.
PODPROGRAM "CO-CHANGE" Tento podprogram předá systémové proměnné bity vstupující v registru A. Maska v B ukazuje, které bity z A mají být kopírovány na (HL). 226C
CO-CHANGE
XOR AND XOR LD INC LD RET
(HL) B (HL) (HL),A HL A,B
Bity specifikované registrem B jsou změněny a výsledek jde do systémové proměnné. Přejdi na adresu další systémové proměnné. Vrať se s maskou v registru A.
Nyní se zpracuje FLASH & BRIGHT. 2273
CO-TEMP-C
227D
CO-TEMP-D
2287
CO-TEMP-E
SBC LD RRCA LD JR RRCA LD LD LD CP JR CP JR LD LD CALL LD RRCA RRCA RRCA JR
A,A A,D B,#80 NZ,#227D,CO-TEMP-D B,#40 C,A A,D #08 Z,#2287,CO-TEMP-E #02 NC,#2244,REPORT-K A,C HL,#5C8F (ATTR-T) #226C,CO-CHANGE A,C
#226C,CO-CHANGE
Pro BRIGHT bude Z - flag = 0. Parametr je vyzvednut a rotován. Připrav masku pro FLASH. Skoč dopředu jde-li o FLASH. Další rotace a příprava masky pro BRIGHT. Uschovej hodnotu v C. Vyzvedni parametr a testuj jeho rozsah. Povoleno je pouze #08, #01 a #02. Skoč na chybové hlášení pokud tomu tak není. Obnov uschovanou hodnotu do A. Toto je ATTR-T. Proveď změnu této systémové proměnné. Obnov uschovanou hodnotu do A. Rotuj, aby bit nastavený pro FLASH/BRIGHT 8 přešel na místo bitu 7 pro FLASH nebo bitu 6 pro BRIGHT. Vystup přes CO-CHANGE.
PODPROGRAM PŘÍKAZU BORDER Parametr příkazu BORDER je proveden instrukcí OUT a uschován v systémové proměnné BORDCR. 2294
BORDER
CALL CP JR OUT RLCA RLCA RLCA BIT JR
#1E94,FIND-INT1 #08 NC,#2244,REPORT-K (#FE),A
5,A NZ,#22A6,BORDER-1
Vyzvedni parametr a testuj jeho rozsah. Skok na chybu, je-li parametr větší než 7. Nastav barvu BORDER násob parametr osmi. Je-li barva BORDER světlá, skoč dopředu (INK bude černý).
Komentovaný výpis paměti ROM
123
22A6
BORDER-1
XOR LD RET
#07 (#5C48),A (BORDCR)
Změna barvy INK. Nastav systémovou proměnnou. Vrať se.
PODPROGRAM "ADRESA OBRAZOVÉHO BODU" Je používán podprogramy POINT a PLOT. Na vstupu obsahuje BC souřadnice x,y. Na výstupu je v HL adresa bajtu obrazovky, ve kterém je daný bod obsažen a registr A ukazuje na jeho pozici uvnitř tohoto bajtu. 22AA
PIXEL-ADD
LD SUB JP LD AND RRA SCF RRA AND RRA XOR AND XOR LD LD RLCA RLCA RLCA XOR AND XOR RLCA RLCA LD LD AND RET
A,#AF B C,#24F9,REPORT-B B,A A
A B #F8 B H,A A,C
Testuj, zdali souřadnice y není větší než 175 a jestliže ano, skoč na ohlášení B nyní obsahuje 175-y. A obsahuje bity: 7 6 5 4 3 2 1 0 A obsahuje: 00 a bity: 7 6 5 4 3 CY=1 A obsahuje: 01 00 a bity 7 6 5 4 CY=0 A obsahuje: 00 01 00 a bity: 7 6
chyby. bajtu z reg. B + CY=0. 2 1. 3 2. 5 4 3.
A obsahuje: 00 01 00 a bity: 7 6 2 1 0. Takže H bude obsahovat 64+8*INT (b/64)+(b mod 8) což je vyšší bajt adresy bodu. A obsahuje bity:7 6 5 4 3 2 1 0 bajtu z reg. C.
A obsahuje bity: 2 1 0 7 6 5 4 3. B #C7 B
A obsahuje bity: 2 1 5 4 3 5 4 3.
L,A A,C #07
A obsahuje bity: 5 4 3 7 6 5 4 3. Takže L bude 32*INT (b/(b mod 64)/8)+INT (x/8). A obsahuje x (mod 8). Takže bod je bit (0 až 7) uvnitř daného bajtu.
PODPROGRAM POINT Je používán podprogramem příkazu POINT při prohledávání. Na vstupu jsou souřadnice x, y uloženy na zásobníku kalkulátoru a na výstupu je na zásobníku 1, pokud má bod barvu INK a 0, je-li to barva PAPER. 22CB
POINT-SUB
22D4
POINT-LP
124
CALL CALL LD INC LD RLCA DJNZ AND JP
#2307,STK-TO-BC #22AA,PIXEL-ADD B,A B A,(HL) #22D4,POINT-LP #01 #2D28,STACK-A
Y do reg.B a x do reg. C. Adresa bodu do HL. B bude počítat A+1 krát aby se požadovaný bit převedl do bitu 0. Vyzvedni bajt z videoram. Rotuj doleva a zároveň do CY. Bit=1 pro inkoust, 0 pro papír. Výsledek je uložen na zásobník kalkulátoru.
Komentovaný výpis paměti ROM
PODPROGRAM PŘÍKAZU PLOT Je využíván také programy CIRCLE a DRAW. Na vstupu jsou souřadnice x, y uloženy na zásobníku kalkulátoru. Po nalezení adresy se bere v úvahu stav INVERSE a OVER a nakreslí příslušný bod. 22DC
PLOT
22E5
PLOT-SUB
22F0
PLOT-LOOP
22FD
PL-TST-IN
2303
PLOT-END
CALL CALL JP LD CALL LD INC LD RRCA DJNZ LD LD LD BIT JR AND BIT JR XOR CPL LD JP
#2307,STK-TO-BC #22E5,PLOT-SUB #0D4D,TEMPS (#5C7D),BC (COORDS) #22AA,PIXEL-ADD B,A B A,#FE #22F0,PLOT-LOOP B,A A,(HL) C,(IY+87) (P-FLAG) 0,C NZ,#22FD,PL-TST-IN B 2,C NZ,#2303,PLOT-END B (HL),A #0BDB,PO-ATTR
Y do reg. B a x do reg. C. Volání podprogramu. Výstup s nastavením přechodných barev. Nastav systémovou proměnnou. Adresa bodu do HL. B bude počítat A+1 krát, aby se log. 0 dostala na správné místo v A. Vložení nuly a její nastavení do bitu, který odpovídá pozici bodu kopie do B. Bajt obrazovky do A. Test na OVER 1 a přeskok, když ano OVER 0 způsobí, že bod bude mít hodnotu 0. Test na INVERSE 1 a přeskok, když ano INVERSE 0 překlopí logickou hodnotu bodu. Bajt je vložen na obrazovku. Výstup s nastavením atributu.
PODPROGRAM STK-TO-BC Tento podprogram uloží dvě FP čísla do registrového páru BC a je používán k vyzvednutí parametrů v rozsahu #00 až #FF. Zároveň však ukládá do registrového páru DE tzv. diagonální hodnoty (+-1,+-1), které jsou používány v podprogramu DRAW. 2307
STK-TO-BC
CALL LD PUSH CALL LD POP LD LD RET
#2314,STK-TO-A B,A BC #2314,STK-TO-A E,C BC D,C C,A
První číslo do A. Potom do B. Chvilková úschova. Druhé číslo do A a jeho znaménko do E. Obnov první číslo. Jeho znaménko do D. Druhé číslo do C. BC a DE jsou nastaveny tak, jak bylo požadováno.
PODPROGRAM STK-TO-A Tento podprogram uloží do registru A FP číslo z vrcholu kalkulátorového zásobníku. Číslo musí být v rozsahu #00 až #FF. 2314
STK-TO-A
CALL JP LD RET LD RET
#2DD5,FP-TO-A C,#24F9,REPORT-B C,#01 Z C,#FF
Modul zaokrouhlené poslední hodnoty do registru A, není-li to možné, ohlaš chybu. #01 do C jako signál: pozitivní hodnota. Vrať se, byla-li hodnota pozitivní. V ostatních případech změň hodnotu v C na #FF (= -1). Hotovo.
Komentovaný výpis paměti ROM
125
PŘÍKAZ CIRCLE Tento podprogram narýsuje přibližnou kružnici se středem v bodě X,Y o poloměru Z. Parametry jsou před použitím převedeny na tvar INTEGER. Proto Z musí být menší než 87.5, i když střed kružnice leží ve středu obrazovky. Použitá metoda nakreslí sérii přímek aproximujících oblouk. Program CIRCLE má čtyři části: a) Test poloměru. Je-li poloměr menší než jedna, je narýsován pouze bod o souřadnicích X,Y. b) Je zavolána CD-PRMS1 na adrese #247D, která se používá k nastavení počátečních parametrů pro CIRCLE a DRAW. c) Jsou nastaveny zbývající parametry pro CIRCLE včetně počátečního umístění prvního “oblouku“. d) Skok do DRAW, kde je využito programu pro narýsování oblouku (na adrese #2420). Nyní budou popsány postupně části a) až c). ad a) #2320 až #233A. Poloměr Z je vyzvednut z kalkulátorového zásobníku a jeho hodnota je převedena na vhodný tvar. Je-li Z menší než jedna, je vymazáno ze zásobníku a je proveden odskok pro narýsování bodu o souřadnicích X,Y. 2320
CIRCLE
RST CP JP RST CALL CALL RST DEFB DEFB
#18,GET-CHAR #2C NZ,#1C8A,REPORT-C #20,NEXT-CHAR #1C82,EXPT-1NUM #1BEE,CHECK-END #28,FP-CALC #2A,abs #3D,re-stack
DEFB LD CP JR RST DEFB DEFB JR
#38,konec výpočtu A,(HL) #81 NC,#233B,C-R-GRE-1 #28,FP-CALC #02,výmaz #38,konec výpočtu #22DC,PLOT
Vyzvedni aktuální znak a otestuj ho. Ohlaš chybu, není-li to čárka. Vyzvedni další znak (poloměr) a ulož ho na zásobník kalkulátoru. Přejdi na další příkaz při kontrole syntaxe. Kalkulátor. X,Y,Z Tvar Z je převeden z INTEGERu na FP a ponechán na zásobníku; proto je jeho exponent k dispozici. Vezmi exponent poloměru. Testuj, jestli je menší než jedna. Jestliže ne, skoč. Je-li menší, vymaž ho ze zásobníku. Zásobník nyní obsahuje X,Y. Narýsuj bod na souřadnicích X,Y.
ad b) #233B až #2346 a volání CD-PRMS1. 2*PI je uloženo do paměti č.5 a je zavoláno CD-PRMS1. Tento program uloží do registru B počet křivek, které jsou potřebné pro kruh viz. A=4*INT(PI*SQR Z/4)+4, což je 4,8,12 ... až do maxima 32. Také ukládá do paměti č.0 až č.4 hodnoty 2*PI/A, SIN(PI/A), 0, COS (2*PI/A) a SIN (2*PI/A). 233B
C-R-GRE-1
RST DEFB DEFB LD RST DEFB DEFB DEFB CALL
#28,FP-CALC #A3,stk-pi/2 #38,konec výpočtu (HL),#83 #28,FP-CALC #C5,st-mem-5 #02,výmaz #38,konec výpočtu #247D,CD-PRMS1
X,Y,Z,PI/2 Nyní dochází ke změně exponentu na #83, čímž dochází ke změně PI/2 na 2*PI. X,Y,Z,2*PI. 2*PI do mem-5. X,Y,Z Nastav počáteční parametry.
ad c) #2347 až #2381: zbývající parametry a skok na DRAW. Testuje se, jestli je délka počátečního oblouku menší než jedna. Je-li tomu tak, provede se skok na prosté narýsování bodu o souřadnicích X,Y. Jinak jsou nastaveny tyto parametry: X+Z a Y-Z* SIN (PI/A) jako počáteční a koncový bod, a okopírovány do COORDS. Nula a hodnota 2*Z*SIN (PI/A) jsou uschovány v mem-1 a mem-2 jako počáteční přírůstky. Smyčka příkazu DRAW, která zajišťuje rýsování oblouku, také zajistí, že všechny narýsované body zůstanou na stejné kružnici, a přírůstkový úhel bude 2*PI/A. 126
Komentovaný výpis paměti ROM
2347
235A
C-ARC-GE1
PUSH RST DEFB DEFB DEFB DEFB LD CP JR RST DEFB DEFB DEFB POP JP RST DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB
BC #28,FP-CALC #31,zdvojení #E1,get-mem-1 #04,násobení #38,konec výpočtu A,(HL) #80 NC,#235A,C-ARC-GE1 #28,FP-CALC #02,výmaz #02,výmaz #38,konec výpočtu BC #22DC,PLOT #28,FP-CALC #C2,st-mem-2 #01,záměna #C0,st-mem-0 #02,výmaz #03,odečítání #01,záměna #E0,get-mem-0 #0F,sčítání #CO,st-mem-0 #01,záměna #31,zdvojení #E0,get-mem-0 #01,záměna #31,zdvojení #E0,get-mem-0 #A0,stk-nula #C1,st-mem-1 #02,výmaz #38,konec výpočtu
Úschova počítadla oblouků do B. X,Y,Z X,Y,Z,Z X,Y,Z,Z,SIN (PI/A) X,Y,Z,Z*SIN (PI/A) Z*SIN (PI/A) je polovinou délky počátečního oblouku, a tato hodnota je testována, aby se zjistilo, jestli je menší než 0.5. Když ne, provede se skok. Jinak jsou Z a “polooblouk“ vymazány ze zásobníku kalkulátoru.
Strojový zásobník je také vyčištěn a provede se skok na vytištění bodu o souřadnicích X,Y. X,Y,Z,Z*SIN (PI/A) Z * SIN (PI/A) do mem-2. X,Y,Z*SIN (PI/A),Z X,Y,Z*SIN (PI/A),Z X,Y,Z*SIN (PI/A) X,Y-Z*SIN (PI/A) Y-Z*SIN (PI/A),X Y-Z*SIN (PI/A),X,Z Y-Z*SIN (PI/A),X+Z X+Z do mem-0. X+Z,Y-Z*SIN (PI/A) X+Z,Y-Z*SIN (PI/A), Y-Z*SIN (PI/A) sa,sb,sb,sa sa,sb,sa,sb sa,sb,sa,sb,sb sa,sb,sa,sb,sb,sa sa,sb,sa,sb,sb,sa,0 mem-1 nastavena na nulu. sa,sb,sa,sb,sb,sa
Zde “sa“ znamená X+Z a “sb“ znamená Y-Z*SIN (PI/A). INC CALL LD PUSH CALL POP LD LD POP JP
(IY+28) (mem-2-1st) #1E94,FIND-INT1 L,A HL #1E94,FIND-INT1 HL H,A (#5C7D),HL (COORDS) BC #2420,DRW-STEPS
Exponent v mem-2 je změněn-vzniká tvar 2*Z*SIN (PI/A). Poslední hodnota X + Z je předána ze zásobníku do registru A, a je uschována v HL. Y-Z*SIN (PI/A) jde ze zásobníku do A a je kopírováno do H. HL ukazuje na počáteční bod a ten jde do COORDS. Je obnoveno počítadlo oblouků a provede se skok na DRAW.
Nyní jsou na zásobníku hodnoty X+Z, Y-Z*SIN (PI/A), Y-Z*SIN (PI/A), X+Z.
Komentovaný výpis paměti ROM
127
PODPROGRAM PŘÍKAZU DRAW Do tohoto podprogramu se vstupuje se souřadnicemi bodů, řekněme X0,Y0 v systémové proměnné COORDS. Jsou-li pro příkaz DRAW udány pouze dva parametry X,Y, potom podprogram narýsuje přímku z bodu X0,Y0 do bodu X0+X,Y0+Y. Je-li udán třetí parametr G, potom podprogram rýsuje aproximaci kruhového oblouku z bodu o souřadnicích X0,Y0 do bodu X0+X,Y0+Y, jehož středový úhel je G rad. Podprogram má čtyři části: a) jsou-li udány pouze dva parametry nebo parametr poloměru je menší než jedna, je narýsována prostá přímka. b) volá CD-PRMS1 na #247D k nastavení počátečních parametrů. c) nastavuje zbývající parametry a to včetně počátečních rozmístnění pro první oblouk. d) vstupuje do smyčky pro rýsování oblouků na #24B7. Dva podprogramy CD-PRMS1 a DRAW-LINE následují za postupně popsány všechny čtyři části hlavního podprogramu.
tímto
hlavním
podprogramem.
Nyní
budou
ad a) Jsou-li udány pouze dva parametry provede se skok na LINE-DRAW na adrese #2477. Přímka se rýsuje také v tom případě, je-li hodnota Z menší než jedna. Z leží jedním až jedenapůltým násobkem průměru zamýšlené kružnice. V této části je nastavena mem-0 na SIN (G/2), mem-1 na Y a mem-5 na G. 2382
DRAW
238D
DR-3-PRMS
23A3
DR-SIN-NZ
128
RST CP JR CALL JP RST CALL CALL RST DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB JP DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB
#18,GET-CHAR #2C Z,#238D,DR-3-PRMS #1BEE,CHECK-END #2477,LINE-DRAW #20,NEXT-CHAR #1C82,EXPT-1NUM #1BEE,CHECK-END #28,FP-CALC #C5,st-mem-5 #A2,stk-polovinu #04,násobení #1F,sin #31,zdvojení #30,not #30,not #00,skok-pravda #06,na DR-SIN-NZ #02,výmaz #38,konec výpočtu #2477,LINE-DRAW #C0,st-mem-0 #02,výmaz #C1,st-mem-1 #02,výmaz #31,zdvojení #2A,abs #E1,get-mem-1 #01,záměna #E1,get-mem-1 #2A,abs #0F,sčítání #E0,get-mem-0 #05,dělení #2A,abs #E0,get-mem-0 #01,záměna
Vyzvedni aktuální znak. Je-li to čárka, skoč. Při kontrole syntaxe se posuň na další příkaz. Skoč na pouhé rýsování přímky. Vyzvedni další znak (úhel), který je uložen na zásobníku kalkulátoru. Při kontrole syntaxe se posuň na další příkaz. X,Y,G jsou na zásobníku. G jde do mem-5 X,Y,G,0.5 X,Y,G/2 X,Y,SIN (G/2) X,Y,SIN (G/2),SIN (G/2) X,Y,SIN (G/2), (0 nebo 1) X,Y,SIN (G/2), (1 nebo 0) X,Y,SIN (G/2) Jestli SIN (G/2)=0 tj. G=2*N*PI narýsuj přímku. X,Y Přímka z bodu X0,Y0 do X0+X,Y0+Y. SIN (G/2) jde do mem-0. X,Y jsou nyní na zásobníku Y jde do mem-1 X X,X X,X' (X'=ABS X) X,X',Y X,Y,X' X,Y,X',Y X,Y,X',Y' (Y'=ABS Y) X,Y,X'+Y' X,Y,X'+Y',SIN (G/2) X,Y,(X'+Y')/SIN (G/2) (dále pouze Z') X,Y,Z (Z=ABS Z') X,Y,Z,SIN (G/2) X,Y,SIN (G/2),Z Komentovaný výpis paměti ROM
DEFB DEFB LD CP JR RST DEFB DEFB DEFB JP
#3D,re-stack #38,konec výpočtu A,(HL) #81 NC,#23C1,DR-PRMS #28,FP-CALC #02,delete #02,delete #38,konec výpočtu #2477,LINE-DRAW
Z je v zásobníku převedeno tak, aby byl k dispozici jeho exponent. Vyzvedni exponent Z. Je-li Z větší nebo rovno jedné, skoč. X,Y,SIN (G/2),Z X,Y,SIN (G/2) X,Y Narýsuj přímku z bodu X0,Y0 do X0+X,Y0+Y.
ad b) Pouhé volání CD-PRMS1. Tento podprogram uchová v registru B počet kratších oblouků, které jsou potřeba pro kompletní oblouk. Podprogram také ukládá v mem-0 až v mem-4 hodnoty G/A, SIN (G/2*A), 0, COS (G/A), SIN (G/A). 23C1
DR-PRMS
CALL #247D,CD-PRMS1
Podprogram je volán.
ad c) Nastaví se zbytek parametrů jak je třeba. Zásobník bude obsahovat tyto čtyři položky čteno zdola: X0+X a Y0+Y jako koncový bod posledního oblouku, pak X0 a Y0 jako počátečný bod prvního oblouku. Mem-0 bude obsahovat X0 a mem-5 Y0. Mem-1 a mem-2 budou obsahovat počáteční umístění pro první oblouk U a V a mem-3 a mem-4 budou obsahovat COS (G/A) a SIN (G/A) pro potřeby smyčky rýsující oblouky. Formule pro výpočet U a V se dá vysvětlit následovně: Místo aby se postupovalo po závěrečné tětivě řekněme délky L, s přírůstky X a Y, chceme postupovat po počáteční tětivě (která může být delší) délky L*W, kde W=SIN (G/2*A)/SIN (G/2), s přírůstky X*W a Y*W, ale pootočené o úhel (G/2-G/2*A), tedy s pravdivými přírůstky: U=Y*W*SIN (G/2-G/2*A)+X*W*COS (G/2-G/2*A) V=Y*W*COS (G/2-G/2*A)-X*W*SIN (G/2-G/2*A) Tyto formule mohou být kontrolovány z diagramu, při použití normálních rozkladů pro COS (P-Q) a SIN (P-Q), kde Q=G/2-G/2*A. 23C4
PUSH RST DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB
BC #28,FP-CALC #02,výmaz #E1,get-mem-1 #01,záměna #05,dělení #C1,st-mem-1 #02,výmaz #01,záměna #31,zdvojení #E1,get-mem-1 #04,násobení #C2,st-mem-2 #02,výmaz #01,záměna #31,zdvojení #E1,get-mem-1 #04,násobení #E2,get-mem-2 #E5,get-mem-5 #E0,get-mem-0 #03,odčítání #A2,stk-polovina #04,násobení #31,zdvojení #1F,sin
Uschovej počítadlo oblouků v regist. B. X,Y,SIN (G/2),Z X,Y,SIN (G/2) X,Y,SIN (G/2),SIN (G/2*A) X,Y,SIN (G/2*A),SIN (G/2) X,Y,SIN (G/2*A)/SIN (G/2)=W W do mem-1. X,Y Y,X Y,X,X Y,X,X,W Y,X,X*W X*W do mem-2. Y,X X,Y X,Y,Y X,Y,Y,W X,Y,Y*W X,Y,Y*W,X*W X,Y,Y*W,X*W,G X,Y,Y*W,X*W,G,G/A X,Y,Y*W,X*W,G-G/A X,Y,Y*W,X*W,G-G/A,1/2 X,Y,Y*W,X*W,G/2-G/2*A (dále pouze F) X,Y,Y*W,X*W,F,F X,Y,Y*W,X*W,F,SIN F
Komentovaný výpis paměti ROM
129
DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB LD CP POP JP PUSH RST DEFB DEFB LD CALL RST DEFB DEFB DEFB DEFB LD CALL RST DEFB DEFB DEFB DEFB DEFB POP
130
#C5,st-mem-5 #02,výmaz #20,cos #C0,st-mem-0 #02,výmaz #C2,st-mem-2 #02,výmaz #C1,st-mem-1 #E5,get-mem-5 #04,násobení #E0,get-mem-0 #E2,get-mem-2 #04,násobení #0F,sčítání #E1,get-mem-1 #01,záměna #C1,st-mem-1 #02,výmaz #E0,get-mem-0 #04,násobení #E2,get-mem-2 #E5,get-mem-5 #04,násobení #03,odečítání #C2,st-mem-2 #2A,abs #E1,get-mem-1 #2A,abs #0F,sčítání #02,výmaz #38,konec výpočtu A,(DE) #81 BC C,#2477,LINE-DRAW BC #28,FP-CALC #01,záměna #38,konec výpočtu A,(#5C7D) (COORDS-lo) #2D28,STACK-A #28,FP-CALC #C0,st-mem-0 #0F,sčítání #01,záměna #38,konec výpočtu A,(#5C7E) (COORDS-hi) #2D28,STACK-A #28,FP-CALC #C5,st-mem-5 #0F,sčítání #E0,get-mem-0 #E5,get-mem-5 #38,konec výpočtu BC
SIN F do mem-5. X,Y,Y*W,X*W,F X,Y,Y*W,X*W,COS F COS F do mem-0. X,Y,Y*W,X*W X*W do mem-2. X,Y,Y*W Y*W do mem-1. X,Y,Y*W,SIN F X,Y,Y*W*SIN F X,Y,Y*W*SIN F,X*W X,Y,Y*W*SIN F,X*W,COS F X,Y,Y*W*SIN F,X*W*COS F X,Y,Y*W*SIN F+X*W*COS F (dále U) X,Y,U,Y*W X,Y,Y*W,U U do mem-1. X,Y,Y*W X,Y,Y*W,COS F X,Y,Y*W*COS F X,Y,Y*W*COS F,X*W X,Y,Y*W*COS F,X*W,SIN F X,Y,Y*W*COS F,X*W*SIN F X,Y,Y*W*COS F-X*W*SIN F (dále V) V do mem-2. X,Y,V' (V'=ABS V) X,Y,V',U X,Y,V',U' (U'=ABS U) X,Y,V'+U' X,Y DE nyní ukazuje na U'+V'. Vem exponent U'+V'. Jestliže platí U'+V' < 1, pak pouze ukliď zásobník. Přímka z bodu X0,Y0 do X0+X,Y0+Y. Jinak pokračuj s parametry X,Y na zásobníku. Y,X Dej X0 do A a tím dále na zásobník. Y,X,X0 X0 do mem-0. Y,X0+X X0+X,Y Dej Y0 do A a tím i na zásobník. X0+X,Y,Y0 Y0 do mem-5. X0+X,Y0+Y X0+X,Y0+Y,X0 X0+X,Y0+Y,X0,Y0 Obnov počítadlo oblouků v registru B.
Komentovaný výpis paměti ROM
ad d) Smyčka pro rýsování oblouků. Do této smyčky se vstupuje na adrese #2439 s souřadnicemi počátečního bodu na vrcholu zásobníku a s umístěním prvního oblouku v mem-1 a mem-2. Je zajištěno pomocí jednoduché trigonometrie, že všechny následující body X1, Y1 a X2, Y2 leží na kružnici a jsou tětivami středového úhlu N, který je též původem těchto souřadnic, potom X2=X1*COS(N)-Y1*SIN(N), Y2=X1*SIN N+Y1*COS N. Ale protože původ je zde ve spodním levém rohu obrazovky, musí se pro dosažení požadovaného efektu zahrnout tyto vztahy do přírůstků, řekněme Un=Xn+1-Xn a Vn=Yn+1-Yn, ve smyčce pro rýsování oblouků. V následujícím komentáři jsou ukázány hodnoty zásobníku pro n+1 průběh smyčkou, kdy Xn a Yn jsou už zvětšeny o hodnoty Un a Vn poté, co byly obdrženy z Un-1 a Vn-1. Čtyři hodnoty na vrcholu zásobníku na #2425 jsou u DRAW, čteno zdola, X0+X, Y0+Y, Xn, Yn ale pro ušetření místa nejsou tyto hodnoty ukázány až do bodu #2439. Zajímají-li vás hodnoty pro příkaz CIRCLE, jsou vidět na konci podprogramu CIRCLE. Pro CIRCLE platí, že úhel G musí mít hodnotu 2*PI. 2420
DRW-STEPS
2425
ARC-LOOP
2439
ARC-START
DEC JR JR RST DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB PUSH RST DEFB DEFB DEFB DEFB DEFB DEFB LD CALL RST DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB LD CALL RST DEFB
B Z,#245F,ARC-END #2439,ARC-START #28,FP-CALC #E1,get-mem-1 #31,zdvojení #E3,get-mem-3 #04,násobení #E2,get-mem-2 #E4,get-mem-4 #04,násobení #03,odčítání #C1,st-mem-1 #02,výmaz #E4,get-mem-4 #04,násobení #E2,get-mem-2 #E3,get-mem-3 #04,násobení #0F,sčítání #C2,st-mem-2 #02,výmaz #38,konec výpočtu BC #28,FP-CALC #C0,st-mem-0 #02,výmaz #E1,get-mem-1 #0F,sčítání #31,zdvojení #38,konec výpočtu A,(#5C7D) {COORDS-lo} #2D28,STACK-A #28,FP-CALC #03,odčítání #E0,get-mem-0 #E2,get-mem-2 #0F,sčítání #C0,st-mem-0 #01,záměna #E0,get-mem-0 #38,konec výpočtu A,(#5C7E) {COORDS-hi} #2D28,STACK-A #28,FP-CALC #03,odčítání
B počítá průchody smyčkou. Skok, když B dosáhlo nuly. Skok na začátek smyčky. Viz. text o zásobníku. Un-1 Un-1,Un-1 Un-1,Un-1,COS (G/A) Un-1,Un-1*COS (G/A) Un-1,Un-1*COS (G/A),Vn-1 Un-1,Un-1*COS (G/A),Vn-1,SIN (G/A) Un-1,Un-1*COS (G/A),Vn-1*SIN (G/A) Un-1,Un-1*COS (G/A)-Vn-1*SIN (G/A)=Un Un do mem-1. Un-1 Un-1,SIN (G/A) Un-1*SIN (G/A) Un-1*SIN (G/A),Vn-1 Un-1*SIN (G/A),Vn-1,COS (G/A) Un-1*SIN (G/A),Vn-1*COS (G/A) Un-1*SIN (G/A)+Vn-1*COS (G/A)=Vn Vn do mem-2. Jak bylo řečeno v textu, zásobník ve skutečnosti obsahuje hodnoty X0+X,Y0+Y,Xn a Yn. Uschovej čítač oblouků. X0+X,Y0+Y,Xn,Yn Yn do mem-0. X0+X,Y0+Y,Xn X0+X,Y0+Y,Xn,Un X0+X,Y0+Y,Xn+Un (Xn+Un=Xn+1) X0+X,Y0+Y,Xn+1,Xn+1 Dále Xn' přibližná hodnota dosažená podprogramem pro rýsování přímek je uložena do registru A a uložena na zásobník. X0+X,Y0+Y,Xn+1,Xn+1,Xn' X0+X,Y0+Y,Xn+1,Xn+1-Xn'=Un' X0+X,Y0+Y,Xn+1,Un',Yn X0+X,Y0+Y,Xn+1,Un',Yn,Vn X0+X,Y0+Y,Xn+1,Un',Yn+Vn=Yn+1 Yn+1 do mem-0. X0+X,Y0+Y,Xn+1,Yn+1,Un' X0+X,Y0+Y,Xn+1,Yn+1,Un',Yn+1 Yn' je aproximováno podobně jako Xn' je okopírováno do A a uloženo na zásobník. X0+X,Y0+Y,Xn+1,Yn+1,Un',Yn+1,Yn' X0+X,Y0+Y,Xn+1,Yn+1,Un',Vn'
Komentovaný výpis paměti ROM
131
245F
2477
ARC-END
LINE-DRAW
DEFB CALL POP DJNZ RST DEFB DEFB DEFB DEFB LD CALL RST DEFB DEFB DEFB LD CALL RST DEFB DEFB CALL JP
#38,konec výpočtu #24B7,DRAW-LINE BC #2425,ARC-LOOP #28,FP-CALC #02,výmaz #02,výmaz #01,záměna #38,konec výpočtu A,(#5C7D) {COORDS-lo} #2D28,STACK-A #28,FP-CALC #03,odčítání #01,záměna #38,konec výpočtu A,(#5C7E) {COORDS-hi} #2D28,STACK-A #28,FP-CALC #03,odčítání #38,konec výpočtu #24B7,DRAW-LINE #0D4D,TEMPS
Je narýsován další oblouk. Obnovení počítadla oblouků. Mají-li se rýsovat ještě další oblouky provede se skok. Souřadnice konce oblouku, který byl narýsován, jsou nyní vymazány ze zásobníku. Y0+Y,X0+X X-ová souřadnice posledního oblouku, řekněme Xz', je nyní okopírována na zásobník. Y0+Y,X0+X,Xz' Y0+Y,X0+X-Xz' X0+X-Xz',Y0+Y Obdrží se Y-ová souřadnice. X0+X-Xz',Y0+Y,Yz' X0+X-Xz',Y0+Y-Yz' Závěrečný oblouk je narýsován do bodu X0+X,Y0+Y, nebo uzavření kružnice. Nastav barvy.
PODPROGRAM PRO NASTAVENÍ PARAMETRŮ Tento podprogram je využíván jak příkazem CIRCLE, tak příkazem DRAW, aby jim nastavila počáteční parametry. Příkaz CIRCLE ji volá s parametry X,Y a poloměrem Z na vrcholu zásobníku, čteno zdola. Příkaz DRAW má své X,Y,SIN (G/2) a Z, (jak je definováno v DRAW ad a)), na vrcholu zásobníku. V následujícím komentáři je obsah zásobníku ukázán pouze od Z dále. Podprogram vrací v registru B počet oblouků, registr A byl již popsán v příkazech CIRCLE a DRAW, a v mem-0 až mem-5 jsou hodnoty G/A,SIN (G/2*A),0, COS (G/A),SIN (G/A) a G. Pro kružnici se musí G rovnat hodnotě 2*PI. 247D
2495 2497
132
CD-PRMS1
USE-252 DRAW-SAVE
RST DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB CALL JR AND ADD JR LD PUSH CALL RST DEFB DEFB DEFB DEFB
#28,FP-CALC #31,zdvojení #28,odmocnina #34,stk-data #32,exponent #82 #00,#00,#00,#00 #01,záměna #05,dělení #E5,get-mem-5 #01,záměna #05,dělení #2A,abs #38,konec výpočtu #2DD5,FP-TO-A C,#2495,USE-252 #FC A,#04 NC,#2497,DRAW-SAVE A,#FC AF #2D28,STACK-A #28,FP-CALC #E5,get-mem-5 #01,záměna #05,dělení #31,zdvojení
Z Z,Z Z,SQR Z Z,SQR Z,2
Z,2,SQR Z Z,2/SQR Z Z,2/SQR Z,G Z,G,2/SQR Z Z,G*SQR Z/2 Z,G'*SQR Z/2 (G'=MOD G) Z,G'*SQR Z/2 = A1 Hodnota A1 je uložena ze zásobníku do A, je-li to možno. Je-li A1 > 256, použij 252. 4*INT (A1/4) do registru A. Přičti k počtu oblouků v A čtyři. Je-li to stále méně než 256, skoč. Zde použij 252. Nyní uschovej počet oblouků. A okopíruj tuto hodnotu také na zásobník kalkulátoru. Z,A Z,A,G Z,G,A Z,G/A Z,G/A,G/A Komentovaný výpis paměti ROM
DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB POP RET
#1F,sin #C4,st-mem-4 #02,výmaz #31,zdvojení #A2,stk-polovina #04,násobení #1F,sin #C1,st-mem-1 #01,záměna #C0,st-mem-0 #02,výmaz #31,zdvojení #04,násobení #31,zdvojení #0F,sčítání #A1,stk-1 #03,odčítání #1B,negace #C3,st-mem-3 #02,výmaz #38,konec výpočtu BC
Z,G/A,SIN (G/A) SIN (G/A) do mem-4. Z,G/A Z,G/A,G/A Z,G/A,G/A,0.5 Z,G/A,G/2*A Z,G/A,SIN (G/2*A) SIN (G/2*A) do mem-1. Z,SIN (G/2*A),G/A G/A do mem-0. Z,SIN (G/2*A)=S Z,S,S Z,S*S Z,S*S,S*S Z,2*S*S Z,2*S*S,1 Z,2*S*S-1 Z,1-2*S*S=COS (G/A) COS (G/A) do mem-3. Z Obnov počet oblouků do B. Konec.
PODPROGRAM “NARÝSUJ PŘÍMKU“ Tento podprogram je volán příkazem DRAW k narýsování přímky vedoucí z bodu X0,Y0 (v COORDS) do bodu X0+X,Y0+Y, kde přírůstky X a Y jsou uloženy na vrcholu kalkulátoru. Podstatou této metody je rozmístit co možná nejvíce horizontálních nebo vertikálních kroků mezi základní rozsah diagonálních kroků, s využitím algoritmu, který rozmisťuje vertikální kroky co možná nejrovnoměrněji. 24B7
DRAW-LINE
24C4
DL-X-GE-Y
24CB
DL-LARGER
CALL LD CP JR LD PUSH XOR LD JR OR RET LD LD PUSH LD LD
#2307,STK-TO-BC A,C B NC,#24C4,DL-X-GE-Y L,C DE A E,A #24CB,DL-LARGER C Z L,B B,C DE D,#00 H,B
ABS Y do B;ABS X do C; SGN Y do D;SGN X do E. Je-li ABS X > = ABS Y, skoč dopředu. Menší jde do L a větší jde do H. Uschovej diagonální krok (+-1,+-1). Vlož vertikální krok (+-1,0) do DE a (D=SGN Y) skoč pro nastavení registru H. Jsou-li ABS X i ABS Y nulové, vrať se. Menší (zde je to ABS Y) jde do L. ABS X jde do B pro H. Uschovej diagonální krok (+-1,+-1). Vlož horizontální krok (0,+-1) do DE. Větší z ABS X,ABS Y jde do H.
Zde začíná algoritmus. Větší z ABS X a ABS Y, řekněme H, je uloženo do A a redukováno na INT (H/2). Nyní se provede H-L horizontálních nebo vertikálních kroků a L diagonálních kroků, kdy L je menší z ABS X a ABS Y, tímto způsobem: L se přičte do A; jestliže nyní je A >= H, je sníženo o H a provedou se diagonální kroky, jinak se provedou horizontální nebo vertikální kroky. Toto se opakuje H-krát (B také obsahuje H). Povšimněte si, že se též využívají zrcadlové registry HL k uschování hodnoty COORDS.
24CE
D-L-LOOP
LD RRA ADD
A,B A,L
B jde do A stejně jako do H. A začíná s hodnotou INT (H/2). L se přičte do A.
Komentovaný výpis paměti ROM
133
24D4
D-L-DIAG
24DB
D-L-HR-VT
24DF
D-L-STEP
24EC
D-L-PLOT
24F7 24F9
134
D-L-RANGE REPORT-B
JR CP JR SUB LD EXX POP PUSH JR LD PUSH EXX POP LD LD ADD LD LD INC ADD JR JR DEC LD CALL EXX LD DJNZ POP RET JR RST DEFB
C,#24D4,D-L-DIAG H C,#24DB,D-L-HR-VT H C,A BC BC #24DF,D-L-STEP C,A DE BC HL,(#5C7D) {COORDS} A,B A,H B,A A,C A A,L C,#24F7,D-L-RANGE Z,#24F9,REPORT-B A C,A #22E5,PLOT-SUB A,C #24CE,D-L-LOOP DE Z,#24EC,D-L-PLOT #08,ERROR-1 #0A
Je-li to víc než 256 provede se skok na diagonální krok. Jestliže A < H provede se skok na horizontální, nebo vertikální krok. Sniž A o H a obnov jej do C. Nyní použij zrcadlové registry. Diagonální krok do B'C'. A úschova. Skok k provedení kroku. Uschovej A (nesníženo) v C. Uschovej krátce na zásobníku. Zaměň registrové páry. Vyzvedni krok. Nyní prováděj krok, nejdříve dej COORDS do H'L'. Krok Y z B' do A. Přičti H'. Výsledek ulož do B'. Nyní bude testován na rozsah X-ový krok (Y-ový krok se otestuje v podprogramu PLOT). Přičti L' do A a proveď skok při CY=1 na další test. Z=0 a CY=0 X-ová pozice -1 je mimo rozsah. Obnov pravdivou hodnotu v A. Hodnota do C' pro rýsování. Narýsuj tento krok. Obnov hlavní registry. C jde zpět do A pro pokračování algoritmu. Skok na start smyčky po B-kroku (tedy po H-kroku). Vyčisti strojový zásobník. Konec. Z=0 a CY=1 znamená X-ová souřadnice 255, v rozsahu. Ohlaš: B-Integer out of range.
Komentovaný výpis paměti ROM
HODNOCENÍ VÝRAZŮ PODPROGRAM SCANNING Tento podprogram se používá, aby ohodnotil výsledky dalšího výrazu. Výsledek se vrací jako "poslední hodnota“ na zásobníku kalkulátoru. Pro numerické výsledky bude "poslední hodnota“ skutečné FP číslo, nicméně výsledkem hodnocení řetězců je soubor parametrů představující poslední hodnotu. První z pěti bajtů není specifikován, druhý a třetí bajt obsahují adresu začátku řetězce a čtvrtý a pátý bajt jeho délku. Bit 6 systémové proměnné FLAGS je nastaven pro číselné výsledky a je nulový pro řetězce. Jestliže se výraz skládá pouze z jediného operandu, např. A ... RND ... A$(4,3 TO 7) ..., potom "poslední hodnota“ představuje hodnotu, která se získá ohodnocením daného operandu. V případě, že výraz obsahuje jako operand funkci, např. CHR$ A, ... NOT A, ... SIN 1, je operační kód této funkce uložen na zásobníku, dokud není vypočtena poslední hodnota operandu. Potom se tato hodnota použije v příslušné operaci, aby se získala nová "poslední hodnota“. V případě, že se mají vykonat aritmetické nebo logické operace, např. A+B, ..., A*B, ..., A=B, potom se musí uschovat operační kód a poslední hodnota prvního argumentu, dokud není nalezena poslední hodnota druhého argumentu. A vskutku výpočet poslední hodnoty druhého argumentu v sobě může zahrnovat uložení posledních hodnot a operačních kódů na zásobník po dobu průběhu vlastního výpočtu. Proto lze zpracovat i složitější hierarchii operací. Například CHR$ (T+A)-26*INT ((T+A)/26+65) se bude provádět tak dlouho, až se dosáhne bodu, z kterého již lze mezivýsledky "demontovat“, a takto může být teprve získána konečná "poslední“ hodnota. Každý operační kód má přidělenou prioritu a operace s vyšší prioritou jsou vždy uskutečněny před operacemi s prioritou nižší. Podprogram začíná s registrem A obsahujícím první znak souboru a počáteční prioritou nula, která je uložena na zásobníku. 24FB
SCANNING
24FF
S-LOOP-1
RST LD PUSH LD LD CALL LD JP LD LD ADD JP
#18,GET-CHAR B,#00 BC C,A HL,#2596 #16DC,INDEXER A,C NC,#2684,S-ALPHNUM B,#00 C,(HL) HL,BC (HL)
Vyzvedni první znak. Číslo priority jde na zásobník. Hlavní bod opětovného vstupu. Hledej v tabulce funkcí, kdy kód je v registru C. Obnov kód do A. Skoč, nebyl-li kód nalezen v tabulce. Použij položku nalezenou v tabulce k vytvoření požadované adresy a skoč na tuto adresu.
Následují čtyři podprogramy, které jsou volány podprogramy pro tabulku funkcí. První z nich s názvem "SCANNING QUOTE SUBRUTINE“ ("TESTOVÁNÍ UVOZOVEK“) je použita podprogramem S-QUOTE aby zjistil, jestli každá řetězcová uvozovka má další uvozovku do páru. 250F
S-QUOTE-S
CALL INC CP JP CP JR CALL CP RET
#0074,CH-ADD+1 BC #0D Z,#1C8A,REPORT-C #22 NZ,#250F,S-QUOTE-S #0074,CH-ADD+1 #22
Ukazuj na další znak. Zvyš délku o jednu. Je to CR? (=ENTER?) Ohlaš chybu, jestliže ano. Existuje další uvozovka? Skoč zpět, jestliže ne. Ukazuj na další znak a nastav Z flag jestliže se jedná o další uvozovku. Konec.
Další podprogram, který lze nazvat: "testování dvou souřadnic“, je používán programy S-SCREEN$, S-ATTR a S-POINT, aby se zajistilo, že požadované souřadnice budou udány v náležité formě. 2522
S-2-COORD
RST CP JR CALL RST
#20,NEXT-CHAR #28 NZ,#252D,S-RPORT-C #1C79,NEXT-2NUM #18,GET-CHAR
Vyzvedni další znak. Je to závorka "("? Ohlaš chybu, jestliže ne. Souřadnice na zásobníku kalkulátoru. Vyzvedni aktuální znak.
Komentovaný výpis paměti ROM
135
252D
S-RPORT-C
CP JP
#29 NZ,#1C8A,REPORT-C
Je to závorka ")“? Ohlaš chybu, jestliže ne.
PODPROGRAM "SYNTAX-Z“ V tomto bodě je vložen podprogram SYNTAX-Z, který je z jiných částí programu volán 32 krát. A protože instrukce BIT 7,(IY+1) má oproti instrukci CALL o jeden bajt více, ušetří se na každém volání této instrukce jeden bajt. Jednoduchý test bitu 7 FLAGS nastaví Z flag na nulu při běhu programu a na jedničku při kontrole syntaxe. 2530
SYNTAX-Z
BIT RET
7,(IY+1) (FLAGS)
Testuj bit 7 FLAGS. Konec.
Další podprogram je testovací podprogram SCREEN$, který je používán z podprogramu S-SCREEN$ pro nalezení znaku na souřadnicích řádek X a sloupec Y obrazovky. Prohledává pouze znaky, na které je nastavena systémová proměnná CHARS. Poznámka: Běžně se jedná o znaky od #20 (mezera) do #7F. Uživatel však může změnou systémové proměnné CHARS testovat také další znaky (včetně uživatelské grafiky). 2535
S-SCRN$-S
254F
S-SCRN-LP
255A
S-SC-MTCH
255D
S-SC-ROWS
136
CALL LD LD ADD LD RRCA RRCA RRCA AND XOR LD LD AND XOR LD LD PUSH PUSH PUSH LD XOR JR INC JR DEC LD LD INC INC LD XOR XOR JR DJNZ POP POP POP LD SUB
#2307,STK-TO-BC HL,(#5C36) (CHARS) DE,#0100 HL,DE A,C
X do C a Y do B (kde 0<=X<23 a O<=Y<=31 dekadicky) CHARS+256 dekadicky
#E0 B E,A A,C #18 #40 D,A B,#60 BC DE HL A,(DE) (HL) Z,#255A,S-SC-MTCH A NZ,#2573,S-SCR-NXT A C,A B,#07 D HL A,(DE) (HL) C NZ,#2573,S-SCR-NXT #255D,S-SC-ROWS BC BC BC A,#80 B
Toto je nižší bajt požadované adresy obrazovky.
vytvoří v HL bázovou adresu znakového souboru. X je okopírována do A. Číslo 32 dekadicky*X mod 8+Y se formuje v A a je kopírováno do E.
X je opět okopírována do A. Nyní je opět dekadicky 64+8*INT (X/8) uloženo do D. DE nyní obsahuje požadovanou adresu na obrazovce. B spočítá 96 znaků. Uschovej počet. Uschovej ukazatel obrazovky a ukazatel na znakový soubor. Vyzvedni první bitový řádek znaku z obrazovky. Testuj s řádkem ze znakového souboru. Byla-li nalezena přímá shoda, skoč. Testuj shodu s inverzním znakem (z #FF vytvoř v A #00). Skoč, nebyla-li ani tato shoda nalezena. Obnov #FF v A. Inverzní status (#00 nebo #FF) do C. B počítá dalších 7 bitových řádků. Posuň DE na další bitový řádek (přičti 256 dekadicky). Posuň HL na další řádek (tedy na další bajt). Vyzvedni řádek z obrazovky, porovnej jej s řádkem v ROM. Přidej inverzní status a skoč, nedochází-li k celkové shodě. Skoč zpět, pokud nejsou porovnány všechny bitové řádky. Zbav se ukazatele na soubor znakových matic a ukazatele obrazovky. Závěrečný počet do BC. Kód posledního znaku +1. A nyní obsahuje požadovaný kód. Komentovaný výpis paměti ROM
2573
257D
LD RST LD JR POP LD ADD POP POP DJNZ LD JP
S-SCR-NXT
S-SCR-STO
BC,#0001 #30,BC-SPACES (DE),A #257D,S-SCR-STO HL DE,#0008 HL,DE DE BC #254F,S-SCRN-LP C,B #2AB2,STK-STO-$
Nyní bude potřeba jedno místo v pracovním prostoru. Vytvoř toto místo. Vlož do něj znak. Skoč na uložení znaku na zásobník. Obnov ukazatel na znakový soubor. Posuň jej o 8 bajtů tedy na další matici tohoto souboru. Obnov ukazatel obrazovky. Obnov čítač. Skok zpět, protože znaků je 96. Signál: prázdný řetězec. Nebyl-li znak nalezen, skoč k uložení nulového řetezce. Jinak ulož nalezený znak
Poznámka: Výstup přes STK-STO-$ je chybou, která způsobí, že nalezený výsledek je uložený dvakrát. Zde měla být instrukce RET. Poslední z těchto čtyř podprogramů je podprogram prohledávající atributy. Je volán programem S-ATTR, aby vrátil hodnotu ATTR (X,Y), udávající hodnotu atributu pro znak nacházející se na souřadnicích X,Y obrazovky. 2580
S-ATTR-S
CALL LD RRCA RRCA RRCA LD AND XOR LD LD AND XOR LD LD JP
#2307,STK-TO-BC A,C
C,A #E0 B L,A A,C #03 #58 H,A A,(HL) #2D28,STACK-A
X do C, Y do B (opět 0<=X<=23 a 0<=Y<=31 dekadicky) X je okopírováno do A a číslo 32 * (X mod 8) + Y je formováno v A a okopírováno do L. Hodnota 32 * (X mod 8) + INT (X/8) je také v C
L obsahuje nižší bajt atributové adresy. Hodnota 32*(X mod 8)+INT(X/8) je zpět okopírována do A. Hodnota INT (X/8)+#58 je formována v A a okopírována do H, které pak obsahuje vyšší bajt adresy atributu. Atributový bajt je okopírován do A a je proveden odskok a uložení daného bajtu na zásobník.
TABULKA TESTOVACÍCH FUNKCÍ Tato tabulka obsahuje 8 funkcí a 4 operátory. Zahrnuje v sobě tedy pět nových funkcí SPEKTRA a umožňuje elegantním způsobem dosahovat některých funkcí a operátorů, které již existovaly v počítači ZX-81. adresa
kód
doplněk
jméno
adresa prováděcího podprogramu
2596 2598 259A 259C 259E 25A0 25A2 25A4 25A6 25A8 25AA 25AC 25AE
22 28 2E 2B A8 A5 A7 A6 C4 AA AB A9 00
1C 4F F2 12 56 57 84 8F E6 BF C7 CE
S-QUOTE S-BRACKET S-DECIMAL S-U-PLUS S-FN S-RND S-PI S-INKEY$ S-BIN [EQU.S-DECIMAL] S-SCREEN$ S-ATTR S-POINT Koncový znak
Komentovaný výpis paměti ROM
25B3 25E8 268D 25AF 25F5 25F8 2627 2634 268D 2668 2672 267B
137
PODPROGRAM PRO VYHODNOCENÍ FUNKCÍ 25AF
S-U-PLUS
RST JP
#20,NEXT-CHAR #24FF,S-LOOP-1
Pro obyčejné plus se pouze přesuň na další znak a skoč zpět na hlavní opětovný vstup programu SCANNING.
Podprogram na prohledávání uvozovek: Tento podprogram zpracovává řetězce s uvozovkami, např. obyčejné jako "jméno", nebo složitější "téměř ""nevinná"" lež" nebo viditelně nadbytečné jako VAL$ """A""". 25B3
S-QUOTE
25BE
S-Q-AGAIN
25CB
S-Q-COPY
25D9
S-Q-PRMS
RST INC PUSH LD CALL JR CALL JR CALL JR RST POP PUSH LD INC LD INC CP JR LD INC CP JR DEC
#18,GET-CHAR HL HL BC,#0000 #250F,S-QUOTE-S NZ,#25D9,S-Q-PRMS #250F,S-QUOTE-S Z,#25BE,S-Q-AGAIN #2530,SYNTAX-Z Z,#25D9,S-Q-PRMS #30,BC-SPACES HL DE A,(HL) HL (DE),A DE #22 NZ,#25CB,S-Q-COPY A,(HL) HL #22 Z,#25CB,S-Q-COPY BC
Vyzvedni aktuální znak. Ukazuj na začátek řetězce. Uschovej počáteční adresu. Nastav délku na nulu. Volej porovnávací podprogram. Skoč,jestliže je Z = 0, což znamená: další uvozovka není Znovu volej pro třetí uvozovku. A dále pro pátou sedmou a tak dále. Testuješ-li syntax, skoč na reset bitu č. 6 FLAGS a pokračuj v prohledávání. Vytvoř místo pro řetězec a závěrečnou uvozovku. Vyzvedni ukazatel na start a ulož ukazatel na první místo. Vyzvedni znak z řetězce, posuň ukazatel na další. Okopíruj poslední znak do pracovního prostoru a posuň ukazatel na další místo. Je poslední znak uvozovka? Jestliže ne, skok na přenos další uvozovky. Je-li však další znak uvozovka, okopíruj až tu další
Jinak ukonči kopírování. Vytvoř v BC skutečnou délku.
Poznámka: Povšimněte si, že první uvozovka nebyla započítána do délky. Koncová uvozovka ale byla a proto je nyní i tato vynechána. První, třetí, pátá, ... uvozovka uvnitř řetězce byla počítána, ale druhá, čtvrtá, šestá, ... počítány nebyly.
25DB
S-STRING
POP LD RES BIT CALL JP
DE HL,#5C3B 6,(HL) 7,(HL) NZ,#2AB2,STK-STO-$ #2712,S-CONT-2
Obnov start kopírovaného řetězce. Toto je FLAGS a tento vstupní bod se používá, kdykoliv má být bit 6 FLAGS resetován a parametry řetězce uloženy na zásobník pokud se provádí řádek. Skok na pokračování prohledávání řádku.
Poznámka: Povšimněte si, že při kopírování řetězců do pracovního prostoru každý pár uvozovek uvnitř řetězce ("") byl snížen na jedny uvozovky ("). 25E8
S-BRACKET
25F5
S-FN
RST CALL CP JP RST JP JP
#20,NEXT-CHAR #24FB,SCANNING #29 NZ,#1C8A,REPORT-C #20,NEXT-CHAR #2712,S-CONT-2 #27BD,S-FN-SBRN
Při prohledávání závorek vyzvedne další znak a volá rekurzivně SCANNING. Nebyla-li nalezena správná závorka, bude ohlášena chyba. Jinak se pokračuje v prohledávání. Podprogram prohledávání funkcí.
Tento podprogram pro uživatelem definované funkce pokračuje do podprogramu prohledávání funkcí.
138
Komentovaný výpis paměti ROM
25F8
2625
S-RND
S-RND-END
CALL JR LD CALL RST DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB CALL LD LD AND JR SUB LD JR
#2530,SYNTAX-Z Z,#2625,S-RND-END BC,(#5C76) (SEED) #2D2B,STACK-BC #28,FP-CALC #A1,stk-jedna #0F,přičtení #34,stk-data #37,exponent #87 #16,(#00,#00,#00) #04,násobení #34,stk-data #80,(čtyři bajty) #41,exponent #91 #00,#00,#80,(#00) #32,n-mod-m #02,výmaz #A1,stk-jedna #03,odečtení #31,zdvojení #38,konec výpočtu #2DA2,FP-TO-BC (#5C76),BC (SEED) A,(HL) A Z,#2625,S-RND-END #10 (HL),A #2630,S-PI-END
Pokud se nekontroluje syntaxe, skoč na výpočet náhodného čísla. Vyzvedni aktuální hodnotu SEED a ulož ji na zásobník kalkulátoru. Nyní použij kalkulátoru. Poslední hodnotou je nyní SEED + 1. Ulož na zásobník číslo 75 (dekadicky).
(SEED + 1) * 75 Nyní jsou bajty expandovány, takže na zásobník jde číslo 65537.
(SEED+1)*75/65537 abys dosáhl "zbytku“ a "odpovědi“. Vymaž odpověď. Poslední hodnota je nyní zbytek - 1. Zdvoj tuto poslední hodnotu a ukonči výpočet. Užij poslední hodnotu jako nový údaj pro SEED. Vyzvedni exponent poslední hodnoty a jestliže je nulový skoč dopředu. Sniž exponent, což znamená: vyděl hodnotou 65536, aby se dosáhlo požadovaného rozsahu hodnot. Odskoč přes podprogram PI.
Podprogram "hledání PI“: nalezne výraz PI a pokud se nekontroluje syntaxe, uloží na zásobník hodnotu PI jako "poslední hodnotu“. 2627
S-PI
2630
S-PI-END
2634
S-INKEY$
CALL JR RST DEFB DEFB INC RST JP
#2530,SYNTAX-Z Z,#2630,S-PI-END #28,FP-CALC #A3,stk-pi/2 #38,konec výpočtu (HL) #20,NEXT-CHAR #26C3,S-NUMERIC
LD RST CP JP LD RES BIT JR CALL LD JR CALL JR DEC LD
BC,#105A #20,NEXT-CHAR #23 Z,#270D,S-PUSH-PO HL,#5C3B 6,(HL) 7,(HL) Z,#2665,S-INK$-EN #028E,KEY-SCAN C,#00 NZ,#2660,S-IK$-STK #031E,K-TEST NC,#2660,S-IK$-STK D E,A
Test na kontrolu syntaxe. Skoč, jestliže kontroluješ syntaxi. Nyní použij kalkulátor. PI/2 je uloženo na zás. kalk. jako "poslední hodnota“. Exponent je zvětšen, čímž se dosáhne výsledku PI. Přesun na další znak. Skok dopředu. Priorita #10 operační kód #5A pro podprogram READ-IN. Je-li další znak křížek, skoč, neboť bude následovat číselný argument. Toto je FLAGS. Resetuj bit 6 pro řetězcový výsledek a testuj bit 7 na kontrolu syntaxe. Skoč, je-li to potřeba. Vyzvedni hodnotu klávesy do DE. Připrav prázdný řetězec a vlož jej na zásobník, bylo-li stisknuto více kláves. Testuj hodnotu klávesy a ulož hodnoty prázdného řetězce, jestliže hodnoty kláves nevyhovují. #FF do D pro L mod (set bit 3). Hodnota klávesy do registru E pro dekódování.
Komentovaný výpis paměti ROM
139
CALL PUSH LD RST POP LD LD LD CALL JP
#0333,K-DECODE AF BC,#0001 #30,BC-SPACES AF (DE),A C,#01 B,#00 #2AB2,STK-STO-$ #2712,S-CONT-2
Dekóduj hodnotu klávesy. Uschovej hodnotu ASCII. Je potřeba jedno místo v pracovním prostoru. Vytvoř toto místo. Obnov hodnotu ASCII. Připrav jeho uschování na zásobník jakožto řetězce. Jeho délka je 1. Dokonči parametr délky a ulož požadovaný řetězec. Skoč dopředu.
2660
S-IK$-STK
2665
S-INK$-EN
2668
S-SCREEN$
CALL CALL RST JP
#2522,S-2-COORD NZ,#2535,S-SCRN$-S #20,NEXT-CHAR #25DB,S-STRING
Testuj, zda byly udány 2 souřadnice. Pokud nekontroluješ syntaxi, volej podprogram. Vyzvedni další znak a skoč zpět.
2672
S-ATTR
CALL CALL RST JR
#2522,5-2-COORD NZ,#2580,S-ATTR-S #20,NEXT-CHAR #26C3,S-NUMERIC
Testuj, zda byly udány 2 souřadnice. Pokud nekontroluješ syntaxi, volej podprogram. Vyzvedni další znak a skoč zpět.
267B
S-POINT
CALL CALL RST JR
#2522,S-2-COORD NZ,#22CB,POINT-SUB #20,NEXT-CHAR #26C3,S-NUMERIC
Testuj, zda byly udány 2 souřadnice. Pokud nekontroluješ syntaxi, volej podprogram. Vyzvedni další znak a skoč zpět.
2684
S-ALPHNUM
CALL JR CP JR
#2C88,ALPHANUM NC,#26DF,S-NEGATE #41 NC,#26C9,S-LETTER
Je znak alfanumerický ? Skoč, jestliže ne. Nyní skoč, je-li to písmeno, jinak pokračuj do S-DECIMAL.
Tento podprogram zpracovává číselné výrazy začínající desetinnou čárkou nebo číslicí. Také se stará o příkaz BIN, který je zpracováván podprogramem "decimal na FP“. 268D
S-DECIMAL CALL #2530,SYNTAX-Z (EQU.S-BIN) JR NZ,#26B5,S-STK-DEC
Skoč dopředu, jestliže se provádí řádek.
Akce, která se nyní zahájí se značně odlišuje pro kontrolu syntaxe a pro běh programu. Kontroluje se syntaxe, je vypočítána FP forma a okopírována do aktuálního basicovského řádku. Provádí-li se program, bude FP vždy k dispozici, takže je okopírována na zásobník kalkulátoru aby vytvořila "poslední hodnotu“. Během kontroly syntaxe: CALL RST LD CALL INC LD INC EX LD LD AND SBC LD LDIR 140
#2C9B,DEC-TO-FP #18,GET-CHAR BC,#0006 #1655,MAKE-ROOM HL (HL),#0E HL DE,HL HL,(#5C65) (STKEND) C,#05 A HL,BC (#5C65),HL (STKEND)
Je nalezena FP forma. HL se nastaví, aby ukazoval za poslední číslici. Je potřeba 6 míst. Vytváří se prostor v basicovém řádku. HL ukazuje na první volné místo. Vloží se značka FP čísla a postoupí se na další číslo. Nyní bude ukazatel potřeba v DE. Vyzvedni STKEND. Jedná se o 5 bajtů, které budou přeneseny. Vyčisti CY flag. Nový STKEND = starý STKEND - 5. Přenes FP číslo ze zásobníku kalkulátoru do basicového řádku. Komentovaný výpis paměti ROM
EX DEC CALL JR
DE,HL HL #0077,TEMP-PTR1 #26C3,S-NUMERIC
Obnov ukazatel v HL a ukazuj na poslední přidaný bajt. Tento podprogram nastaví CH-ADD. Skoč dopředu.
Za chodu programu: 26B5 26B6
S-STK-DEC S-SD-SKIP
RST INC LD CP JR INC CALL LD
#18,GET-CHAR HL A,(HL) #0E NZ,#26B6,S-SD-SKIP HL #33B4,STACK-NUM (#5C5D),HL (CH-ADD)
Vyzvedni aktuální znak. Nyní se přesuň na další znak, dokud není nalezena značka pro FP číslo. Ukazuj na 1. bajt čísla a přenes toto číslo na zásobník. Nastav CH-ADD.
Číselný výsledek musí být identifikován, když přichází z RND, PI, ATTR, POINT nebo dekadického čísla, nastavením bitu 6 ve FLAGS. 26C3
S-NUMERIC
SET JR
6,(IY+1) (FLAGS) #26DD,S-CONT-1
Nastav signál: numerická hodnota. Skoč dopředu.
PODPROGRAM HODNOCENÍ PROMĚNNÝCH Po identifikaci názvu proměnné a zavolání LOOK-VARS, kde byla zjištěna existence proměnné v oblasti proměnných nebo programové oblasti (DEF FN pro uživatelem definované funkce FN), uloží se nalezená číselná hodnota na zásobník kalkulátoru pomocí podprogramu STACK-NUM. Řetězcové pole však musí být předáno na zásobník podprogramem STK-VAR, nebo při uživatelem definované funkci podprogramem STK-F-ARG (který je volán z podprogramu LOOK-VARS). 26C9
S-LETTER
26DD
S-CONT-1
CALL JP CALL LD CP JR INC CALL JR
#28B2,LOOK-VARS C,#1C2E,REPORT-2 Z,#2996,STK-VAR A,(#5C3B) (FLAGS) #C0 C,#26DD,S-CONT-1 HL #33B4,STACK-NUM #2712,S-CONT-2
V případě, že proměnná neexistuje, vypiš chybové hlášení. Jinak ulož par. řet. a vrať adresu číselného elementu. Vyzvedni FLAGS. Testuj bit 6 a 7 současně. Jeden nebo oba jsou vynulovány. Číselná hodnota musí být uložena na zásobník. Přenes tam číslo. Skoč dopředu.
Znak je testován na kód pro "-", čímž se identifikuje "unární mínus“. Před provedením testu je registr B nastaven na prioritu #09 a registr C na hodnotu #D8, což je kód této operace. 26DF
S-NEGATE
LD CP JR
BC,#09DB #2D Z,#270D,S-PUSH-PO
Priorita #09, operační kód #D8. Je to "-" ? Skoč dopředu, když ano.
Nyní se testuje znak na kód "VAL$“ s prioritou #10 a operačním kódem #18. LD CP JR
BC,#1018 #AE Z,#270D,S-PUSH-PO
Priorita #10, operační kód #18. Je to VAL$ ? Skoč dopředu je-li to VAL$.
Aktuální znak musí nyní představovat některou z funkcí CODE až NOT s kódem #AF až #C3. SUB JP
#AF C,#1C8A,REPORT-C
Rozsah funkcí je změněn a #AF až #C3 na #00 až #14. Ohlaš chybu, jsou-li mimo rozsah.
Komentovaný výpis paměti ROM
141
Funkce NOT je identifikována a zpracována odděleně od ostatních. LD CP JR JP
BC,#04F0 #14 Z,#270D,S-PUSH-PO NC,#1C8A,REPORT-C
Priorita #04, operační kód #F0. Je to funkce NOT? Skoč, jestliže ano. Znovu testuj rozsah.
Zbývající funkce mají prioritu 16. Operační kódy pro tyto funkce jsou nyní vypočítány. Funkce, které operují na řetězcích potřebují mít bit 6 nulový a funkce, které vracejí řetězcové výsledky potřebují mít bit 7 nulový ve svých operačních kódech.
2707
S-NO-TO-$
LD ADD LD CP JR RES CP JR RES
B,#10 A,#DC C,A #DF NC,#2707,S-NO-TO-$ 6,C #EE C,#270D,S-PUSH-PO 7,C
Priorita 16. Funkční rozsah je nyní #DC až #EF. Převeď operační kód do C. Odděl CODE, VAL a LEN, které operují na řetězcích pro dosažení numerických hodnot. Odděl STR$ a CHR$, které operují na číslech a dávají řetězcové výsledky. Poznač operační kód. Ostatní operační kódy mají bit 7 a 6 = 1.
Prioritní a operační kódy pro funkci, která se právě posuzuje, jsou nyní uloženy na strojový zásobník, kde se vytváří určitá posloupnost těchto operací. 270D
S-PUSH-PO
PUSH BC RST #20,NEXT-CHAR JP #24FF,S-LOOP-1
Ulož na zásobník prioritní a operační kód než se posuneš na posouzení další části výrazu.
Zde pokračuje hodnocení řádku. Aktuální argument může být následován "(", binárním operátorem, nebo je-li to konec výrazu, pak znakem CR, oddělovačem nebo THEN. 2712 2713
S-CONT-2 S-CONT-3
RST CP JR
#18,GET-CHAR #28 NZ,#2723,S-OPERTR
Vyzvedni aktuální znak a skoč, není-li to "(", která indikuje výraz se závorkami.
Jestliže je poslední hodnota číselná, potom výraz v závorkách je pravdivým podvýrazem a musí být ohodnocen samostatně. Je-li však poslední hodnota řetězec, potom výraz v závorkách představuje element pole nebo část řetězce. Potom zavoláním podprogramu SLICING je tento výraz upraven tak jak je potřeba. BIT JR CALL RST JR
6,(IY+1) (FLAGS) NZ,#2734,S-LOOP #2A52,SLICING #20,NEXT-CHAR #2713,S-CONT-3
Skoč dopředu, když obsluhuješ číselný výraz v závorkách. Modifikuj parametry "poslední hodnoty“. Přesuň se k posouzení dalšího znaku.
Jestliže aktuální znak je skutečně binární operátor, bude mít operační kód v rozsahu #C3 až #CF a příslušný kód priority. 2723
142
S-OPERTR
LD LD LD CALL JR LD LD
B,#00 C,A HL,#2795 #16DC,INDEXER NC,#2734,S-LOOP C,(HL) HL,#26ED
Původní kód do BC pro hledání v tabulce operátorů. Ukazatel na tabulku. Hledej v tabulce. Skoč dopředu, nebyla-li operace nalezena. Vyzvedni příslušný kód z tabulky. Ukazatel na tabulku priorit: #26ED+#C3=#27B0 je první adresa. Komentovaný výpis paměti ROM
ADD LD
HL,BC B,(HL)
Hledej v tabulce. Vyzvedni příslušnou prioritu.
Nyní se vstupuje do hlavní smyčky tohoto programu. V této fázi již je: a) Poslední hodnota na zásobníku kalkulátoru. b) Počáteční prioritní znak na zásobníku pod "hromadou“ funkcí a binárních operačních kódů neznámé velikosti. Ovšem tato "hromada“ může být též nulová. c) BC obsahuje aktuální operaci a prioritu, která při dosažení konce bude mít hodnotu nula. Konečně jsou ze zásobníku sejmuty poslední hodnoty a porovnány oproti aktuální operaci a prioritě. Jestliže aktuální priorita je vyšší než poslední priorita, potom se provede výstup ze smyčky, protože aktuální priorita je považována za vyšší než priorita operace poslední. Takže je-li aktuální priorita považována za nižší, potom je provedena tato poslední operace. Aktuální operace a priorita jde zpátky na zásobník, aby mohla být dále zpracována smyčkou. Tímto způsobem se hierarchie funkcí a binárních operací, které čekají v jakési frontě, zpracovává ve správném pořadí. 2734
S-LOOP
POP LD CP JR AND JP
DE A,D B C,#2773,S-TIGHTER A Z,#0018,GET-CHAR
Vyzvedni poslední operaci a její prioritu. Priorita jde do registru A. Porovnej "poslední“ oproti "aktuálnímu“. Výstup na čekání na argument. Jsou obě priority nulové? Jestliže ano výstup přes GET-CHAR, čímž se "poslední hodnota“ stane výslednou.
Než je provedena poslední operace, je funkce USR rozdělena na "USR číslo“ nebo "USR řetězec“ podle logické hodnoty bitu 6 FLAGS, nastaveného již dříve při ukládání argumentu funkce USR jako "poslední hodnoty“.
274C
S-STK-LST
PUSH LD LD CP JR BIT JR LD PUSH CALL JR LD AND LD RST DEFB DEFB JR
BC HL,#5C3B A,E #ED NZ,#274C,S-STK-LST 6,(HL) NZ,#274C,S-STK-LST E, #99 DE #2530,SYNTAX-Z Z,#275B,S-SYNTEST A,E #3F B,A #28,FP-CALC #3B,FP-calc-2 #38,Konec výpočtu #2764,S-RUNTEST
Ulož aktuální hodnotu na zásobník. Toto je FLAGS. Poslední operace se testuje na kód pro USR, dá USR číslo, nebylo-li modifikováno. Skoč, nebylo-li to USR. Testuj bit 6 FLAGS. Skoč, byl-li nastaven (USR číslo). Změň poslední kód: doplněk #19+#80 pro řetězec či číslo Ulož přechodně poslední hodnoty a nedělej nic, kontroluješ-li syntax. Poslední oper.kód. Vymaž bity 6 a 7, aby se převedlo op.kód na kalkulátorový doplněk. Užij kalkulátor. Proveď aktuální operaci. Konec. Skoč dopředu.
Důležitou částí kontroly syntaxe je též testování operace aby se zajistilo, že povaha poslední hodnoty je správného typu pro posuzovanou operaci. 275B
S-SYNTEST
2761
S-RPORT-C
LD XOR AND JP
A,E (IY+1) (FLAGS) #40 NZ,#1C8A,REPORT-C
Vyzvedni poslední operační kód. Testuj typ poslední hodnoty oproti požadavkům na funkci. Aby byla syntaxe správná, musí se shodovat. Skoč, jestliže syntaxe selhala.
Komentovaný výpis paměti ROM
143
Před návratem projdi smyčkou, aby se povaha poslední hodnoty zaznamenala do systémové proměnné FLAGS. 2764
S-RUNTEST
2770
S-LOOPEND
POP LD SET BIT JR RES POP JR
DE HL,#5C3B 6,(HL) 7,E NZ,#2770,S-LOOPEND 6,(HL) BC #2734,S-LOOP
Vyzvedni poslední operační kód. Toto je FLAGS. Předpokládej, že výsledek je číselný. Je-li povaha poslední hodnoty číselná, skoč dopředu. Je to řetězec. Vyzvedni aktuální hodnotu do BC a Skoč zpět.
Kdykoliv je "aktuální“ operace“ s vyšší prioritou, potom poslední a aktuální hodnoty jdou zpátky na zásobník. Nicméně, když aktuální operace pracuje s řetězci, je operační kód modifikován aby se signalizoval tento požadavek. 2773
S-TIGHTER
2788
S-NOT-AND
2790
S-NEXT
PUSH LD BIT JR AND ADD LD CP JR SET JR JR CP JR SET PUSH RST JP
DE A,C 6,(IY+1) (FLAGS) NZ,#2790,S-NEXT #3F A,#08 C,A #10 NZ,#2788,S-NOT-AND 6,C #2790,S-NEXT C,#2761,S-RPORT-C #17 Z,#2790,S-NEXT 7,C BC #20,NEXT-CHAR #24FF,S-LOOP-1
Poslední hodnoty jdou na zásobník. Vyzvedni aktuální operační kód. Jedná-li se o číselný operand, neupravuj tento kód. Nuluj bit 6 a 7. Zvyš kód o #08 a vrať ho v registru C. Je to operace AND? Skoč, jestliže ne. AND vyžaduje číselný operand. Skoč dopředu. Operace -,*,/,^,OR nelze provádět mezi řetězci. Jedná se o "+“? Skoč, jestliže ano. Další operace produkují číselný výsledek. Aktuální hodnoty jdou na zásobník. Posuzuj další znak a skoč zpět do smyčky.
TABULKA OPERÁTORŮ lokace 2795 2797 2799 279B 279D 279F 27A1
kód op.kód operátor 2B CF + 2D C3 2A C4 * 2F C5 / 5E C6 ^ 3D CE = 3E CC >
lokace kód op.kód operátor 27A3 3C CD < 27A5 C7 C9 <= 27A7 C8 CA >= 27A9 C9 CB <> 27AB C5 C7 OR 27AD C6 C8 AND 27AF 00 koncový znak
TABULKA PRIORIT lokace 27B0 27B1 27B2 27B3 27B4 27B5 27B6 144
priorita 06 08 08 0A 02 03 05
operátor * / ^ OR AND <=
lokace 27B7 27B8 27B9 27BA 27BB 27BC
priorita 05 05 05 05 05 06
operátor >= <> > < = +
Komentovaný výpis paměti ROM
PODPROGRAM HODNOCENÍ FUNKCÍ Tento podprogram je volán z podprogramu "vyhodnocení FN“, aby vyhodnotila funkce definované uživatelem v basicovém řádku. Podprogram lze rozdělit na čtyři části : a) Kontrola syntaxe příkazu FN během kontroly syntaxe. b) Při běhu programu se provede hledání příkazu DEF FN v programové oblasti a porovnávají se jména funkcí dokud se nenalezne shoda. Jinak je ohlášena chyba. c) Jsou ohodnoceny argumenty funkce voláním podprogramu SCANNING. d) Je ohodnocena samotná funkce (SCANNINGem, který zase volá LOOK-VARS a tím i "SF-ARGMTS“). 27BD
S-FN-SBRN
27D0
SF-BRKT-1
27D9
SF-ARGMTS
27E4 27E6 27E9
SF-BRKT-2 SF-RPRT-C SF-FLAG-6
27F4
SF-SYN-EN
CALL JR RST CALL JP RST CP PUSH JR RST CP JR RST CP JR CALL RST CP JR RST JR CP JP RST LD RES POP JR SET JP
#2530,SYNTAX-Z NZ,#27F7,SF-RUN #20,NEXT-CHAR #2C8D,ALPHA NC,#1C8A,REPORT-C #20,NEXT-CHAR #24 AF NZ,#27D0,SF-BRKT-1 #20,NEXT-CHAR #28 NZ,#27E6,SF-RPRT-C #20,NEXT-CHAR #29 Z,#27E9,SF-FLAG-6 #24FB,SCANNING #18,GET-CHAR #2C NZ,#27E4,SF-BRKT-2 #20,NEXT-CHAR #27D9,SF-ARGMTS #29 NZ,#1C8A,REPORT-C #20,NEXT-CHAR HL,#5C3B 6,(HL) AF Z,#27F4,SF-SYN-EN 6,(HL) #2712,S-CONT-2
Pokud se nekontroluje syntaxe, skoč na SF-RUN. Vyzvedni první znak názvu. Není-li alfanumerický, ohlaš chybu. Vyzvedni další znak. Je to "$“ ? Uschovej Z flag na zásobník a skoč, nebyl-li to "$“. Jinak vyzvedni další znak. Nejedná se o závorku ohlaš chybu. Vyzvedni další znak. Je to závorka ")“ ? Skoč jestliže ano, neboť nejsou žádné argumenty. Volej SCANNING, který kontroluje syntax arg. a vloží FP. Vyzvedni znak, který následuje za argumentem. Není-li to čárka ",“, skoč, neboť nejsou žádné argumenty. První znak dalšího argumentu. Zpátky do smyčky k prozkoumání dalšího argumentu. Je současný znak závorka ")“ ? Ohlaš chybu, není-li to závorka ")“. Ukazuj na další znak v basicovém řádku. Toto je FLAGS. Předpokládá se řetězcová funkce. Obnov Z flag a skoč je-li výsledek funkce řetězcového typu. Jinak nastav bit 6 ve FLAGS. Skoč zpět při vyhodnocování řádku.
ad b) Při běhu programu se musí najít příslušný příkaz DEF FN. 27F7
SF-RUN
2802
SF-ARGMT-1
RST AND LD RST SUB LD JR RST RST PUSH
#20,NEXT-CHAR #DF B,A #20,NEXT-CHAR #24 C,A NZ,#2802,SF-ARGMT-1 #20,NEXT-CHAR #20,NEXT-CHAR HL
Vyzvedni první znak jména. Resetuj bit 5 pro velká písmena. Okopíruj jméno do B. Vyzvedni další znak. Odečti #24, což je kód pro znak "$“. Výsledek ulož do C (nula pro řetězce, jinak číselná fce). Skoč, jedná-li se o číselnou funkci. Vyzvedni další znak. Je to závorka "(". Vezmi první znak prvního argumentu. Uschovej ukazatel na zásobník a
Komentovaný výpis paměti ROM
145
2808
SF-FND-DF
2812
REPORT-P
LD DEC LD PUSH CALL POP JR RST DEFB
HL,(#5C53) (PROG) HL DE,#00CE BC #1D86,LOOK-PROG BC NC,#2814,SF-CP-DEF #08,ERROR-1 #18
ukazuj na začátek programu Zpět o jedno místo. Hledat se bude DEF FN. Uschovej název a řetězcový statut. Nyní prohledávej program. Obnov název a řetězcový statut. Skoč, byl-li příkaz DEF FN nalezen. Jinak ohlaš: P-FN without DEF
Po nalezení příkazu DEF FN je testováno jméno a status obou funkcí. Neshodují-li se, pokračuje se v hledání. 2814
SF-CP-DEF
2825
SF-NOT-FD
PUSH CALL AND CP JR CALL SUB CP JR POP DEC LD PUSH CALL POP JR
HL #28AB,FN-SKPOVR #DF B NZ,#2825,SF-NOT-FD #28AB,FN-SKPOVR #24 C Z,#2831,SF-VALUES HL HL DE,#0200 BC #198B,EACH-STMT BC #2808,SF-FND-DF
Má-li se hledat dál, uschovej ukazatel na znak DEF FN. Vyzvedni název funkce DEF FN. Resetuj bit 5 pro velká písmena. Shoduje se název pro hledanou FN? Skoč, jestliže ne. Vyzvedni další znak v příkazu DEF FN. Odečti #24 což je znak "$“. Porovnej status funkce. Při kompletní shodě skoč. Obnov ukazatel na DEF FN. Krok zpět. Připrav se na další prohledávání a k nalezení konce příkazu použij porovnávací podprogram. Mezitím bylo uloženo jméno a status. Skoč zpět na další hledání.
ad c) Nyní je nalezen správný příkaz DEF FN. Argumenty příkazu FN budou ohodnoceny opakovaným voláním SCANNINGu a 5 bajtů jejich hodnoty (nebo parametry pro řetězce) budou uloženy do příkazu DEF FN, do míst vytvořených při kontrole syntaxe. HL bude použit jako ukazatel na příkaz DEF FN (v případě volání podprogramu FN-SKPOVR), zatímco CH-ADD ukazuje na příkaz FN (a volá si RST #20 v případě potřeby). 2831
SF-VALUES
2843
SF-ARG-LP
2852
146
SF-ARG-VL
AND CALL POP POP LD CALL PUSH CP JR INC LD CP LD JR DEC CALL INC LD INC PUSH PUSH CALL
A Z,#28AB,FN-SKPOVR DE DE (#5C5D),DE (CH-ADD) #28AB,FN-SKPOVR HL #29 Z,#2885,SF-R-BR-2 HL A,(HL) #0E D,#40 Z,#2852,SF-ARG-VL HL #28AB,FN-SKPOVR HL D,#00 HL HL DE #24FB,SCANNING
Ukazuje-li HL na znak "$“, přesuň se na znak "(". Odhoď ukazatel na DEF FN. Vyzvedni ukazatel na první argument FN a okopíruj ho do CH-ADD. Přeskoč "(", uschovej tento ukazatel na zásobník. Ukazuje na závorku? Jestliže ano, skoč, protože funkce nemá argumenty. Ukazuj na další kód a dej ho do A. Je to značka pro FP číslo? Nastav bit 6 v registru D pro numerický argument. Skoč, jednalo-li se o numer.argument. HL bude ukazovat na znak "$“ a ne na řídící kód. HL nyní ukazuje na značku FP čísla. Bit 6 je vynulován, signál: řetězec. Ukazuj na první z pěti bajtů v DEF FN. Uschovej tento ukazatel na zásobník. Uschovej "řetězcový status“ argumentu. Ohodnoť argument. Komentovaný výpis paměti ROM
2885
SF-R-BR-2
288B
REPORT-Q
POP XOR AND JR POP EX LD LD SBC LD LDIR EX DEC CALL CP JR PUSH RST CP JR RST POP CALL JR PUSH RST CP JR RST DEFB
AF (IY+1) (FLAGS) #40 NZ,#288B,REPORT-Q HL DE,HL HL,(#5C65) (STKEND) BC,#0005 HL,BC (#5C65),HL (STKEND) DE,HL HL #28AB,FN-SKPOVR #29 Z,#2885,SF-R-BR-2 HL #18,GET-CHAR #2C NZ,#288B,REPORT-Q #20,NEXT-CHAR HL #28AB,FN-SKPOVR #2843,SF-ARG-LP HL #18,GET-CHAR #29 Z,#288D,SF-VALUE #08,ERROR-1 #19
Dej vlajku "číslo/řetězec“ do A. Testuj bit 6 oproti výsledku ze SCANNINGu a vypiš hlášení Q jestliže se neshodují. Vyzvedni ukazatel na první z pěti bajtů v DEF FN a dej ho do DE. HL nechť ukazuje na STKEND. BC je použito jako počítadlo 5 bajtů které se přenesou. Zmenši STKEND o 5 a tak vymaž poslední hodnotu ze zásobníku. Okopíruj pět bajtů do míst v DEF FN. HL ukazuje na další kód. Zajisti, aby HL ukazovalo na znak nad pěti bajty. Je to závorka ")“? Skoč jestliže ano, neboť nejsou další argumenty pro DEFFN Je to čárka ",“, uschovej tedy její ukazatel. Vyzvedni znak za posledním argumentem příkazu FN. Není-li to čárka, skoč, neboť jsou to popletené argumenty pro FN a DEF FN. Posuň CH-ADD na další argument FN. Vyzvedni ukazatel na ",“ v příkazu DEF FN. Posuň HL na další argument v DEF FN. Skoč zpět k posouzení tohoto argumentu. Uschovej ukazatel na závorku ")“ v DEF FN. Vyzvedni znak po posledním argumentu v FN. Je to závorka ")“ ? Jestliže ano, skoč k ohodnocení funkce, jinak ohlaš: Q-Parameter error
d) Konečně je funkce sama ohodnocena voláním SCANNING, když předtím DEFADD obsahovala adresu argumentů tak, jak se vyskytovaly v příkazu DEF FN. Tím je zajištěno, že při zavolání SCANNINGu LOOKVARS budou prohledány nejprve tyto argumenty a pak teprve proměnné. 288D
SF-VALUE
POP EX LD LD EX LD PUSH RST RST CALL POP LD POP LD RST JP
DE DE,HL (#5C5D),HL (CH-ADD) HL,(#5C0B) (DEFADD) (SP),HL (#5C0B),HL (DEFADD) DE #20,NEXT-CHAR #20,NEXT-CHAR #24FB,SCANNING HL (#5C5D),HL (CH-ADD) HL (#5C0B),HL (DEFADD) #20,NEXT-CHAR #2712,S-CONT-2
Obnov ukazatel na ")“ v DEF FN. Dej tento ukazatel do HL a uschovej ho v CH-ADD. Vyzvedni starou hodnotu DEFADD. Ulož ji na zásobník a současně vyzvedni adresu DEF FN a ulož ji do DEFADD. Uschovej adresu ")“ v příkazu FN. Posuň CH-ADD na poslední ")“ a "=“ na začátku výrazu pro DEF FN. Nyní ohodnoť funkci. Obnov adresu závorky v příkazu FN a uschovej ji v CH-ADD. Obnov původní hodnotu DEFADD a ulož ji zpět. Vyzvedni další znak v basicovém řádku. Skoč zpět do SCANNINGu.
PODPROGRAM "FN-SKPOVR“ (SKOKY VE FUNKCI) Tento podprogram se používá z podprogramů FN a STK-F-ARG aby posouval HL po příkazu DEF FN, aniž by byla CH-ADD změněna, neboť tato ukazuje na příkaz FN. 28AB
FN-SKPOVR
INC
HL
Ukazuj na další kód v příkazu.
Komentovaný výpis paměti ROM
147
LD CP JR RET
A,(HL) #21 C,#28AB,FN-SKPOVR
Dej ho do A a je-li to řídící znak nebo mezera, přeskoč ho. Jinak se vrať.
PODPROGRAM "PROHLEDEJ PROMĚNNÉ“ Tento podprogram se volá kdykoliv je potřeba prohledávat oblast proměnných, nebo argumentů DEF FN, jak je třeba. Vstupuje se do ní se systémovou proměnnou CH-ADD nastavenou na první písmeno názvu proměnné, jejíž umístění se hledá. Jméno se bude nacházet v programové nebo pracovní oblasti. Nejprve bude v registru C vytvořen označovací bajt jehož povaha je založena na prvním písmenu názvu proměnné. Bity 5 a 6 tohoto bajtu indikují typ použité proměnné. Registr B je používán jako bitová vlajka (flag). 28B2
LOOK-VARS
SET RST CALL JP PUSH AND LD RST PUSH CP JR SET CP JR SET CALL JR
6,(IY+1) (FLAGS) #18,GET-CHAR #2C8D,ALPHA NC,#1C8A,REPORT-C HL #1F C,A #20,NEXT-CHAR HL #28 Z,#28EF,V-RUN/SYN 6,C #24 Z,#28DE,V-STR-VAR 5,C #2C88,ALPHANUM NC,#28E3,V-TEST-FN
Předpokládej číselnou proměnnou. Vyzvedni první znak do A. Je alfanumerický ? Ohlaš chybu jestliže ne. Uschovej ukazatel na první znak. Převeď bity 0-4 do registru C. Bity 5-7 jsou vždy nulové. Vyzvedni další znak do A. Uschovej jeho ukazatel. Je druhým znakem závorka "(" ? Odděl pole a čísla. Nyní nastav bit 6. Je druhým znakem "$“ ? Odděl všechny řetězce. Nyní nastav bit 5. Jestliže délka názvu proměnné je pouze jeden znak, skoč dopředu.
Nyní bude nalezen koncový znak názvů majících více než jeden znak. 28D4
V-CHAR
CALL JR RES RST JR
#2C88,ALPHANUM NC,#28EF,V-RUN/SYN 6,C #20,NEXT-CHAR #28D4,V-CHAR
Je znak alfanumer.? Vyskoč ze smyčky jestliže byl nalezen konec názvu. Označ rozlišovací bajt. Vyzvedni další znak. Jdi zpět a testuj jej.
Obyčejné řetězce a řetězcová pole vyžadují, aby bit 6 systémové proměnné FLAGS byl vynulován. 28DE
V-STR-VAR
RST RES
#20,NEXT-CHAR 6,(IY+1) (FLAGS)
Posuň CH-ADD za značku "$“. Nuluj bit 6 jako signál:řetězec.
Není-li DEFADD-HI nula, znamená to, že se bude zpracovávat fce ("FN“), je-li však program v běhu, budou se hledat argumenty příkazu DEF FN. 28E3
V-TEST-FN
LD AND JR CALL JP
A,(#5C0C) (DEFADD-HI) A Z,#28EF,V-RUN/SYN #2530,SYNTAX-Z NZ,#2951,STK-F-ARG
Je DEFADD-HI nula? Jestliže ano, skoč dopředu. Je program v běhu? Jestliže ano, skoč dopředu k prohledání příkazu DEF FN.
Jinak (nebo když proměnná nebyla nalezena v příkazu DEF FN) se provede hledání v oblasti proměnných, pokud se ovšem nekontroluje syntaxe. 28EF 148
V-RUN/SYN
LD
B,C
Kopíruj rozlišovací bajt do registru B. Komentovaný výpis paměti ROM
CALL JR LD AND SET LD JR
#2530,SYNTAX-Z NZ,#28FD,V-RUN A,C #E0 7,A C,A #2934,V-SYNTAX
Je-li program v běhu, skoč dopředu. Převeď rozlišovací bajt do A. Vymaž část znakového kódu. Indikuj syntaxi nastavením bitu 7. Obnov značkový bajt a pokračuj.
Provádí se basicový řádek a proto se provede prohledání oblasti proměnných. 28FD
V-RUN
LD
HL,(#5V4B) (VARS)
Vyzvedni ukazatel VARS.
Nyní vstup do smyčky, která posoudí názvy existujících proměnných. 2900
V-EACH
LD AND JR CP JR RLA ADD JP JR
A,(HL) #7F Z,#2932,V-80-BYTE C NZ,#292A,V-NEXT A,A P,#293F,V-FOUND-2 C,#293F,V-FOUND-2
První písmeno každé existující proměnné porovnávej na bitech 0-6. Skoč při bajtu #80 (koncový znak oblasti proměnných). Vlastní porovnání. Jestliže se první znaky neshodují, skoč dopředu. Rotuj A doleva a pak je zdvoj, abys otestoval bity 5,6. Řetězcové proměnné a pole. Jednoduché číselné a "FOR NEXT“ proměnné.
Dlouhé názvy vyžadují aby byly porovnány celé.
2912 2913
V-MATCHES V-SPACES
POP PUSH PUSH INC LD INC CP JR OR CP JR OR CP JR LD CALL JR
DE DE HL HL A,(DE) DE #20 Z,#2913,V-SPACES #20 (HL) Z,#2912,V-MATCHES #80 (HL) NZ,#2929,V-GET-PTR A,(DE) #2C88,ALPHANUM NC,#293E,V-FOUND-1
Pořiď kopii ukazatele na druhý znak. Uschovej ukazatel na první znak. Posuzuj další znak. Vyzvedni postupně všechny znaky a ukazuj na další znak. Je to mezera? Ignoruj mezery. Nastav bit 5 tak, abys testoval velká i malá písmena. Jestliže se shodují, skoč zpět pro další znak. Budou se shodovat při nastaveném bitu 7 ? Zkus to. Jestliže se poslední znaky neshodují, skoč dopředu. Kontrola konce názvu před odskokem dopředu.
Ve všech případech neshody názvů se musí HL upravit tak, aby ukazoval na další proměnnou v oblasti proměnných. 2929 292A
V-GET-PTR V-NEXT
POP PUSH CALL EX POP JR
HL BC #19B8,NEXT-ONE DE,HL BC #2900,V-EACH
Vyzvedni ukazatel. Krátce uschovej B & C. Nyní DE ukazuje na další proměnnou. Zaměň oba ukazatele vyzvedni zpět B&C a skoč znovu do smyčky.
Nebyla-li nalezena žádná položka se správným názvem, skoč sem. 2932
V-80-BYTE
SET
7,B
Signál: proměnná nenalezena.
Komentovaný výpis paměti ROM
149
A při kontrole syntaxe skočíš sem. 2934
V-SYNTAX
POP RST CP JR SET JR
DE #18,GET-CHAR #28 Z,#2943,V-PASS 5,B #294B,V-END
Znič ukazatel na druhý znak. Vyzvedni aktuální znak. Je to závorka "(" ? Skoč dopředu. Signál:nejedná se o pole. Skoč dopředu.
Sem přijdeš po nalezení položky s odpovídajícím jménem. 293E 293F
V-FOUND-1 V-FOUND-2
POP POP POP PUSH RST
DE DE DE HL #18,GET-CHAR
Odhoď uschovaný ukazatel na proměnnou. Znič ukazatel na 2. znak proměnné. Znič ukazatel na 1. znak proměnné. Uschovej ukazatel na poslední znak názvu proměnné. Vyzvedni aktuální znak.
Má-li jméno proměnné více než jeden znak, musí být převedeny i další znaky. Poznámka: Zdá se však, že to už bylo uděláno v části V-CHAR. 2943
V-PASS
CALL JR RST JR
#2C88,ALPHANUM NC,#294B,V-END #20,NEXT-CHAR #2943,V-PASS
Je znak alfanumerický? Byl-li nalezen konec názvu proměnné, skoč. Vyzvedni další znak a jdi zpět na jeho test.
Nyní jsou nastaveny výstupní parametry. 294B
V-END
POP RL BIT RET
HL B 6,B
HL ukazuje na poslední znak názvu. Rotuj celý registr, otestuj jeho bit 6. Hotovo.
Výstupní parametry tohoto podprogramu mohou být shrnuty následovně: Systémová proměnná CH-ADD ukazuje na první místo za názvem proměnné v basicovém řádku. Pokud proměnná nebyla nalezena: a) CY=1 b) Z flag je nastaven jenom při hledání pole. c) Registrový pár HL ukazuje na první znak názvu proměnné tak, jak se vyskytuje v basicovém řádku. Pokud proměnná byla nalezena: a) CY=0 b) Z flag=1 jak pro jednoduché řetězcové proměnné, tak pro pole. c) Registrový pár HL ukazuje na písmeno krátkého jména, nebo na poslední znak u vícepísmenných názvů, existující položky v oblasti proměnných. Ve všech případech bity 5 a 6 registru C indikují typ zpracovávané proměnné. Bit 7 je komplementem "SYNTAX/RUN flag“. Bity 0-4 budou obsahovat kód znaku nalezené proměnné pouze tehdy, byl-li program v běhu. Pokud byl podprogram volán při kontrole syntaxe, bude se vždy vracet s CY=0. Z flag bude nastaven na 1 pro pole, nebo na 0 pro všechny proměnné kromě řetězcových názvů nesprávně následovaných závorkou "(“, což nastaví Z flag na jedna, ale v případě že se bude provádět SAVE "jméno" DATA a$(), bude se syntaxe považovat za správnou.
150
Komentovaný výpis paměti ROM
PODPROGRAM "ULOŽ ARGUMENTY FUNKCÍ NA ZÁSOBNÍK“ Podprogram je volán z LOOK-VARS když není DEFADD-hi nula, aby v oblasti argumentů byl nalezen příkaz DEF FN, před prohledáním programové oblasti. Byla-li proměnná nalezena v příkaze DEF FN, budou parametry řetězcové proměnné uloženy na zásobník a bude dán signál: nevolej STK/VAR. Ale to už zůstává na programu SCANNING, který uloží hodnoty číselné proměnné obvyklým způsobem (viz. adresa #26DA). 2951
STK-F-ARG
295A
SFA-LOOP
296B
SFA-CP-VR
LD LD CP JP LD OR LD INC LD CP JR DEC CALL INC RES LD CP JR INC INC INC INC INC CALL CP JP CALL JR
HL,(#5C0B) (DEFADD) A,(HL) #29 Z,#28EF,V-RUN/SYN A,(HL) #60 B,A HL A,(HL) #0E Z,#296B,SFA-CP-VR HL #28AB,FN-SKPOVR HL 5,B A,B C Z,#2981,SFA-MATCH HL HL HL HL HL #28AB,FN-SKPOVR #29 Z,#28EF,V-RUN/SYN #28AB,FN-SKPOVR #295A,SFA-LOOP
Ukazuj na 1.znak oblasti argumentů a převeď jej do A. Je to závorka ")“ ? Jestliže ano, skoč k prohledání oblasti proměnných. Vyzvedni další argument ve smyčce. Nastav bity 5 a 6,jako signál: obyčejná číselná proměnná. Okopíruj je do B. Ukazuj na další kód. Vyzvedni jej do A. Je to #0E (značka FP čísla) ? Jestliže ano, skoč (je to číselná proměnná). Nastav HL aby ukazovalo na značku "$“ a ne na mezeru nebo řídící znak. HL nyní ukazuje na značku FP čísla. Nuluj bit 5 v B což je signál: řetězcová proměnná. Vyzvedni název proměnné do A. Je to ta, kterou hledáme ? Jestli ano, skoč. Nyní překroč 5 bajtů FP čísla nebo parametru řetězce, aby mohl být nalezen další argument. Posuň se na další znak. Je to závorka ")“ ? Jestliže ano, skoč na prohledání oblasti proměnných. Ukazuj na další argument a skoč zpět na jeho posouzení.
Byla nalezena shoda. Parametry řetězcové proměnné jdou nyní na zásobník, čímž se předejde potřebě volání programu STK-VAR. 2981
SFA-MATCH
2991
SFA-END
BIT JR INC LD CALL EX LD POP POP XOR INC RET
5,C NZ,#2991,SFA-END HL DE,(#5C65) (STKEND) #33C0,MOVE-FP DE,HL (#5C65),HL (STKEND) DE DE A A
Jedná se o číselnou proměnnou, skoč, a SCANNING už ji uloží na zásobník. Ukazuj na 1. z pěti ukládaných bajtů. DE ukazuje na STKEND. Ulož těchto 5 bajtů. HL ukazuje na novou pozici STKEND, jejíž hodnota je uložena do STKEND. Odhoď ukazatele pro LOOK-VARS (1. a 2. znakový ukazatel). Vrať se s CY i Z flag nulovými, což je signál: nevolat STK-VAR. Hotovo.
Komentovaný výpis paměti ROM
151
PODPROGRAM STK-VAR Tento podprogram se obyčejně používá k nalezení parametrů, které definují existující řetězec v oblasti proměnných nebo vrací v HL bázovou adresu určitého elementu nebo polem. Je-li volána z DIM slouží pouze ke kontrole syntaxe basicového příkazu. Parametry definující řetězec ale mohou být pozměněny voláním programu SLICING, je-li to potřeba. 2996
STK-VAR
XOR LD BIT JR
A B,A 7,C NZ,#29E7,SV-COUNT
Nastav vlajku: pole. Vynuluj B. Skoč dopředu při kontrole syntaxe.
Dále odděl jednoduché řetězce od polí.
29A1
SV-SIMPLE$
29AE
SV-ARRAYS
BIT JR INC INC LD INC LD INC EX CALL RST JP INC INC INC LD BIT JR
7,(HL) NZ,#29AE,SV-ARRAYS A HL C,(HL) HL B,(HL) HL DE,HL #2AB2,STK-STO-$ #18,GET-CHAR #2A49,SV-SLICE? HL HL HL B,(HL) 6,C Z,#29C0,SV-PTR
Jedná-li se o pole, skoč dopředu. Signál: jednoduchý řetězec. Posuň ukazatel. Vyzvedni délku řetězce. Posuň ukazatel. Převeď ukazatel na aktuální řetězec. Předej parametry na zásobník kalkulátoru. Vyzvedni aktuální znak a skoč na test "krácení“. Posuň ukazatel za délku pole. Vyzvedni počet dimenzí. Jedná se o číselné pole skoč dopředu.
Jestliže řetězcové pole má počet dimenzí 1, lze jej považovat za obyčejný řetězec. DEC JR
B Z,#29A1,SV-SIMPLE$
Zmenši počet dimenzí a skoč, byl-li počet 1.
Dále se provede kontrola indexu. EX RST CP JR EX
DE,HL #18,GET-CHAR #28 NZ,#2A20,REPORT-3 DE,HL
Uschovej ukazatel v DE. Vyzvedni aktuální znak. Je to závorka "(" ? Skoč podat chybové hlášení, jestliže ne. Obnov ukazatel v HL.
Pro oba typy polí se nyní ohodnotí index. 29C0
SV-PTR
EX JR
DE,HL #29E7,SV-COUNT
Dej ukazatel do DE. Skoč dopředu.
Následující smyčka má za úkol nalézt parametry daného elementu pole. Do smyčky se vstupuje v bodě SV-COUNT. Smyčka se vykoná B krát, což u číselných polí odpovídá počtu použitých dimenzí. Pro řetězcová pole se smyčka vykoná B-1 krát, protože poslední index se použije ke stanovení "výřezu“ z řetězce. 29C3
152
SV-COMMA
PUSH HL RST #18,GET-CHAR POP HL
Uschovej čítač. Vyzvedni aktuální znak. Obnov čítač. Komentovaný výpis paměti ROM
CP JR BIT JR BIT JR CP JR RST RET
#2C Z,#29EA,SV-LOOP 7,C Z,#2A20,REPORT-3 6,C NZ,#29D8,SV-CLOSE #29 NZ,#2A12,SV-RPT-C #20,NEXT-CHAR
Je aktuální znak čárka ",“ ? Skoč dopředu na posouzení dalšího indexu. Při běhu programu skoč ohlásit chybu. Jedná-li se o řetězcové pole, skoč dopředu. Je aktuální znak závorka ")“ ? Skoč ohlásit chybu, jestliže ne. Vyzvedni další znak. Syntaxe je v pořádku - vrať se.
Pro řetězcové pole může již tento index znamenat "řez“, anebo je ještě dále v basicovém řádku. 29D8
SV-CLOSE
29E0
SV-CH-ADD
CP JR CP JR RST DEC LD JR
#29 Z,#2A48,SV-DIM #CC NZ,#2A12,SV-RPT-C #18,GET-CHAR HL (#5C5D),HL (CH-ADD) #2A45,SV-SLICE
Je aktuální znak závorka ")“? Jestliže ano, skoč na kontrolu dalšího indexu. Je aktuální znak TO ? Skoč ohlásit chybu, jestliže ne. Vyzvedni aktuální znak. Ukazuj na předchozí znak a nastav CH-ADD. Skoč na hodnocení "řezu“.
Zde je vstup do smyčky. 29E7 29EA
SV-COUNT SV-LOOP
29FB
SV-MULT
LD PUSH RST POP LD CP JR RST CP JR CP JR PUSH PUSH CALL EX EX CALL JR DEC
HL,#0000 HL #20,NEXT-CHAR HL A,C #C0 NZ,#29FB,SV-MULT #18,GET-CHAR #29 Z,#2A48,SV-DIM #CC Z,#29E0,SV-CH-ADD BC HL #2AEE,DE,(DE+1) (SP),HL DE,HL #2ACC,INT-EXP1 C,#2A20,REPORT-3 BC
CALL ADD POP POP DJNZ
#2AF4,GET-HL*DE HL,BC DE BC #29C3,SV-COMMA
Nastav čítač elementů na nulu. Krátce jej uschovej. Vyzvedni další znak. Obnov čítač. Vyzvedni rozlišovací bajt. Pokud nekontroluješ syntaxi, skoč vpřed. Vyzvedni aktuální znak. Je aktuální znak závorka ")“ ? Čítání elementů skončeno - skoč dopředu. Je aktuální znak TO ? Skoč zpět - jedná se o "řez“. Uschovej počet dimenzí a rozlišovací bajt. Uschovej čítač elementů. Vyzvedni velikost dimenze do DE. Čítač do HL a ukazatel na zásobník. Záměna. Ohodnoť další index. Je-li mimo rozsah, ohlaš chybu. Dekrementuj výsledek ohodnocení, protože čítač má počítat elementy vyskytující se před specifikovaným elementem. Vynásob čítač velikostí dimenze. Přičti výsledek z INT-EXP1 k aktuálnímu čítači. Vyzvedni ukazatel proměnné. Vyzvedni počet dimenzí a rozlišovací bajt. Pokračuj v průchodech smyčkou, dokud B není nula.
Než se odliší číselná a řetězcová pole, testuje se vlajka SYNTAX/RUN.
2A12
SV-RPT-C
BIT 7,C JR NZ,#2A7A,SL-RPT-C PUSH HL BIT 6,C
Jestliže syntaxi, Uschovej Jedná-li
Komentovaný výpis paměti ROM
kontroluješ skoč ohlásit chybu. čítač. se o řetězcové 153
JR
NZ,#2A2C,SV-ELEM$
pole, skoč dopředu.
Při zpracování číselného pole musí být aktuální znak závorka ")“.
2A20
REPORT-3
LD LD RST CP JR RST DEFB
B,D C,E #18,GET-CHAR #29 Z,#2A22,SV-NUMBER #08,ERROR-1 #02
Převeď ukazatel proměnné do BC. Vyzvedni aktuální znak. Je aktuální znak závorka ")“ ? Přeskoč chybové hlášení, jestliže jo. Ohlaš: 3-Subscript out of range.
Nyní může být vypočtena adresa skutečné FP formy. 2A22
SV-NUMBER
RST POP LD CALL ADD RET
#20,NEXT-CHAR HL DE,#0005 #2AF4,GET-HL*DE HL,BC
Vyzvedni další znak. Vyzvedni čítač. Číselný element má délku 5 bajtů. Vypočti celkový počet bajtů před požadovaným elementem. HL nyní ukazuje před požadovaný element. Vrať se s touto adresou.
Při zpracování řetězcového pole je velikost elementu dána hodnotou "poslední dimenze“. Jsou vypočteny příslušné parametry a předány na zásobník kalkulátoru. 2A2C
SV-ELEM$
CALL EX CALL POP ADD INC LD LD EX CALL
#2AEE,DE,(DE+1) (SP),HL #2AF4,GET-HL*DE BC HL,BC HL B,D C,E DE,HL #2AB1,STK-ST-0
Vyzvedni rozměr poslední dimenze. Ukazatel proměnné jde na zásobník a čítač do HL. Vynásob čítač velikostí dimenze. Vyzvedni ukazatel proměnné. HL nyní ukazuje na jedno místo před element. A nyní na začátek elementu. Převeď velikost poslední dimenze do BC, což bude délka. Začátek do DE. Parametry na zásobník kalkulátoru.
Poznámka: První parametr je nula, což indikuje element pole a tedy signál : nemazat existující element. Zápis indexu je možný třemi způsoby: A$(2,4 TO 8) nebo A$(2)(4 TO 8) anebo pokud se požaduje celý řetězec A$(2).
2A45 2A48 2A49
SV-SLICE SV-DIM SV-SLICE?
RST CP JR CP JR CALL RST CP JR
#18,GET-CHAR #29 Z,#2A48,SV-DIM #2C NZ,#2A20,REPORT-3 #2A52,SLICING #20,NEXT-CHAR #28 Z,#2A45,SV-SLICE
Vyzvedni aktuální znak. Je to závorka ")“ ? Skoč, jestliže ano. Je to čárka ",“ ? Skoč na ohlášení chyby, jestliže ne. Použij SLICING pro úpravu souboru parametrů. Vyzvedni další znak. Je to závorka "(“ ? Skoč zpět, je-li třeba posoudit "řez“.
Po posouzení posledního indexu se provede návrat, přičemž parametry požadovaného řetězce jsou uloženy na zásobníku kalkulátoru. RES RET
154
6,(IY+1) (FLAGS)
Signál: řetězcový výsledek. Návrat.
Komentovaný výpis paměti ROM
PODPROGRAM "SLICING“ Tento podprogram provede "řez“ z aktuálního řetězce. Na vstupu jsou parametry řetězce uloženy na zásobníku kalkulátoru a v registrech A B C D E. Parametry jsou vyzvednuty pouze při exekuci řádku. 2A52
SLICING
CALL CALL RST CP JR PUSH XOR PUSH PUSH LD RST POP
#2530,SYNTAX-Z NZ,#2BF1,STK-FETCH #20,NEXT-CHAR #29 Z,#2AAD,SL-STORE DE A AF BC DE,#0001 #18,GET-CHAR HL
Testuj vlajku. Při běhu programu vyzvedni parametry. Vyzvedni další znak. Je to závorka ")“ ? Skoč dopředu, jestli ano. Začátek jde na zásobník. Nuluj registr A a uschovej. Uschovej délku. Předpoklad, že "řez“ začne 1.znakem. Vyzvedni 1.znak. Délka do HL.
Nyní se ohodnotí první parametr pro řez.
2A7A
SL-RPT-C
CP JR POP CALL PUSH LD LD PUSH RST POP CP JR CP JP
#CC Z,#2A81,SL-SECOND AF #2ACD,INT-EXP2 AF D,B E,C HL #18,GET-CHAR HL #CC Z,#2A81,SL-SECOND #29 NZ,#1C8A,REPORT-C
Je aktuální znak TO ? První parametr je tedy považován za 1 a skoč testovat 2. Obnov A, které je #00. 1.parametr do BC, A bude #FF, byla-li chyba v rozsahu. Uschovej tuto hodnotu. Převeď 1.parametr do DE. Uschovej délku. Vyzvedni aktuální znak. Obnov délku. Je aktuální znak TO ? Skoč na test 2.parametru. Je to závorka ")“ ? Skoč ohlásit chybu, jestliže ne.
V tomto bodě již byl identifikován řez o délce jednoho znaku. Například A$(4). LD LD JR
H,D L,E #2A94,SL-DEFINE
Poslední znak řezu je tedy také prvním znakem. Skoč dopředu.
Zde se hodnotí druhý parametr. 2A81
SL-SECOND
PUSH RST POP CP JR POP CALL PUSH RST LD LD CP JR
HL #20,NEXT-CHAR HL #29 Z,#2A94,SL-DEFINE AF #2ACD,INT-EXP2 AF #18,GET-CHAR H,B L,C #29 NZ,#2A7A,SL-RPT-C
Uschovej délku. Vyzvedni další znak. Obnov délku. Je to závorka ")“ ? Skoč, jestliže není druhý parametr. Jestliže 1.parametr byl v rozsahu, A je #00, jinak #FF. BC obsahuje 2.parametr. Uschovej "chybový registr“. Vyzvedni aktuální znak. Předej výsledek z INT-EXP2 do HL. Je to závorka ")“ ? Jestliže ne, skoč ohlásit chybu.
Budou definovány "nové“ parametry.
Komentovaný výpis paměti ROM
155
2A94
SL-DEFINE
2AA8
SL-OVER
2AAD
SL-STORE
POP EX ADD DEC EX AND SBC LD JR INC AND JP LD LD POP RES CALL RET
AF (SP),HL HL,DE HL (SP),HL A HL,DE BC,#0000 C,#2AA8,SL-OVER HL A M,#2A20,REPORT-3 B,H C,L DE 6,(IY+1) (FLAGS) #2530,SYNTAX-Z Z
Vyzvedni "chybový“ registr. Druhý parametr jde na zásobník a současně start je v HL. Přičti první parametr ke startu. Jdi zpět o jedno místo, aby hodnota v HL byla správná. Nový start jde na zásobník a 2.parametr zpět do HL. Odečti první parametry od druhých k nalezení délky řezu. Inicializuj novou délku. Negativní řez nezpůsobí chybu, ale nulový řetězec. Umožni jedno místo pro uzavírací bajt. Nyní testuj chybový registr. Byl-li některý parametr mimo rozsah, skoč. Převeď novou délku do BC. Vyzvedni nový start a zajisti, že se stále signalizuje řetězec. V tomto místě se vrať, jestliže kontroluješ syntaxi, jinak pokračuj do podprogramu STK-STORE.
PODPROGRAM "STK-STORE“ Tento podprogram předává hodnoty v registrech A B C D E na zásobník kalkulátoru. S každým zavoláním tohoto programu se tedy zásobník zvětší o 5 bajtů. Podprogram se normálně používá k předání řetězcových parametrů, ale je i využíván podprogramy STACK-BC a LOG (2^A) k ukládání "malých celých čísel“ na zásobník kalkulátoru. Všimněte si, že při ukládání parametrů řetězce první hodnota (přichází v registru A) bude nulová, jestliže řetězec je součástí pole nebo je řezem nějakého delšího řetězce. Pro kompletní jednoduchý řetězec bude hodnota #01. Tato vlajka se používá v příkazu LET, kde #01 signalizuje, že stará kopie má být zničena. 2AB1 2AB2 2AB6
STK-ST-0 STK-STO-$ STK-STORE
XOR RES PUSH CALL POP LD LD INC LD INC LD INC LD INC LD INC LD RET
A 6,(IY+1) (FLAGS) BC #33A9,TEST-5-SP BC HL,(#5C65) (STKEND) (HL),A HL (HL),E HL (HL),D HL (HL),C HL (HL),B HL (#5C65),HL (STKEND)
Signál: řetězec jako část pole nebo jeho řez. Zajisti, že vlajka indikuje řetězcový výsledek. Uschovej krátce BC. Je místo 5 bajtů? Nevracej se pokud není toto místo. Obnov BC. Vyzvedni adresu prvního místa nad aktuálním zásobníkem. Převeď 1.bajt. Postup. Převeď 2. a 3.bajt, což je u řetězců start.
Postup. Převeď 4. a 5.bajt, což je u řetězců délka.
Posuň ukazatel tak, aby ukazoval nad zásobník. Ulož tuto adresu do STKEND a vrať se.
PODPROGRAM "INT-EXP“ Tento podprogram vrací výsledek ohodnocení "dalšího výrazu“, jako například hodnotu integer v registrovém páru BC. Také testuje výsledek proti limitujícím hodnotám předávaným v registrovém páru HL. CY se bude rovnat 1, jestliže došlo k chybě "out of range“ (mimo rozsah). Registr A se používá jako "chybový registr“. Obsahuje #00 nedošlo-li k chybě a #FF došlo-li k chybě. 2ACC 2ACD
156
INT-EXP1 INT-EXP2
XOR A PUSH DE PUSH HL
Nuluj chybový registr. Uschovej registr DE, HL a také Komentovaný výpis paměti ROM
PUSH CALL POP CALL JR PUSH CALL POP LD OR SCF JR POP PUSH AND SBC
AF #1C82,EXPT-1NUM AF #2530,SYNTAX-Z Z,#2AEB,I-RESTORE AF #1E99,FIND-INT2 DE A,B C Z,#2AE8,I-CARRY HL HL A HL,BC
chybový registr. Hodnota dalšího výrazu je přenesena na zásobník kalk. Obnov chybový registr. Při kontrole syntaxe skoč dopředu. Uschovej opět chybový registr. Poslední hodnota je kompresována do BC. Chybový registr do D. Další výraz, který dává nulu je vždy chybový
takže je-li tomu tak, skoč. Udělej kopii limitu. Toto bude rozměr, limit pro DIM nebo délka řetězce. Nyní porovnej výsledek oproti tomuto limitu.
Stav CY a hodnota v registru D jsou nyní manipulovány tak, aby daly příslušnou hodnotu pro chybový registr. 2AE8
I-CARRY
2AEB
I-RESTORE
LD SBC POP POP RET
A,D A,#00 HL DE
PODPROGRAM DE, (DE+1) Tento podprogram provádí adresované hodnotou (DE+2). 2AEE
DE,(DE+1)
EX INC LD INC LD RET
Vyzvedni hodnotu "staré chyby“, vytvoř "novou“ chybu. #00 = nedošlo k chybě. #FF nebo méně je mimo rozsah. Obnov registry před návratem. Vrať se: chybový registr je A.
pseudoinstrukci
DE,HL HL E,(HL) HL D,(HL)
LD
DE,(DE+1)
a
vrací
HL
jako
ukazatel
na
místo
Použij HL pro konstrukci. Ukazuj na "DE+1“. Ve skutečnosti LD E,(DE+1). Ukazuj na "DE+2“. Ve skutečnosti LD D,(DE+2). Hotovo.
PODPROGRAM "GET-HL*DE“ Tento podprogram volá HL=HL*DE, pokud se nekontroluje syntaxe, čímž se dosahuje požadované funkce. Přetečení ze 16-tého bitu dává hlášení "out of memory“. Není to sice úplně pravda, ale předpokládá se, že není dost paměti pro úkol, který je uvažován. 2AF4
GET-HL*DE
CALL RET CALL JP RET
#2530,SYNTAX-Z Z #30A9,HL=HL*DE C,#1F15,REPORT-4
Při kontrole syntaxe se vrať okamžitě. Proveď násobení. Hlášení "out of memory“. Hotovo.
Komentovaný výpis paměti ROM
157
PODPROGRAM PŘÍKAZU LET Toto je skutečný podprogram přidělování, používaný příkazy LET, READ a INPUT. Jestliže cílová proměnná je nově deklarovaná proměnná, potom systémová proměnná DEST bude ukazovat na první písmeno názvu proměnné, tak jak se vyskytuje v basicovém řádku. Bit 1 systémové proměnné FLAGX bude nastaven na jedničku. Jestliže však cílová proměnná již existuje, potom bit 1 ve FLAGX bude nulový a systémová proměnná DEST bude ukazovat na místo před pěti bajty starého čísla; a pro řetězec na první místo starého řetězce. Použití systémové proměnné DEST tímto způsobem se vztahuje na jednoduché proměnné a části polí. Bit 0 systémové proměnné FLAGX je roven jedné, jestliže cílová proměnná je kompletní jednoduchá řetězcová proměnná (což je signál: smaž starou kopii). Na začátku se vyzvedne aktuální hodnota v systémové proměnné DEST a testuje se bit 1 proměnné FLAGS. 2AFF
LET
LD BIT JR
HL,(#5C4D) (DEST) 1,(IY+55) (FLAGX) Z,#2B66,L-EXISTS
Vyzvedni aktuální adresu v DEST. Obsluhuješ-li proměnnou, která již existuje, skoč.
Jde o nově deklarovanou proměnnou. Proto musí být nejdříve nalezena délka jejího názvu. LD
BC,#0005
Předpokládej, že se jedná o číselnou proměnnou-5 bajtů.
Zde je vstup do smyčky, která obslouží znaky dlouhého názvu. Jakékoliv mezery nebo barevné kódy v názvu jsou ignorována. 2B0B 2B0C
L-EACH-CH L-NO-SP
INC INC LD CP JR JR CP JR
BC HL A,(HL) #20 Z,#2B0C,L-NO-SP NC,#2B1F,L-TEST-CH #10 C,#2B29,L-SPACES
CP JR INC JR
#16 NC,#2B29,L-SPACES HL #2B0C,L-NO-SP
Přičti jedničku do čítače za znak názvu. Posuň se po názvu proměnné. Vyzvedni aktuální kód. Je-li to mezera, skoč zpět. Takto jsou ignorovány mezery. Je-li kód v rozsahu #21 až #FF, skoč dopředu. Vezmi jako výsledný kód ty, které jsou v rozsahu #00 až #0F. Také akceptuj rozsah #16 až #1F. Překroč řídící kód za jakýmkoliv znakem pro INK až OVER. Skoč zpět, protože tyto kódy jsou považována za mezery.
Odděl "číselné“ a "řetězcové“ názvy. 2B1F
L-TEST-CH
CALL JR CP JP
#2C88,ALPHANUM C,#2B0B,L-EACH-CH #24 Z,#2BC0,L-NEW$
Je znak alfanumerický? Je-li tomu tak, akceptuj ho jako kód dlouhého názvu. Je to znak "$“? Obsluhuješ-li nově deklarovaný obyčejný řetězec, skoč dopředu.
Nově deklarovaná proměnná, která byla výše zpracována, potřebuje nyní prostor o velikosti BC v oblasti proměnných pro uložení svého názvu a své hodnoty. Tento prostor se vytvoří, potom se do něj okopíruje název proměnné, přičemž znaky tohoto názvu jsou už označeny tak, jak je potřeba. 2B29
L-SPACES
LD LD DEC CALL
A,C HL,(#5C59) (E-LINE) HL #1655,MAKE-ROOM
Okopíruj délku do A. Nastav HL tak, aby ukazovalo na #80-kový bajt na konci oblasti proměnných. Nyní otevři oblast proměnných.
Je vytvořen prostor o velikosti "BC“ před #80-kovým bajtem. INC INC EX 158
HL HL DE,HL
Ukazuj na první nový bajt. DE bude ukazovat na druhý nový bajt. Komentovaný výpis paměti ROM
PUSH LD DEC SUB LD JR
DE HL,(#5C4D) (DEST) DE #06 B,A Z,#2B4F,L-SINGLE
Uschovej tento ukazatel. Vyzvedni ukazatel na začátek jména. DE ukazuje na první nový bajt. B bude obsahovat počet znaků, které byly nalezeny v dlouhém názvu navíc. Obsluhuješ-li proměnnou s krátkým názvem, skoč dopředu.
Znaky navíc dlouhého názvu jsou předány do oblasti proměnných. 2B3E
L-CHAR
INC LD CP JR OR INC LD DJNZ
HL A,(HL) #21 C,#2B3E,L-CHAR #20 DE (DE),A #2B3E,L-CHAR
Ukazuj na každý znak "navíc". Vyzvedni jej. Akceptuj znaky od #21 do #FF a ignoruj od #00 do #20. Nastav bit 5 pro malá písmena. Převáděj znaky postupně od druhého nového bajtu dále. Pokračuj znovu do smyčky pro všechny znaky "navíc".
Poslední znak dlouhého názvu musí být ORován hodnotou #80. OR LD
#80 (DE),A
Označ znak tak jak je třeba a přepiš poslední kód.
První znak názvu zpracovávané proměnné je nyní posouzen.
2B4F
L-SINGLE
LD LD XOR OR POP
A,#C0 HL,(#5C4D) (DEST) (HL) #20 HL
Připrav se na označení "dlouhý název". Vyzvedni ukazatel na znak. A obsahuje #80 pro krátký název a #CO pro dlouhý název. Nastav bit 5 pro malá písmena. Nyní odhoď ukazatel.
Podprogram L-FIRST je nyní volán pro vložení "písmene" na příslušné místo. CALL #2BEA,L-FIRST
Vlož "písmeno" - HL ukazuje na nový #80-kový bajt.
Poslední hodnota může být nyní převedena do oblasti proměnných. Všimněte si, že v tomto bodě HL vždy ukazuje na pozici za pěti bajty, které jsou přiděleny tomuto číslu. Instrukce RST #28 je použita k zavolání kalkulátoru a poslední hodnota je pak "vymazána", ale nepřepsána. 2B59
L-NUMERIC
PUSH RST DEFB DEFB POP LD AND SBC JR
HL #28,FP-CALC #02,výmaz #38,konec výpočtu HL BC,#0005 A HL,BC #2BA6,L-ENTER
Uschovej cílový ukazatel. Použij kalkulátor. Takto je posunut STKEND zpět o pět bajtů. Obnov ukazatel. Nechť Číslo je dlouhé pět bajtů. HL ukazuje na první z pěti lokací. Skoč dopředu k provedení skutečného převedení.
Při zjištění, že proměnná již existuje, vstup do tohoto bodu. Nejprve otestuj bit 6 ve FLAGS, abys oddělil číselné proměnné od řetězcových nebo řetězcová pole. 2B66
L-EXISTS
BIT JR
6,(IY+1) (FLAGS) Z,#2B72,L-DELETE$
Při zpracování jakéhokoliv druhu řetězcové proměnné skoč dopředu.
Pro číselné proměnné "nové" číslo přepíše "staré" číslo. Takže HL musí ukazovat na místo za pět bajtů existující položky. Nyní ovšem HL ukazuje na místo před těmito pěti bajty.
Komentovaný výpis paměti ROM
159
LD ADD JR
DE,#0006 HL,DE #2B59,L-NUMERIC
Pět bajtů pro číslo + jeden pro znak FP čísla. Nyní HL ukazuje na místo "za". Skoč zpět k provedení skutečného přenesení.
Parametry řetězcové proměnné jsou vyzvednuty a kompletní jednoduché řetězce jsou odděleny od krácených řetězců a polí. 2B72
L-DELETE$
LD LD BIT JR
HL,(#5C4D) (DEST) BC,(#5C72) (STRLEN) 0,(IY+55) (FLAGX) NZ,#2BAF,L-ADD$
Vyzvedni start. Poznámka: tento řádek je nadbytečný. Vyzvedni délku. Při zpracování kompletního obyčejného řetězce skoč dopředu. Starý řetězec bude potřeba vymazat pouze v tomto případě.
Při zpracování řezu existující řetězcové proměnné, nebo řezu nebo kompletní části řetězcového pole, prochází program dvěma fázemi. Nejprve se v pracovním prostoru musí vytvořit nový řetězec, který je podle potřeby zkrácen nebo prodloužen, a v druhé fázi je pak tento řetězec okopírován na své místo v oblasti proměnných. Ovšem, pokud má řetězec nulovou délku, neděje se nic. LD OR RET
A,B C Z
Jedná-li se o nulový řetězec, vrať se.
Jinak vytvoř požadovaný počet míst v pracovním prostoru. PUSH RST PUSH PUSH LD LD INC LD LDDR
HL #30,BC-SPACES DE BC D,H E,L HL (HL),#20
Uschovej start (DEST). Vytvoř potřebné místo v pracovním prostoru. Uschovej ukazatel na první místo. Uschovej délku pro pozdější použití. DE ukazuje na poslední místo a HL ukazuje o bajt dále. Je vložen znak mezery a po jeho okopírování do všech nových pozic ukazuje HL na první nový znak.
Nyní jsou ze zásobníku kalkulátoru vyzvednuty parametry právě zpracovávaného řetězce. PUSH HL CALL #2BF1,STK-FETCH POP HL
Krátce uschovej ukazatel. Vyzvedni nové parametry a obnov ukazatel.
Poznámka: V tomto bodě již bylo v pracovním prostoru vytvořeno místo pro právě "přidělovanou proměnnou", například při příkazu LET a$(4 TO 8)="abcdefg" bylo vytvořeno pět míst. Parametry vyzvednuté jako poslední hodnota reprezentují řetězec, který má být kopírován do nových míst s použitím Prokrustova pravidla krácení nebo prodlužování podle potřeby. Délka nového řetězce je porovnávána s délkou možného prostoru.
2B9B
160
L-LENGTH
EX
(SP),HL
AND SBC ADD JR LD LD EX
A HL,BC HL,BC NC,#2B9B,L-LENGTH B,H C,L (SP),HL
Délka nové oblasti do HL a ukazatel nové oblasti na zásobník. Porovnej dvě délky a pasuje-li nový řetězec do prostoru (a tedy není-li potřeba žádného krácení), skoč dopředu. Jinak uprav novou délku neboť je příliš dlouhá. Délka nové oblasti na zásobník a ukazatel nové oblasti do HL.
Komentovaný výpis paměti ROM
Pokud nemá nový řetězec nulovou délku je kopírován do pracovního prostoru. Prokrustovo pravidlo se provádí automaticky, jestliže je nový řetězec kratší, než pro něj vytvořené místo, a je ho třeba "natáhnout". EX LD OR JR LDIR
DE,HL A,B C Z,#2BA3,L-IN-W/S
Start nového řetězce do HL a ukazatel nové oblasti do DE.
Je-li nový řetězec nulový, skoč dopředu. Jinak přesuň nový řetězec do pracovního prostoru.
Hodnoty, které byly uschovány na zásobníku, jsou nyní obnoveny. 2BA3
L-IN-W/S
POP POP POP
BC DE HL
Délka nové oblasti. Ukazatel nové oblasti. Start, ukazatel na proměnnou (původně v DEST), nyní je v L-ENTER použit k předání "nového" řetězce do oblasti proměnných.
PODPROGRAM "L-ENTER“ Tento krátký podprogram se používá buď k předání číselné hodnoty ze zásobníku kalkulátoru, nebo řetězce z pracovního prostoru, na své nové místo v oblasti proměnných. Podprogram je tedy používán pro všechny řetězce kromě nově deklarovaných a existujících kompletních řetězců. 2BA6
L-ENTER
EX LD OR RET PUSH LDIR POP RET
DE,HL A,B C Z DE HL
Zaměň ukazatele. Opět kontroluj nulovou délku. Vrať se při nulovém výsledku. Uschovej cílový ukazatel. Přenes číselnou hodnotu nebo řetězec. HL ukazuje na první bajt číselné hodnoty nebo řetězce. Vrať se.
PODPROGRAM " 'LET' POKRAČUJE ZDE" Při zpracování kompletních a existujících řetězců vstupuje nový řetězec "pod maskou" nově deklarovaného před tím, než je zničena jeho původní verze. 2BAF
L-ADD$
DEC DEC DEC LD PUSH PUSH CALL
HL HL HL A,(HL) HL BC #2BC6,L-STRING
POP POP INC INC INC JP
BC HL BC BC BC #19E8,RECLAIM-2
HL ukazuje na znak písmene názvu proměnné. Tzn. DEST-3. Vyzvedni znak. Uschovej ukazatel na existující verzi. Uschovej délku existujícího řetězce. Použij L-STRING k přičtení nového řetězce do oblasti proměnných. Obnov délku a ukazatel. Přidej jeden bajt pro písmeno a dva bajty pro délku. Odejdi přes "zničení" celé původně existující verze.
Nově deklarované jednoduché řetězce jsou zpracovány následovně: 2BC0
L-NEW$
LD LD AND
A,#DF HL,(#5C4D) (DEST) (HL)
Připrav se na označení názvu proměnné. Vyzvedni ukazatel na písmeno a patřičně jej poznač. Pak použij L-STRING (viz dále).
Komentovaný výpis paměti ROM
161
PODPROGRAM "L-STRING" Parametry nového řetězce jsou vyzvednuty. Pak se vytvoří potřebný prostor a řetězec je přenesen. 2BC6
L-STRING
PUSH CALL EX ADD PUSH DEC LD INC INC INC LD DEC CALL
AF #2BF1,STK-FETCH DE,HL HL,BC BC HL (#5C4D),HL (DEST) BC BC BC HL,(#5C59) (E-LINE) HL #1655,MAKE-ROOM
Uschovej znak názvu proměnné. Vyzvedni start a délku nového řetězce. Převeď start do HL. HL ať ukazuje jedno místo za řetězec. Uschovej délku. HL ukazuje na konec řetězce. Krátce uschovej ukazatel. Přidej jeden bajt pro písmeno a dva bajty pro délku. HL ukazuje na #80-kový bajt konce proměnných. Nyní vytvoř prostor v oblasti proměnných.
Poznámka: Ve skutečnosti je #80-kový bajt posunut (a s ním všechny důležité ukazatele) tak, že vznikne BC míst. LD POP PUSH INC LDDR EX INC POP LD DEC LD POP
HL,(#5C4D) (DEST) BC BC BC DE,HL HL BC (HL),B HL (HL),C AF
Obnov ukazatel na konec nového řetězce. Proveď kopii délky nového řetězce, přidej jednu na délku, i v případě délky řetězce 0. Pak okopíruj nový řetězec plus jeden bajt. HL nechť ukazuje na vyšší bajt délky. Vyzvedni délku. Vlož její vyšší a pak nižší bajt. Vyzvedni znak názvu proměnné.
PODPROGRAM "L-FIRST" Do tohoto podprogramu se vstupuje s již patřičně označeným písmenem názvu proměnné v registru A. Tento znak přepíše starý #80-kový bajt v oblasti proměnných. Při výstupu z tohoto podprogramu je registrový pár HL nastaven na nový #80-kový bajt. 2BEA
L-FIRST
DEC LD LD DEC RET
HL (HL),A HL,(#5C59) (E-LINE) HL
Nechť HL ukazuje na starý #80-kový bajt. Ulož tam písmeno názvu proměnné. Nechť HL ukazuje na nový #80-kový bajt. Skončeno s nově deklarovanou proměnnou.
PODPROGRAM "STK-FETCH" Tento důležitý podprogram vyzvedne poslední hodnotu ze zásobníku kalkulátoru. Těchto pět bajtů může vyjadřovat buď FP formu, "krátkou" nebo "dlouhou" formu, nebo to mohou být parametry řetězce. 2BF1
162
STK-FETCH
LD DEC LD DEC LD DEC
HL,(#5C65) (STKEND) HL B,(HL) HL C,(HL) HL
Vyzvedni STKEND. Zpět o jedno místo. 5. hodnota. Zpět o jedno místo. 4. hodnota. Zpět o jedno místo.
Komentovaný výpis paměti ROM
LD DEC LD DEC LD LD RET
D,(HL) HL E,(HL) HL A,(HL) (#5C65),HL (STKEND)
3. hodnota. Zpět o jedno místo. 2. hodnota. Zpět o jedno místo. 1. hodnota. Obnov hodnotu STKEND na novou pozici. Hotovo.
PODPROGRAM PŘÍKAZU DIM Tento podprogram vytváří nová pole v oblasti proměnných. Podprogram začíná vyhledáním existující proměnné v oblasti proměnných, aby se zjistilo zda pole s tímto názvem již existuje, a případně bylo toto pole zničeno před vytvořením pole nového. Nové číselné pole bude mít všechny prvky nastaveny na nulu a nové řetězcové pole bude vyplněno mezerami. 2C02 2C05
DIM D-REPORT-C
CALL JP CALL JR RES CALL CALL
#28B2,LOOK-VARS NZ,#1C8A,REPORT-C #2530,SYNTAX-Z NZ,#2C15,D-RUN 6,C #2996,STK-VAR #1BEE,CHECK-END
Prohledej oblast proměnných. Ohlaš chybu C, pokud se nejedná o pole. Při běhu programu skoč dopředu. Testuj syntaxi řetězcových polí jako by byli číselné. Kontroluj syntaxi výrazů v závorkách a posuzuj další výrazy, když je syntaxe v pořádku.
Existující pole je zničeno. 2C15
D-RUN
JR PUSH CALL CALL POP
C,#2C1F,D-LETTER BC #19B8,NEXT-ONE #19E8,RECLAIM-2 BC
Neexistuje-li žádné pole skoč dopředu. Uschovej rozlišovací bajt. Nalezni začátek další proměnné a znič existující pole. Obnov rozlišovací bajt.
Jsou nalezeny počáteční parametry nového pole. 2C1F
D-LETTER
2C2D
D-SIZE
SET LD PUSH LD BIT JR LD EX
7,C B,#00 BC HL,#0001 6,C NZ,#2C2D,D-SIZE L,#05 DE,HL
Nastav bit 7 rozlišovacího bajtu. Čítač rozměrů na nulu. Uschovej čítač a rozlišovací bajt. Registr HL bude obsahovat délku elementu v poli. (1 pro řetězec a 5 pro číslo). Délka elementu do DE.
Do následující smyčky se vstoupí pro každý rozměr, který je specifikován v závorkách po příkazu DIM. Celkový počet bajtů pro elementy pole bude vytvořen v registrovém páru DE. 2C2E
D-NO-LOOP
RST LD CALL JP POP PUSH INC PUSH LD LD CALL EX RST
#20,NEXT-CHAR H,#FF #2ACC,INT-EXP1 C,#2A20,REPORT-3 HL BC H HL H,B L,C #2AF4,GET-HL*DE DE,HL #18,GET-CHAR
Posuň CH-ADD při každém průchodu. Nastav limitní hodnotu. Ohodnoť parametr. Ohlaš chybu je-li parametr mimo rozsah. Vyzvedni čítač dimenzí a rozlišovací bajt. Uschovej parametr při každém průchodu smyčkou. Inkrementuj čítač rozměrů při každém průběhu. Obnov čítač dimenzí a rozlišovací bajt. Parametry jsou přeneseny do registrového páru HL. Celkový počet bajtů se vytváří v registrovém páru HL. Potom je převeden do DE. Vyzvedni aktuální znak a
Komentovaný výpis paměti ROM
163
CP JR
#2C Z,#2C2E,D-NO-LOOP
skoč znovu do smyčky, je—li to další rozměr.
Poznámka: V tomto bodě obsahuje registrový pár DE počet bajtů požadovaných pro elementy nového pole. Velikost každého rozměru je uschována na zásobník. Nyní zkontroluj, že skutečně existuje závorka ")" za danými výrazy. CP JR RST
#29 NZ,#2C05,D-REPORT-C #20,NEXT-CHAR
Je to ")"? Jestliže ne, skoč zpět. Posuň CH-ADD za ni.
Nyní budou rozměrům přiděleny velikosti. POP LD LD LD INC INC ADD ADD JP PUSH PUSH PUSH LD LD
BC A,C L,B H,#00 HL HL HL,HL HL,DE C,#1F15,REPORT-4 DE BC HL B,H C,L
Vyzvedni čítač rozměrů a rozlišovací bajt. Pro pozdější použití předej rozlišovací bajt do reg. A. Přenes čítač do L. Vyčisti registr H. Zvětši čítač rozměrů o dvě a vynásob ho dvěma. Vytvoř správnou délku pro proměnnou přičtením celkového počtu bajtů. Ohlaš "out of memory" je-li třeba. Uschovej celkový počet bajtů pole, čítač dimenzí a rozlišovací bajt. Uschovej také počet všech bajtů nutných k vytvoření pole a zároveň ho přenes do BC.
Požadovaný prostor pro nové pole je vytvořen na konci oblasti proměnných. LD DEC CALL INC
HL,(#5C59) (E-LINE) HL #1655,MAKE-ROOM HL
HL ukazuje na #80-kový bajt. Je vytvořen prostor a HL ukazuje na jeho první místo.
Nyní jsou vloženy parametry. LD POP DEC DEC DEC INC LD INC LD POP LD INC LD
(HL),A BC BC BC BC HL (HL),C HL (HL),B BC A,B HL (HL),A
Řádně označené písmeno je vloženo první. Je vyzvednuta celková délka a
je snížena o tři. Posuň HL. Vlož nižší a vyšší bajt délky. Vyzvedni čítač rozměrů. Převeď jej do registru A. Posuň HL. Vlož počet rozměrů.
Elementy nového pole jsou nyní vyčištěny. LD LD DEC LD 164
H,D L,E DE (HL),#00
HL ukazuje na poslední místo pole a DE o jedno místo před ním. Vlož nulu na poslední místo. Komentovaný výpis paměti ROM
2C7C
DIM-CLEAR
BIT JR LD POP LDDR
6,C Z,#2C7C,DIM-CLEAR (HL),#20 BC
Ale pokud se jedná o řetězcové pole budou místo nul vloženy "mezery". Vyzvedni celkový počet bajtů pole a vyčisti pole plus jedno místo navíc.
Nyní jsou vloženy velikosti rozměrů. 2C7F
DIM-SIZES
POP LD DEC LD DEC DEC JR RET
BC (HL),B HL (HL),C HL A NZ,#2C7F,DIM-SIZES
Vyzvedni velikost rozměru. Vlož vyšší a nižší bajt. Zmenši čítač dimenzí a opakuj operaci, dokud nebyly posouzeny všechny dimenze Jinak se vrať.
PODPROGRAM "ALFANUM" Je-li v registru A uložen znak platné číslice nebo písmene, vrací tento podprogram CY flag nastaven na hodnotu jedna. 2C88
ALPHANUM
CALL #2D1B,NUMERIC CCF RET C
Test na číslici. CY bude jedna pro platnou číslici a v tom případě se vrať.
PODPROGRAM "ALFA" Je-li v registru A uložen znak platného písmene vrací tento podprogram CY flag nastaven na hodnotu jedna. 2C8D
ALPHA
CP CCF RET CP RET CP CCF RET CP RET
#41 NC #5B C #61 NC #7B
Testuj oproti #41, což je kód pro písmeno "A". Komplementuj CY a vrať se nebyl-li to platný kód znaku. Testuj oproti #5B, což je o jednu více než kód písmene Z. Vrať se jestliže se jedná o znak. Testuj oproti #61, což je kód pro písmeno "a". Komplementuj CY a vrať se nebyl-li to platný kód znaku. Testuj oproti #7B, což je o jednu více než kód písmene z. Hotovo.
PODPROGRAM "DECIMAL TO FLOATING POINT" Součástí kontroly syntaxe je převádění dekadických čísel uložených v basicovém řádku na floating point formu. Tento podprogram načte dekadické číslo (číslici za číslicí) a výsledek zpracování uloží na zásobník kalkulátoru. Nejdříve je však obsloužen případný výskyt příkazu BIN, který je následován sérií jedniček a nul. 2C9B
DEC-TO-FP
2CA2
BIN-DIGIT
CP JR LD RST SUB ADC
#C4 NZ,#2CB8,NOT-BIN DE,#0000 #20,NEXT-CHAR #31 A,#00
JR EX
NZ,#2CB3,BIN-END DE,HL
Jedná se o znak BIN? Jestliže ne, skoč. Nastav hodnotu výsledku na hodnotu 0. Vyzvedni další znak. Odečti znakový kód pro jedničku. Nula nyní dává nulu s CY=1 a jednička dává nulu s CY=0. Jakýkoliv jiný znak vyvolá skok na BIN-END, a zkontroluje se znovu syntaxe. Výsledek do HL.
Komentovaný výpis paměti ROM
165
2CB3
BIN-END
CCF ADC JP EX JR LD LD JP
HL,HL C,#31AD,REPORT-6 DE,HL #2CA2,BIN-DIGIT B,D C,E #2D2B,STACK-BC
Komplementuj CY. Posuň výsledek do leva s načtením CY do bitu 0. Ohlaš přetečení, je-li výsledek větší než 65535. Vrať výsledek do DE. Skoč zpět na další nulu nebo jedničku. Okopíruj výsledek do BC pro uložení na zásobník.
Pro ostatní čísla se nejdříve převede celá část a jestliže je další znak desetinná tečka, posoudí se i zlomková část. 2CB8
NOT-BIN
2CCB
DECIMAL
2CCF
DEC-RPT-C
2CD5
DEC-STO-1
2CDA
NXT-DGT-1
CP JR CALL CP JR RST CALL JR JR RST CALL JP RST DEFB DEFB RST DEFB DEFB DEFB DEFB RST CALL JR RST DEFB DEFB DEFB DEFB DEFN DEFB DEFB RST JR
#2E Z,#2CCB,DECIMAL #2D3B,INT-TO-FP #2E NZ,#2CEB,E-FORMAT #20,NEXT-CHAR #2D1B,NUMERIC C,#2CEB,E-FORMAT #2CD5,DEC-STO-1 #20,NEXT-CHAR #2D1B,NUMERIC C,#1C8A,REPORT-C #28,FP-CALC #A0,stk-nula #38,konec výpočtu #28,FP-CALC #A1,stk-jedna #C0,st-mem-0 #02,výmaz #38,konec výpočtu #18,GET-CHAR #2D22,STK-DIGIT C,#2CEB,E-FORMAT #28,FP-CALC #E0,get-mem-0 #A4,stk-deset #05,dělení #C0,st-mem-0 #04,násobení #0F,sčítání #38,konec výpočtu #20,NEXT-CHAR #2CDA,NXT-DGT-1
Je první znak "."? Jestliže ano, skoč dopředu. Jinak vytvoř poslední hodnotu jako typ integer. Je další znak "."? Jestliže ano, skoč dopředu, neboť to může být exponent. Vyzvedni další znak. Jestliže to není číslice, skoč (např 1.E4 je povoleno). Skoč dopředu na obsluhu číslic za desetinnou tečkou. Jestliže číslo začínalo desetinnou tečkou, podívej se zda je následující znak číslice. Není-li tomu tak, ohlaš chybu. Použij kalkulátor a ulož nulu jako celou část těchto čísel. Použij opět kalkulátor. Nalezni FP formu dekadického čísla jedna a uschovej ji v paměťové oblasti číslo nula.
Vyzvedni aktuální znak. Je-li to číslice ulož ji na zásobník. Jinak skoč dopředu. Nyní použij kalkulátor. Při každém průchodu smyčkou je číslo vyzvednuto z paměti vyděleno deseti a obnoveno v paměti (asi takto 0.1,0.01,0.001 atd.). Aktuální číslice je násobena aktuálním číslem a přičtena k poslední hodnotě. Vyzvedni další znak. Skoč zpět (o jeden bajt více než je třeba) k posouzení.
Dále posuzuj jakoukoliv notaci E, např. formátu x E m nebo x e m, kde m je kladné nebo záporné celé číslo. 2CEB
E-FORMAT
2CF2
SIGN-FLAG
166
CP JR CP RET LD RST CP JR CP
#45 Z,#2CF2,SIGN-FLAG #65 NZ B,#FF #20,NEXT-CHAR #2B Z,#2CFE,SIGN-DONE #2D
Je aktuálním znakem "E"? Jestliže ano, pak skoč dopředu. Je to "e"? Konec jestliže ne. Použij B jako vlajku pro znaménko (#FF je plus "+"). Vyzvedni další znak. Je-li to plus, skoč dopředu. Není-li to ani mínus, Komentovaný výpis paměti ROM
2CFE 2CFF
SIGN-DONE ST-E-PART
2D18
E-FP-JUMP
JR INC RST CALL JR PUSH CALL CALL POP JP AND JP INC JR NEG JP
NZ,#2CFF,ST-E-PART B #20,NEXT-CHAR #2D1B,NUMERIC C,#2CCF,DEC-RPT-C BC #2D3B,INT-TO-FP #2DD5,FP-TO-A BC C,#31AD,REPORT-6 A M,#31AD,REPORT-6 B Z,#2D18,E-FP-JUMP #2D4F,E-TO-FP
skoč dopředu. Změň znaménko. Ukazuj na první číslici. Není-li to číslice ohlaš chybu. Uschovej vlajku v registru B. Ulož na zásobník hodnotu ABS m, kde m je exponent. Převeď ABS m do A. Obnov znaménkovou vlajku do B. Ohlaš přetečení je-li ABS m>255 nebo skutečně větší než 127 (hodnoty větší než 39 budou vyloučeny později). Testuj znaménkovou vlajku v registru B. Plus (tedy #FF) nastaví Z flag a pak se odskočí. Neguj m je-li znaménko mínus. Skoč k přidělení poslední hodnoty, výsledek x*10^m.
PODPROGRAM "NUMERIC" Představuje-li aktuální hodnota v registru A znak platné číslice vrací tento podprogram CY flag nastaven na nulu. 2D1B
NUMERIC
CP RET CP CCF RET
#30 C #3A
Testuj oproti #30 což je kód pro nulu. Jestliže se nejedná o platný znakový kód, vrať se. Testuj oproti hornímu limitu. Komplementuj CY a hotovo.
PODPROGRAM "STK-DIGIT" Nepředstavuje-li hodnota v registru A platnou číslici, podprogram se prostě vrátí, jinak je znaku přiřazena jeho hodnota a uložena na zásobník kalkulátoru. 2D22
STK-DIGIT
CALL #2D1B,NUMERIC RET C SUB #30
Není-li znak číslo, vrať se. Nahraď kód aktuální číslicí.
PODPROGRAM "STACK-A" Tento podprogram vytváří z absolutní binární hodnoty v registru A hodnotu ve tvaru floating point a ukládá ji na zásobník. 2D28
STACK-A
LD LD
C,A B,#00
Převeď hodnotu do registru C a vynuluj registr B.
PODPROGRAM "STACK-BC" Tento podprogram vytváří z absolutní binární hodnoty v registru BC hodnotu ve tvaru floating point a ukládá ji na zásobník. Forma používaná v tomto a tím pádem i v předchozích dvou podprogramech, je forma malých celých čísel. Prvý a pátý bajt jsou nulové, třetí a čtvrtý bajt je nižší a vyšší bajt 16-ti bitového čísla v komplementovaném tvaru (tedy -n = 65536 +n) a druhý bajt je znaménkový, tedy #00 pro plus a #FF pro mínus. 2D2B
STACK-BC
LD XOR LD LD LD LD
IY,#5C3A A E,A D,C C,B B,A
Nastav IY na ERR-NR. Vynuluj registr A a registr E, aby indikoval +. Kopíruj méně významný bajt do D a významnější bajt do C. Vyčisti registr B.
Komentovaný výpis paměti ROM
167
CALL RST DEFB AND RET
#2AB6,STK-STORE #28,FP-CALC #38,konec výpočtu A
Nyní ulož číslo. HL nechť ukazuje na STKEND -5. Vynuluj CY flag. Hotovo.
PODPROGRAM "INTEGER TO FLOATING POINT" Tento podprogram převede číslo z basicového řádku, tedy celou část dekadického čísla nebo čísla řádku, na zásobník kalkulátoru jako poslední hodnotu v FP tvaru. Opakované volání na CH-ADD+1 vyzvedne postupně všechny číslice celočíselné části. Výstup se provede v případě nalezení nenumerického znaku. 2D3B
INT-TO-FP
PUSH RST DEFB DEFB POP
AF #28,FP-CALC #A0,stk-nula #38,konec výpočtu AF
Uschovej první číslici v A. Použij kalkulátor. Poslední hodnota je nyní nula. Obnov původní číslici.
Nyní se vstupuje do smyčky. Představuje-li kód číslici, nalezne se její FP forma uloží se pod poslední položku. Ta je potom vynásobena deseti a přičtena k číslici, aby byla vytvořena nová poslední hodnota a ta pak přenesena opět na začátek smyčky. 2D40
168
NXT-DGT-2
CALL RET RST DEFB DEFB DEFB DEFB DEFB CALL JR
#2D22,STK-DIGIT C #28,FP-CALC #01,záměna #A4,stk-deset #04,násobení #0F,sčítání #38,konec výpočtu #0074,CH-ADD+1 #2D40,NXT-DGT-2
Představuje-li kód číslici, ulož její FP formu na zás. kalkulátoru. Jinak se vrať. Použij kalkulátor. Číslice jde pod poslední hodnotu. Je uloženo číslo 10. Poslední hodnota = poslední hodnota * 10. Poslední hodnota = poslední hodnota + číslice. Další znak jde do A. Skok zpět do smyčky s tímto znakem.
Komentovaný výpis paměti ROM
ARITMETICKÉ PODPROGRAMY E-FORMAT TO FLOATING POINT FORMAT (Doplněk: #3C - "e-to-fp“) Tento podprogram převádí číslo zapsané ve tvaru xEm, kde m je kladné nebo záporné celé číslo, na zásobník kalkulátoru tak, že hodnota x je poslední hodnotou a hodnota m je v registru A. Metoda používaná k nalezení absolutní hodnoty m, řekněme čísla p, je dána dělením nebo násobením čísla x hodnotou 10^p podle toho, je-li m kladné nebo záporné. Pro dosažení tohoto výsledku se postupuje následovně: p je posouváno doprava dokud není nulové a x je násobeno nebo děleno hodnotou 10^(2^n) pro každý nastavený bit hodnoty p. Jelikož p nikdy nepřesáhne hodnotu větší než 39, budou bity 6 a 7 hodnoty p normálně nulové. 2D4F
2D55
2D60
E-TO-FP
E-SAVE
E-LOOP
RLCA RRCA JR CPL INC PUSH LD CALL
A AF HL,#5C92 #350B,FP-0/1
RST DEFB DEFB POP SRL JR PUSH RST
#28,FP-CALC #A4,stk-deset #38,konec výpočtu AF A NC,#2D71,E-TST-END AF #28,FP-CALC
NC,#2D55,E-SAVE
Testuj znaménko m rotacemi bitu 7 do CY a zpět aniž by došlo ke změně A. Je-li m pozitivní, skoč. Neguj m v registru A bez porušení CY. Uschovej krátce registr A. Toto je MEMBOT. Znaménkový bajt je nyní uložen v 1. bajtu mem-0,#00= +, #01= -. Na zásobníku je hodnota x. x,10 x,10 Obnov m v registru A. Ve smyčce posunuj další bit m - nastaví CY a Z jak třeba. Je-li CY rovno nule skoč. Uschovej zbytek m a vlajky.
Na zásobníku je nyní x' (což je přechodná fáze násobení x*10^m) a 10^(2^n), kde n=0,1,..,5.
2D6D 2D6E
E-DIVSN E-FETCH
2D71
E-TST-END
2D7B
E-END
DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB POP JR PUSH RST DEFB DEFB DEFB POP JR RST DEFB DEFB RET
#C1,st-mem-1 #E0,get-mem-0 #00,skoč-pravda #04,na E-DIVSN #04,násobení #33,skoč #02,na E-FETCH #05,dělení #E1,get-mem-1 #38,konec výpočtu AF Z,#2D7B,E-END AF #28,FP-CALC #31,zdvojení #04,násobení #38,konec výpočtu AF #2D60,E-LOOP #28,FP-CALC #02,výmaz #38,konec výpočtu
10^(2^n) do mem-1 x',10^(2^n),1/0 x',10^(2^n) x',10^(2^n) x'*10^(2^n)= x'' x'' x'' x'/10^(2^n)=x'' (x*10^(2^n) či x'/10^/(2^n)) x'',10^(2^n) x'',10^(2^n) Obnov zbytek m v registru A a podmínkové vlajky. Bylo-li m sníženo na nulu, skoč. Uschovej zbytek m v registru A. x'',10^(2^n) x'',10^(2^n),10^(2^n) x'',10^(2^(n+1)) x'',10^(2^(n+1)) Obnov zbytek m v registru A. Skoč zpět pro všechny bity hodnoty m. Použij kalkulátor k vymazání výsledné mocniny deseti. Poslední hodnota je tedy x*10^m.
Komentovaný výpis paměti ROM
169
PODPROGRAM "VYZVEDNUTÍ CELÉHO ČÍSLA" Tento podprogram načte do DE hodnotu "malého" celého čísla z místa adresovaného registrovým párem HL. Tedy n je běžně prvním (nebo druhým) číslem na zásobníku kalkulátoru, ale HL může (po záměně s DE) dosáhnout i čísla, které už bylo ze zásobníku kalkulátoru "vymazáno". Podprogram sám o sobě nevymaže číslo ze zásobníku a vrací HL tak, Že ukazuje na čtvrtý bajt čísla v jeho původní pozici. Poznámka: "malé celé číslo" je každé číslo n, pro které platí -65535<=n<=65535. 2D7F
INT-FETCH
INC LD
HL C,(HL)
Ukazuj na znaménkový bajt čísla a vyzvedni ho do C.
Následující mechanismus provede dvojkový doplněk čísla jestliže je záporné (C obsahuje #FF). Jinak ho nechá být (C obsahuje #00). INC LD XOR SUB LD INC LD ADC XOR LD RET
HL A,(HL) C C E,A HL A,(HL) A,C C D,A
Ukazuj na méně významný bajt a vyzvedni ho do A. Je-li číslo záporné, proveď jedničkový doplněk. Přičti 1 pro záporná čísla a nastav CY, pokud není nula. Méně významný bajt do E. Ukazuj na významnější bajt a vyzvedni jej do A. Dokonči dvojkovou komplementaci v případě negativního čísla. CY je vždy rovno nule. Významnější bajt do D a hotovo.
PODPROGRAM "ULOŽENÍ CELÉHO ČÍSLA" Tento podprogram ukládá hodnotu "malého" celého čísla na místo adresované registrovým párem HL a čtyři další místa. Tedy n nahradí první (nebo druhé) číslo na zásobníku kalkulátoru. HL se vrací s hodnotou adresy prvního bajtu čísla n na zásobníku kalkulátoru. 2D8C 2D8E
P-INT-STO INT-STORE
LD PUSH LD INC LD
C,#00 HL (HL),#00 HL (HL),C
Tento vstupní bod je použit pro ukládání celých čísel. Ukazatel na první místo je uschován. První bajt je nastaven na nulu. Ukazuj na druhé místo a vlož znaménkový bajt.
Nyní je použit stejný způsob vytváření dvojkových doplňků pro negativní čísla jako v podprogramu "ULOŽENÍ CELÉHO ČÍSLA". Toto je zapotřebí například před nebo po násobení malých celých čísel. Ovšem sčítání se provádí bez jakýchkoliv úprav. INC LD XOR SUB LD INC LD ADC XOR LD INC LD POP RET
170
HL A,E C C (HL),A HL A,D A,C C (HL),A HL (HL),#00 HL
Ukazuj na třetí místo. Vyzvedni nižší bajt, proveď jeho dvojkový doplněk, je-li to třeba. Ulož tento bajt. Ukazuj na čtvrté místo, vyzvedni vyšší bajt, opět proveď odpovídající úpravy. Ulož i tento bajt. Ukazuj na páté místo a vlož tam nulu. Vrať se s adresou prvního bajtů ukládaného čísla v HL.
Komentovaný výpis paměti ROM
PODPROGRAM "FP D0 BC" Tento podprogram se volá ze čtyř různých míst pro různé účely a je používán ke kompresi FP hodnoty na zásobníku kalkulátoru do registrového páru BC. Je-li výsledek větší než 65535, potom program nastaví CY na hodnotu jedna. Je-li poslední hodnota negativní, potom je Z flag roven nule. Nižší bajt výsledku je také okopírováno do registru A. 2DA2
2DAD
FP-TO-BC
FP-DELETE
RST DEFB LD AND JR RST DEFB DEFB DEFB DEFB RST DEFB DEFB PUSH PUSH EX LD CALL XOR SUB BIT LD LD LD POP POP RET
#28,FP-CALC #38,konec výpočtu A,(HL) A Z,#2DAD,FP-DELETE #28,FP-CALC #A2,stk-polovina #0F,sčítání #27,int #38,konec výpočtu #28,FP-CALC #02,delete #38,konec výpočtu HL DE DE,HL B,(HL) #2D7F,INT-FETCH A B 7,C B,D C,E A,E DE HL
Použij kalkulátor, aby HL ukazovalo na STKEND-5. Vyzvedni exponentový bajt. Je-li nulový, skoč, neboť se jedná o malé číslo. Použij kalkulátor k zaokrouhlení poslední hodnoty na nejbližší celé číslo, což ho převede na malé celé číslo, je-li to možné. Použij kalkulátor k vymazání čísla ze zásobníku. DE stále ukazuje na číslo v paměti (na STKEND). Uschovej oba zásobníkové ukazatele. HL nyní ukazuje na číslo. Kopíruj první bajt do B. Kopíruj bajty 2,3 a 4 do C, E a D. Vynuluj registr A. CY je nula pokud je B různé od nuly. Z flag je nastaven, jestliže číslo je kladné. Vyšší bajt do B. Nižší bajt do C a do A. Obnov ukazatele. Hotovo.
PODPROGRAM "LOG(2^A)" Tento podprogram se volá z podprogramu PRINT-FP aby vypočítal přibližný počet číslic před desetinnou tečkou pro x (číslo, které má být vytištěno). Nejsou-li před desetinnou tečkou žádné číslice, spočte přibližný počet úvodních nul za desetinnou tečkou. Do podprogramu se vstupuje s číslem e' v registru A, což je pravý exponent x, nebo e'-2 a počítá se z=LOG při základu 10 z hodnoty (2^A). A se pak nastaví na hodnotu ABS INT (z+0.5) jak je požadováno. Pro tento účel se použije FP-TO-A. 2DC1
LOG(2^A)
LD RLA SBC LD LD XOR LD CALL RST DEFB DEFB DEFB DEFB DEFB
D,A A,A E,A C,A A B,A #2AB6,STK-STORE #28,FP-CALC #34,stk-data #EF,exponent #7F #1A,#20,#9A,#85 #04,násobení #27,int
Hodnota A je uložena ve tvaru: 00 00 A 00 00 pro A>0 nebo 00 FF A FF 00 pro A<0. Tyto bajty jsou nejprve uloženy do A E D C B a později
na zásobník kalkulátoru. Použij kalkulátor. LOG 2 je nyní uložen na zásobník. Zásobník obsahuje A a LOG 2 A*LOG 2, čili LOG (2^A) INT LOG(2^A)
Komentovaný výpis paměti ROM
171
DEFB #38,konec výpočtu
Podprogram pokračuje do FP-TO-A k dokončení výpočtu.
PODPROGRAM "FLOATING POINT TO A" Tento krátký ale velice důležitý podprogram je volán v osmi případech pro různé účely. Používá mimo jiné, FP-TO-BC k převedení poslední hodnoty do registru A kdykoliv je to možné. Proto také testuje modulus čísla a jestliže je toto číslo větší než 255, je nastaveno CY. Jinak se vrací modul čísla zaokrouhlený na nejbližší celé číslo v registru A. Z flag se používá k rozlišení kladného nebo záporného čísla. 2DD5
FP-TO-A
2DE1
FP-A-END
CALL RET PUSH DEC INC JR POP SCF RET POP RET
#2DA2,FP-TO-BC C AF B B Z,#2DE1,FP-A-END AF
AF
Kompresuj poslední hodnotu do BC. Bylo-li to mimo rozsah, vrať se. Uschovej výsledek a podmínkové příznaky a opět je chyba, není-li v registru B nula. Je-li vše O.K., skoč. Vyzvedni výsledek a podmínkové příznaky. Signál, že výsledek je mimo rozsah. Konec-neúspěšně. Vyzvedni výsledek a podmínkové příznaky. Konec-úspěšně.
PODPROGRAM "VYPSÁNÍ FP ČÍSLA" Tento podprogram se volá podprogramem příkazu PRINT na adrese #2039 a STR$ na adrese #3630, které převádí číslo na řetězec tak, jako kdyby byl vypsán. Tento podprogram vytiskne x, které je uloženo jako poslední hodnota na zásobníku kalkulátoru. Tiskový formát nikdy nezabere více než čtrnáct míst. Osm nejvýznamnějších číslic x správně zaokrouhlených je uschováno v tiskovém bafru vytvořeném speciálně pro tento účel v pamětech zásobníkové paměti mem-3 a mem-4. Malá čísla numericky menší než jedna a čísla větší než 2^27 jsou zpracována samostatně. Menší jsou násobena hodnotou 10^n, kde n je přibližný počet úvodních nul za desetinnou čárkou, zatímco větší čísla jsou dělena hodnotou 10^(n-7), kde n je přibližný počet číslic před desetinnou čárkou. Tímto se všechna čísla dostávají do středního rozsahu a počet číslic požadovaných před desetinnou čárkou je uložen v druhém bajtu paměti mem-5. Nakonec je vše vytisknuto s použitím E-formátu, jestliže bylo více než osm číslic před desetinnou tečkou nebo více než čtyři nuly za desetinnou tečkou. Následující program v basicu ukazuje na rozsah tiskových formátů: 10 FOR a=-11 TO 12: PRINT SGN a*9^a,: NEXT a a) Nejprve je ošetřeno znaménko čísla x: x<0 - podprogram skočí na PF-NEGTVE, kde se před hodnotu ABS x vytiskne znaménko mínus. x=0 - x je vymazáno ze zásobníku kalkulátoru, je vytištěna nula a převeden návrat. x>0 - podprogram jenom pokračuje. 2DE3
172
PRINT-FP
RST DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB LD RST RET
#28,FP-CALC #31,zdvojení #36, <0 #00,skok-pravda #0B,na PF-NEGTVE #31,zdvojení #37, >0 #00,skok-pravda #0D,na PF-POSTVE #02,výmaz #38,konec výpočtu A,#30 #10,PRINT-A-1
Použij kalkulátor. x,x x, (1/0) (logická hodnota x) x x x,x x, (1/0) (logická hodnota x) x x kde již x' bude ABS x Vlož znak nula "0" a vytiskni ho. Konec a poslední hodnota je nula. Komentovaný výpis paměti ROM
2DF2
PF-NEGTVE
2DF8
PF-POSTVE
DEFB DEFB LD RST RST DEFB DEFB DEFB DEFB DEFB DEFB EXX PUSH EXX
#2A,abs #38,konec výpočtu A,#2D #10,PRINT-A-1 #28,FP-CALC #A0,stk-nula #C3,st-mem-3 #C4,st-mem-4 #C5,st-mem-5 #02,výmaz #38,konec výpočtu HL
x'=ABS x x' Vlož znak "-" a vytiskni ho. Opět použij kalkulátor. 15 bajtů pamětí mem-3 až 5 je nastaveno na nuly potřebné pro tiskový bafr a dvě počítadla. Zásobník je vyčištěn až na x'. x' HL', který bude obsahovat kalkulátorové doplňky (např. pro STR$), je uložen na zásobník procesoru (SP).
b) Toto je start smyčky, která zpracovává větší čísla. Nicméně každé číslo x je rozděleno na svou celou část (i) a zlomkovou část (f). Jedná-li se o malé číslo, tedy -65535 až 65535, je uloženo v registrovém páru DE' před vložením do tiskového bafru. 2E01
PF-LOOP
2E1E
PF-SAVE
RST DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB LD AND JR CALL LD LD AND JR OR JR LD LD PUSH EXX POP EXX JR
#28,FP-CALC #31,zdvojení #27,int #C2,st-mem-2 #03,odečet #E2,get-mem-2 #01,záměna #C2,st-mem-2 #02,výmaz #38,konec výpočtu A,(HL) A NZ,#2E56,PF-LARGE #2D7F,INT-FETCH B,#10 A,D A NZ,#2E1E,PF-SAVE E Z,#2E24,PF-SMALL D,E B,#08 DE DE #2E7B,PF-BITS
Opět použij kalkulátor. x',x' x',INT(x')=i x',i do mem-2 x'-i=f f,i i,f i,f do mem-2 i i Jestliže i je malé číslo (1.bajt) je nulový a tedy ABS i<=65535, pak neskákej a okopíruj i do DE (i jako x'>=0). B je nastaveno jako počítadlo 16-ti bitů. D je okopírováno do A. Není-li D nulové, skoč. Nyní testuj E a jestliže DE je nula, skoč, neboť x je čistý zlomek. Přenes E do D. Nastav B na osm bitů. Přenes za pomoci zásobníku DE do DE', aby jeho hodnoty mohly být přeneseny do tiskového bafru v bodě PF-BITS. Skoč dopředu.
c) Čisté zlomky jsou násobeny hodnotou 10^n, kde n je přibližný počet úvodních nul za desetinnou čárkou, -n je přičteno k druhému bajtu mem-5, který obsahuje počet číslic před desetinnou čárkou. Záporná čísla indikují počet nul za desetinnou čárkou. 2E24
PF-SMALL
RST #28,FP-CALC DEFB #E2,get-mem-2 DEFB #38,konec výpočtu
i (i je zde nula) i,f i,f
Poznámka: Povšimněte si, že zásobník je nyní nevyvážen. K tomu by bylo potřeba další bajt DEFB #02, výmaz na adrese #2E25 hned za instrukcí RST #28. Proto nyní výraz jako např. "2“+STR$ 0.5 je nesprávně ohodnocen jako 0.5: nula ponechaná na zásobníku nahradí dvojku a vše je považováno za nulový Komentovaný výpis paměti ROM
173
řetězec. Tím pádem i řetězcová porovnání mohou vést k nesprávným hodnotám, když druhý řetězec má formu STR$ x a x<1, tedy např. výraz "50"<STR$ 0.1 dává logickou hodnotu pravda, neboť místo "50" je opět použit nulový řetězec. LD SUB CALL LD LD SUB LD LD CALL RST DEFB DEFB DEFB DEFB DEFB DEFB CALL PUSH LD DEC RLA SBC INC LD LD INC ADD LD POP JP
A,(HL) #7E #2DC1,LOG(2^A) D,A A,(#5CAC) (mem-5-2nd) D (#5CAC),A (mem-5-2nd) A,D #2D4F,E-TO-FP #28,FP-CALC #31,zdvojení #27,int #C1,st-mem-1 #03,odečet #E1,get-mem-1 #38,konec výpočtu #2DD5,FP-TO-A HL (#5CA1),A (mem-3-1st) A A,A A HL,#5CAB (HL),A HL A,(HL) (HL),A HL #2ECF,PF-FRACTN
Exponentový bajt E čísla f je kopírován do A. A obsahuje E-126 tedy E'+2 kde E' je skutečný exponent f. Konstrukce A=ABS INT(LOG(2^A)) je nyní vytvořena. A=n takže: n okopírováno z A do D. Aktuální počet je vyzvednut z druhého bajtu mem-5 a je od něj odečteno n. n je okopírováno z D do A. Na zásobník je uložena hodnota y=f*10^n. i,y i,y,y i,y,INT y=i2 i2 do mem-1 i,y-i2 i,y-i2,i2 i,f2,i2 (f2=y-i2) i2 je převedeno ze zásobníku do A. Ukazatel na f2 je uschován. i2 je uschováno v prvním bajtu mem-3. Tedy pro tisk. Ovšem je-li i2 nula, nebude se počítat jako číslice pro tisk. A je manipulováno tak, že nula způsobí nulu, ale nenulová hodnota způsobí jedničku. Toto je 1.bajt mem-5, kam je vložena hodnota nula nebo jedna (tedy počet číslic pro tisk) a přičtena k druhému bajtu mem-5, což je počet číslic před desetinnou čárkou. Ukazatel na f2 je obnoven. Skok na umístění f2 do bafru (HL ukazuje na f2,DE na i2).
d) Čísla větší než 2^27 jsou násobena hodnotou 2^(-n+7) což snižuje desetinnou čárkou na osm a je proveden opětovný vstup do smyčky v bodě PF-LOOP. 2E56
PF-LARGE
SUB CP JR CALL SUB LD LD ADD LD LD NEG CALL JR
#80 #1C C,#2E6F,PF-MEDIUM #2DC1,LOG(2^A) #07 B,A HL,#5CAC A,(HL) (HL),A A,B #2D4F,E-TO-FP #2E01,PF-LOOP
počet
číslic
před
E-#80=E' je skutečný exponent i. je-li E' menší než 28 skoč. V registru A je vytvořena hodnota n a snížena na n-7. Pak je okopírována do B a přičtena k druhému bajtu mem-5, což je počet číslic požadovaný před desetinnou čárkou pro tisk čísla x. Potom je i vynásobeno hodnotou 10^(-n+7) a tím převedeno pro střední rozsah. Skok zpět do smyčky pro zpracování středně velikého čís.
e) Celá část hodnoty x je uložena v tiskovém bafru, který je tvořen 10 bajty mem-3 a mem-4. 2E6F
174
PF-MEDIUM
EX DE,HL CALL #2FBA,FETCH-TWO EXX SET 7,D
DE nyní ukazuje na i, HL na f. Mantisa i je nyní DE', DE. Vyzvedni zrcadlové registry. Pravdivý numerický bit 7 do D'. Komentovaný výpis paměti ROM
LD EXX SUB LD
A,L #80 B,A
Exponentový bajt E čísla i do registru A. Zpět na hlavní registry. Skutečný exponent do registru A. Tím se dosáhne požadovaného počtu bitů.
V případě, že i je malé celé číslo (menší než 65535), provede se opětovný vstup v tomto bodě. 2E7B
2E8A
PF-BITS
PF-BYTES
SLA RL EXX RL RL EXX LD LD LD ADC DAA LD DEC DEC JR DJNZ
E D E D HL,#5CAA C,#05 A,(HL) A,A (HL),A HL C NZ,#2E8A,PF-BYTES #2E7B,PF-BITS
Mantisa i je nyní rotována doleva a všechny bity posouvány do mem-4 a každý bajt mem-4 je dekadicky upraven po každém posunu. Všechny čtyři bajty čísla i. Zpět na hlavní registry. Adresa 5.bajtu mem-4 do HL. Počet bajtů do C. Vyzvedni bajt z mem-4. Posuň jej doleva a přiber i nový bit. Pak proveď dekadickou korekci a výsledek opět ulož do mem-4. Ukazuj na další bajt mem-4. Sniž počítadlo bajtů o jeden. Skoč pro každý bajt v mem-4. Skoč pro každý bit hodnoty INT x.
Dekadická korekce každého bajtu mem-4 dává dvě desítkové číslice na bajt, čímž vznikne nejvíce 9 číslic. Vzniklá číslice budou nyní převedeny, jedna na bajt, v pamětech mem-3 a mem-4 použitím instrukce RLD.
2EA1
PF-DIGITS
2EA9
PF-INSERT
2EB3
PF-TEST-2
2EB8
PF-ALL-9
2ECB
PF-MORE
XOR LD LD LD RLD LD RLD JR DEC INC JR LD INC INC INC LD BIT JR INC DJNZ LD SUB JR DEC LD CP JR RST DEFB DEFB
A HL,#5CA6 DE,#5CA1 B,#09 C,#FF NZ,#2EA9,PF-INSERT C C NZ,#2EB3,PF-TEST-2 (DE),A DE (IY+113) (mem-5-1st) (IY+114) (mem-5-2nd) C,#00 0,B Z,#2EB8,PF-ALL-9 HL #2EA1,PF-DIGITS A,(#5CAB) (mem-5-1st) #09 C,#2ECB,PF-MORE (IY+113) (mem-5-1st) A,#04 (IY+111) (mem-4-4th) #2F0C,PF-ROUND #28,FP-CALC #02,výmaz #E2,get-mem-2
Registr A je vyčištěn, aby mohl převzít číslice. Zdrojová adresa 1.bajtu mem-4. Cílová adresa 1.bajt mem-3. Existuje maximálně 9 číslic. Levá slabika mem-4 je odhozena. Hodnota #FF v C je signál: úvodní nula, #00 bez úvodní. Levá slabika hodnoty v (HL) do A, pravá sl. (HL) doleva. Skoč, jestliže číslice v A není nulová. Test na úvodní nulu. Jednalo-li se o úvodní nulu, skoč. Vlož číslici. Ukazuj na další cílovou adresu. Další číslice pro tisk a další před desetinnou tečkou. Změň signál z úvodní nuly na jinou nulu. Zdrojový ukazatel má být inkrementován při každém druhém průchodu smyčkou, kdy B je liché. Skoč zpět pro všech devět číslic. Vyzvedni čítač. Nebylo-li zde devět číslic bez úvodních nul, skoč pro další čísla. Příprava na zaokrouhlení: sniž počet na osm. Porovnej devátou číslici, se čtyřkou k nastavení CY pro zaokrouhlení. Skoč na zaokrouhlení. Použij opět kalkulátor. i je nyní vymazáno. f
Komentovaný výpis paměti ROM
175
DEFB #38,konec výpočtu
f
f) Zlomková část K je nyní převedena do tiskového bafru. 2ECF
PF-FRACTN
2EDF
PF-FRN-LP
2EEC 2EEF
PF-FR-DGT PF-FR-EXX
EX CALL EXX LD SUB LD SET EXX CALL LD CP JR EXX RL EXX JR LD LD CALL LD LD CALL LD PUSH EXX POP DJNZ LD LD LD ADD LD INC JR
DE,HL #2FBA,FETCH-TWO
DE nyní ukazuje na f. Mantisa f je převedena DE', DE. Přepni na zrcadlové registry. A,#80 Exponent f je snížen na nulu, L posunutím bitů hodnoty f, #80-E posune doprava L,#00 hodnotu E uloženou v registru L'. 7,D Skutečný numerický bit 7 do D'. Obnov hlavní registry. #2FDD,SHIFT-FP Nyní proveď posun. A,(IY+113) (mem-5-1st) Vyzvedni počet číslic. #08 Nebylo-li osm číslic, C,#2EEC,PF-FR-DGT skoč dopředu. Bylo-li osm číslic, použij k zaokrouhlení nahoru rotaci D D' doleva,čímž se nastaví CY. Obnov hlavní registry a #2F0C,PF-ROUND skoč dopředu k zaokrouhlení. BC,#0200 Počáteční nula do C a počet dvou do B. A,E D',E',D a E se násobí deseti #2F8B,CA=10*A+C ve dvou fázích nejprve DE a pak D'E', E,A každý bajt bajtem ve dvou krocích. A,D #2F8B,CA=10*A+C Celočíselná část výsledku je potom v C aby mohla být D,A převedena do tiskového bafru. BC Počet a výsledek jsou uloženy do obou párů BC a B'C'. BC #2EEF,PF-FR-EXX Jednou skoč zpět přes výměnu registrů. HL,#5CA1 Start 1.bajt mem-3. A,C Výsledek do A pro uložení. C,(IY+113) (mem-5-1st) Počet číslic do C. HL,BC Adresuj první prázdný bajt. (HL),A Ulož další číslici. (IY+113) (mem-5-1st) Zvyš počet číslic. #2EDF,PF-FRN-LP Dokud není všech osm číslic, skákej zpět.
g) Číslice uložené v tiskovém bafru jsou zaokrouhleny na maximum osmi číslic pro tisk. 2F0C
PF-ROUND
2F18
PF-RND-LP
2F25
PF-R-BACK
176
PUSH LD LD LD ADD LD POP DEC LD ADC LD AND JR CP CCF JR DJNZ
AF Uschovej CY pro zaokrouhlení. HL,#5CA1 Bázová adresa čísla mem-3 1.bajt. C,(IY+113) (mem-5-1st) Doplněk (počet číslic v čísle) do BC. B,#00 HL,BC Adresuj poslední bajt čísla. B,C Kopíruj C do B jako čítač. AF Obnov CY. HL Toto je poslední bajt čísla. A,(HL) Vyzvedni ho do A. A,#00 Přičti CY,tedy zaokrouhli. (HL),A Ulož zaokrouhlený bajt do bafru. A Byla-li to nula, nebo desítka, Z,#2F25,PF-R-BACK bude B zaokrouhleno a závěrečná nula nebo desítka, #0A nebude započtena do tisku. Nuluj CY pro platnou číslici. NC,#2F2D,PF-COUNT Je-li CY=0, skoč. #2F18,PF-RND-LP Skoč zpět pro další zaokr. nebo další závěrečné nuly. Komentovaný výpis paměti ROM
2F2D
PF-COUNT
LD INC INC LD RST DEFB DEFB EXX POP EXX
(HL),#01 Toto je přetečení doleva. B Zde je zapotřebí další jedničky. (IY+114) (mem-5-2nd) Je to také další extra číslice před desetinnou tečkou. (IY+113),B (mem-5-1st) B nyní nastaví počet tištěných číslic mimo záv. nul. #28,FP-CALC f musí být o vymazáno. #02,výmaz #38,konec výpočtu Kalkulátorový doplněk, který byl uschován na HL zásobníku je obnoven v zrcadlovém HL.
h) Nyní může být číslo vytištěno. Nejdříve bude do C uložen počet tištěných číslic, mimo závěrečných nul, a B bude obsahovat počet číslic před desetinnou tečkou.
2F46
PF-NOT-E
LD LD LD CP JR CP JR AND CALL
BC,(#5CAB) (mem-5-1st) Čítače jsou nastaveny. HL,#5CA1 Adresa první číslice. A,B Jestliže je více než 9 nebo méně než -4 #09 číslic před desetinnou tečkou, C,#2F46,PF-NOT-E je použit formát E. #FC Méně než -4 před desetinnou tečkou C,#2F6C,PF-E-FRMT znamená více než čtyři nuly za desetinnou tečkou. A Jestliže nejsou žádná čísla před desetinnou tečkou, Z,#15EF,OUT-CODE vytiskni počáteční nulu.
Další vstupní bod se používá k vytištění čísla ve formátu E. 2F4A
PF-E-SBRN
2F52
PF-OUT-LP
2F59
PF-OUT-DT
2F5E
PF-DC-OUT
2F64
PF-DEC-0S
2F6C
PF-E-FRMT
XOR SUB JR LD JR LD AND JR LD INC DEC CALL DJNZ LD AND RET INC LD RST LD DJNZ LD JR LD DEC LD CALL LD RST LD LD AND
A B M,2F52,PF-OUT-LP B,A #2F5E,PF-DC-OUT A,C A Z,#2F59,PF-OUT-DT A,(HL) HL C #15EF,OUT-CODE #2F52,PF-OUT-LP A,C A Z B A,#2E #10,PRINT-A-1 A,#30 #2F64,PF-DEC-0S B,C #2F52,PF-OUT-LP D,B D B,#01 #2F4A,PF-E-SBRN A,#45 #10,PRINT-A-1 C,D A,C A
Nastav A na nulu. Odečti B. Mínus znamená, že existují číslice před desetinnou tečkou, a proto je vytiskni. A je nyní použito jako čítač. Skoč dopředu k vytištění části za desetinnou tečkou. Kopíruj počet číslic, které mají být vytištěny, do A. Pokud A=0, pak ještě existují závěrečné nuly, které je třeba vytisknout (skoč neboť B je nenulové). Vyzvedni číslici z tiskového bafru. Ukazuj na další číslici. Dekrementuj počet o jednu. Vytiskni příslušnou číslici. Skákej zpět,dokud B není nulové. Je třeba vytisknout desetinnou tečku. Pokud ovšem C není nulové. V tom případě se vrať, neboť je všechno hotovo. Přičti jedničku do B (toto přičte desetinnou tečku). Dej kód pro "." do A. Vytiskni tečku. Vlož kód pro nulu. Skoč zpět k vytištění všech potřebných nul. Nastav čítač pro všechny zbývající číslice. Proveď jejich vytištění. Počet číslic je kopírován do D a okamžitě zmenšen, aby byl dán i exponent. Je zapotřebí jedna číslice před des. tečkou pro E formát Celá část čísla před E je nyní vytištěna. Vlož kód pro E a vytiskni ho. Exponent do C pro vytištění a do A pro otestování. Je testováno znaménko a
Komentovaný výpis paměti ROM
177
2F83 2F85
PF-E-POS PF-E-SIGN
JP NEG LD LD JR LD RST LD JP
P,#2F83,PF-E-POS C,A A,#2D #2F85,PF-E-SIGN A,#2B #10,PRINT-A-1 B,#00 #1A1B,OUT-NUM-1
Je-li kladné, skoč. Jinak neguj A. Kopíruj A zpět do C pro tisk. Vlož kód pro mínus a vytiskni znaménko. Vlož kód pro "+". Nyní vytiskni znaménko ("+" nebo "-") BC obsahuje exponent; Vytiskni ho.
PODPROGRAM "CA=10*A+C" Tento program je volán podprogramem PRINT-FP k vynásobení každého bajtu D',E',D a E deseti tak, že vrací celočíselnou část výsledku v registru C. Na vstupu registr A obsahuje bajt, který má být násoben deseti a registr C obsahuje CY z předchozího bajtu. Při návratu obsahuje A výsledný bajt a v registru C je logická hodnota CY flag pro další bajt. 2F8B
CA=10*A+C
PUSH LD LD LD LD ADD ADD ADD ADD LD ADD LD LD POP RET
DE L,A H,#00 E,L D,H HL,HL HL,HL HL,DE HL,HL E,C HL,DE C,H A,L DE
Uschovej kterýkoliv pár DE (může to být D'E'nebo DE). Kopíruj násobence do HL. Okopíruj jej také do DE. Dvakrát zdvoj HL. Přičti DE (což už 5*A) a nakonec zdvoj HL (konečně 10*a). Kopíruj C do DE (D je nulové) pro sčítání. Nyní se HL rovná 10*A+C. H je kopírováno do C a L je kopírováno do A, čímž je úkol hotov. Obnov DE a vrať se.
PODPROGRAM "PŘÍPRAVY NA SČÍTÁNÍ" Tento podprogram je první ze čtyř podprogramů používaných hlavními aritmetickými podprogramy pro: odčítání, sčítání, násobení a dělení. Podprogram připraví FP-ČÍSLO pro sčítání tím, že nahradí jeho znaménkový bit skutečným číselným bitem logické úrovně 1 a provede negaci čísla (dvojkovou komplementací) je-li záporné. Exponent se vrací v registru A a první bajt je nastaven na #00 pro kladné číslo a #FF pro záporné číslo. 2F9B
PREP-ADD
2FAF
NEG-BYTE
178
LD LD AND RET INC BIT SET DEC RET PUSH LD ADD LD LD SCF DEC LD CPL
A,(HL) (HL),#00 A Z HL 7,(HL) 7,(HL) HL Z BC BC,#0005 HL,BC B,C C,A HL A,(HL)
Převeď exponent do A. Předpokládej kladné číslo. Je-li číslo nulové je příprava skončena. Nyní ukazuj na znaménkový bajt. Nastav Z flag pro pozitivní číslo. Obnov skutečný číselný bit 7. Ukazuj znovu na první bajt. Kladná čísla jsou o.k., ale záporná se musí invertovat. Uschovej jakýkoliv dřívější doplněk. Bude zpracováno pět bajtů. Ukazuj jedno místo za poslední bajt. Převeď 5 do B. Uschovej exponent v C. Nastav CY=1. Ukazuj postupně na všechny bajty. Vyzvedni každý bajt. Jedničkový doplněk bajtu. Komentovaný výpis paměti ROM
ADC LD DJNZ LD POP RET
A,#00 (HL),A #2FAF,NEG-BYTE A,C BC
Přičti CY pro negaci. Obnov bajty. Smyčka proběhne 5-krát. Obnov exponent v A. Obnov jakékoliv dřívější exponenty. Hotovo.
PODPROGRAM "FETCH TWO NUMBERS" Podprogram je volán z programů ADDITION MULTIPLICATION a DIVISI0N k vyzvednutí dvou čísel ze zásobníku kalkulátoru a jejich uložení do registrů včetně zrcadlových. Na vstupu ukazuje HL na první bajt prvého čísla a DE ukazuje na první bajt druhého čísla. Při násobení nebo dělení je znaménko výsledku umístěno v druhém bajtu prvního čísla. 2FBA
FETCH-TWO
PUSH PUSH
HL AF
Uschovej HL. Uschovej AF.
Pět bajtů prvního čísla bude: M1, M2, M3, M4 a M5. LD INC LD LD INC LD LD PUSH INC LD INC LD EX LD LD PUSH INC LD INC LD PUSH EXX POP POP POP EXX INC LD INC LD POP POP RET
C,(HL) HL B,(HL) (HL),A HL A,C C,(HL) BC HL C,(HL) HL B,(HL) DE,HL D,A E,(HL) DE HL D,(HL) HL E,(HL) DE DE HL BC HL D,(HL) HL E,(HL) AF HL
Pět bajtů druhého čísla bude: N1, N2, N3, N4 a N5. M1 do C. Další. M2 do B. Kopíruj znaménko výsledku do (HL). Další. M1 do A. M3 do C. Uschovej M2 a M3 na zásobník. Další. M4 do C. Další. M5 do B. HL nyní ukazuje na N1. M1 do D. N1 do E. Uschovej M1 a N1 na zásobník. Další. N2 do D. Další. N3 do E. Uschovej N2 a N3 na zásobník. Přepni na zrcadlové registry. N2 do D' N3 do E' M1 do H' N1 do L' M2 do B' M3 do C' Přepni na původní registry. Další. N4 do D. Další. N5 do E. Obnov AF. Obnov HL. Vrať se.
Shrnutí: M1 - M5 jsou v H',B',C',C,B N1 - N5 jsou v L',D',E',D,E HL ukazuje na první bajt prvního čísla.
Komentovaný výpis paměti ROM
179
PODPROGRAM "SHIFTOVANÝ SČÍTANEC" Tento podprogram posunuje FP-číslo až o 32 míst doprava, čímž ho správně nastaví do pozice potřebné pro sčítání. Číslo s menším exponentem již bylo takto ošetřeno před zavoláním tohoto podprogramu. Jakékoliv přečtení doprava (do CY) je přičteno zpět k číslu. Je-li rozdíl exponentů větší než 32, nebo CY přetéká na začátek čísla, je toto číslo nastaveno na nulu tak, aby sčítání nezměnilo druhého sčítance. 2FDD
SHIFT-FP
2FE5
ONE-SHIFT
2FF9
ADDEND-0
2FFB
ZEROS-4/5
AND RET CP JR PUSH LD EXX SRA RR RR EXX RR RR DJNZ POP RET CALL RET EXX XOR LD LD LD EXX LD RET
A Z #21 NC,#2FF9,ADDEND-0 BC B,A L D E D E #2FE5,ONE-SHIFT BC NC #3004,ADD-BACK NZ A L,#00 D,A E,L
Při nulovém rozdílu exponentů se vrať. Je-li rozdíl exponentů větší než #20, skoč dopředu. Krátce uschovej BC. Rozdíl exponentů do B jako čítač posunů. Přepni zrcadlové registry. Posuň aritmeticky doprava L' a zachovej znaménkový bit. Rotuj doprava s CY registry D',E' a dále D a E. Tímto se všech pět bajtů čísla posune B-krát doprava. Skákej zpět do vynulování B. Obnov původní BC. Hotovo, nedošlo-li k přetečení. Přičti zpět CY. Vrať se, pokud CY nepřepadlo hned zpět. Přepni zrcadlové registry. Vynuluj A. Nastav sčítance na nulu v D’,E‘,D a E včetně znaménkového bajtu L'. Při zavolání z #3160 se vynulují pouze čtyři bajty.
DE,#0000
PODPROGRAM "ADD BACK" (=ZPĚTNÉ PŘIČTENÍ) Podprogram přičítá zpět k číslu každé CY, které přeteklo doprava. V extrémním případě se CY vrací nalevo do čísla. Pokud je podprogram volán během sčítání, znamená tento extrém, že mantisa 0.5 byla posunuta o 32 míst doprava a sčítanec bude nastaven na nulu. Při zavolání z podprogramu MULTIPLICATI0N znamená tento extrém, že exponent musí být inkrementován, což může způsobit přetečení. 3004
300D
180
ADD-BACK
ALL-ADDED
INC RET INC RET EXX INC JR INC EXX RET
E NZ D NZ E NZ,#300D,ALL-ADDED D
Přičti CY k poslednímu bajtu. Vrať se, nedošlo-li k přetečení doleva. Pokračuj na další bajt. Vrať se, nedošlo-li k přetečení doleva. Pokračuj na další bajt. Také jej inkrementuj. Skoč nedošlo-li k přetečení doleva. Inkrementuj poslední bajt. Obnov hlavní registry. Vrať se.
Komentovaný výpis paměti ROM
OPERACE SUBTRACTION (=ODEČÍTÁNÍ) Doplněk: #03 "subtract" Tento podprogram jednoduše mění znaménko menšitele a pokračuje dále do ADDITION. Povšimněte si, že HL ukazuje na menšence a DE na menšitele. 300F
SUBTRACT
EX CALL EX
DE,HL #346E,NEGATE DE,HL
Zaměň ukazatele. Změň znaménko menšitele. Zaměň ukazatele zpět a pokračuj do ADDITION.
OPERACE ADDITION (=SČÍTÁNÍ) Doplněk: #0F "addition" První ze tří hlavních aritmetických podprogramů provádí sčítání dvou čísel v FP formě, každé s čtyřbajtovou adresou a jednobajtovým exponentem. V těchto třech podprogramech jsou dvě čísla na vrcholku zásobníku kalkulátoru sečtena, násobena nebo dělena. Výsledkem je pak jedno číslo na vrcholku zásobníku kalkulátoru, čili "poslední hodnota". HL ukazuje na druhé číslo odshora, což je buďto sčítanec, násobitel nebo dělenec. DE ukazuje na číslo na vrcholu zásobníku, což je sčítanec, násobenec nebo dělitel. Po ukončení podprogramu HL ukazuje na výsledek, což je poslední hodnota, jejíž hodnota může být považována za STKEND-5. Ale podprogram sčítání nejdříve testuje, zda následující dvě sčítaná čísla jsou "malá celá číslice". Je-li tomu tak, je jednoduše sečteno HL a BC, a výsledek je uložen na zásobník. Před nebo po sčítání není prováděna dvojková komplementace, neboť čísla, která tuto komplementaci vyžadují, už jsou uložena na zásobníku v potřebném tvaru a připravená ke sčítání. 3014
ADDITION
LD OR JR PUSH INC PUSH INC LD INC LD INC INC INC LD INC LD INC LD POP EX ADD EX ADC RRCA ADC JR SBC LD INC LD INC LD DEC DEC DEC
A,(DE) (HL) NZ,#303E,FULL-ADDN DE HL HL HL E,(HL) HL D,(HL) HL HL HL A,(HL) HL C,(HL) HL B,(HL) HL DE,HL HL,BC DE,HL A,(HL)
Nejsou-li oba první bajty sčítaných čísel nulové, skoč na plné sčítání. Uschovej ukazatel na druhé číslo. Ukazuj na druhý bajt prvního čísla a uschovej i tento ukazatel. Ukazuj na méně významný bajt. Vyzvedni ho do E a
A,#00 NZ,#303C,ADDN-OFLW A,A (HL),A HL (HL),E HL (HL),D HL HL HL
Nenulové A indikuje přetečení. Obnov ukazatele proveď plné sečtení. Nastav správný znaménkový bajt pro výsledek. Ulož jej do zásobníku. Ukazuj na další místo. Ulož nižší a
Vyzvedni významnější bajt.
Posuň se na další bajt druhého čísla Vyzvedni ho do A (znaménkový bajt). Vyzvedni méně a více významné bajty. Vyzvedni ukazatel na znaménkový bajt prvního čísla. Vlož jej do DE a číslo do HL. Proveď sečtení s výsledkem v HL. Výsledek do DE a adresa znaménkového bajtu do HL. Přičti znaménkové bajty a CY do registru A.
vyšší bajt výsledku. Přesuň ukazatel zpět na pozici prvního bajtu.
Komentovaný výpis paměti ROM
181
POP RET
DE
Obnov STKEND do registru DE Hotovo.
Poznámka: Povšimněte si, že číslo -65536 zde může nabýt tvaru 00 FF 00 00 00 jako výsledek sčítání dvou menších záporných celých čísel, např: -65000-536 je jednoduše uložen v této formě, což je chyba. Systém SPECTRA nemůže zpracovat toto číslo. Většina funkcí je považuje za nulu a číslo je vypsáno jako -1E-38 nebo-li jako -0 v tomto nevhodném formátu. 303C
ADDN-OFLW
303E
FULL-ADDN
DEC POP CALL
HL DE #3293,RE-ST-TWO
Obnov ukazatel na první číslo. Obnov ukazatel na druhé číslo. Proveď opětovné uložení obou čísel na zásobník.
Podprogram "plného sčítání" nejprve volá PREP-ADD pro každé číslo, potom vezme dvě čísla ze zásobníku kalkulátoru a uloží číslo s menším exponentem na pozici sčítance, dále volá SHIFT-FP k posunutí sčítance až o 32 míst doprava pro nastavení správné pozice ke sčítání. Vlastní součet proběhne v několika bajtech a při přetečení je proveden jednoduchý posun. Výsledek je dvojkově komplementován při záporném čísle a v případě, že nebylo hlášeno aritmetické přeplnění, jinak podprogram pokračuje do TEST-NORM, aby byl normalizován výsledek před jeho uložením na zásobník se správným znaménkovým bitem vloženým do druhého bajtu.
3055
182
SHIFT-LEN
EXX PUSH EXX PUSH PUSH CALL LD EX CALL LD CP JR LD LD EX PUSH SUB CALL CALL POP POP LD PUSH LD LD ADD EXX EX ADC EX LD ADC LD RRA XOR EXX EX POP
HL DE HL #2F9B,PREP-ADD B,A DE,HL #2F9B,PREP-ADD C,A B NC,#3055,SHIFT-LEN A,B B,C DE,HL AF B #2FBA,FETCH-TWO #2FDD,SHIFT-FP AF HL (HL),A HL L,B H,C HL,DE DE,HL HL,BC DE,HL A,H A,L L,A
Zaměň registry. Uschovej adresu dalšího literálu. Zaměň registry. Uschovej ukazatel na 2.sčítanec. Uschovej ukazatel na 1.sčítanec. Připrav 1.sčítanec a uschovej jeho exponent v B. Zaměň ukazatele. Připrav 2.sčítanec a uschovej jeho exponent v C. Jestliže první exponent je menší ponech první číslo na pozici 2.sčítance, jinak zaměň exponenty a ukazatele. Uschovej větší z exponentů v A. Rozdíl mezi exponenty je délkou pro posun doprava. Vyzvedni dvě čísla ze zásobníku. Posuň 2.sčítanec doprava. Obnov větší exponent a HL ukazuje na výsledek. Ulož exponent výsledku. Opět uschovej ukazatel. M4 do H a M5 do L (viz FETCH-TWO). Přičti dva pravé bajty N2 do H' a N3 do L' (viz FETCH-TWO).
L
Přičti levé bajty plus CY. Výsledek zpět do D',E'. Sečti H'L' a CY: tento mechanismus zajistí, že bude zavolán jeden posuv doprava pokud součet kladných čísel způsobil přetečení doleva, nebo součet dvou záporných čísel nezpůsobil přetečení doleva.
DE,HL HL
Výsledek jde nyní do DE a DE'. Vyzvedni ukazatel na exponent. Komentovaný výpis paměti ROM
307C
TEST-NEG
309F
ADD-REP-6
30A3
END-COMPL
30A5
GO-NC-MLT
RRA JR LD CALL INC JR EXX LD AND EXX INC LD DEC JR LD NEG CCF LD LD CPL ADC LD EXX LD CPL ADC LD LD CPL ADC JR RRA EXX INC JP EXX LD EXX XOR JP
NC,#307C,TEST-NEG A,#01 #2FDD,SHIFT-FP (HL) Z,#309F,ADD-REP-6 A,L #80 HL (HL),A HL Z,#30A5,GO-NC-MLT A,E
Test na posun (H'L' byly #00 pro kladná čísla a #FF pro záporná čísla). A je čítač jednoho posunu doprava. Zavolej posun. Přičti jedničku k exponentu; toto může způsobit aritmetické přetečení. Test na negativní výsledek. Vyzvedni znaménkový bit z L' do A (což správně indikuje znaménko výsledku).
(HL) Z,#31AD,REPORT-6
Ulož jej do druhého bajtu výsledku na zásobníku kalkulátoru. Byl-li nulový neprováděj dvojkový doplněk výsledku. Vyzvedni 1.bajt. Neguj jej. Komplementuj CY pro pokračující negaci a uschovej tento bajt. Vezmi další bajt a proveď dvojkový doplněk. Přičti CY pro negaci. Uschovej tento bajt. Vyzvedni další bajt do A z E. Proveď komplementaci. Přičti CY pro negaci. Uschovej bajt. Vyzvedni poslední bajt a komplementuj ho. Přičti CY pro negaci. Pokud nedošlo k přetečení, je hotovo. Dej 0.5 do mantisy a přičti jedničku k exponentu (to je třeba tehdy, je-li výsledek součtu dvou čísel přesný násobek dvou). Ohlaš chybu, je-li třeba.
D,A
Uschovej poslední bajt.
A #3155,TEST-NORM
Vynuluj CY. Vrať se přes TEST-NORM.
E,A A,D A,#00 D,A A,E A,#00 E,A A,D A,#00 NC,#30A3,END-COMPL
PODPROGRAM "HL=HL*DE" Podprogram je volán podprogramem "GET-HL*DE" a MULTIPLICATION, aby provedl násobení. Každé přetečení na 16.bitu se zpracuje po návratu z tohoto podprogramu. 30A9
HL=HL*DE
30B1
HL-LOOP
PUSH LD LD LD LD ADD JR RL RLA JR ADD JR
BC B,#10 A,H C,L HL,#0000 HL,HL C,#30BE,HL-END C NC,#30BC,HL-AGAIN HL,DE C,#30BE,HL-END
16-ti
bitové
Uschovej BC. Jedná se o 16-bitové násobení. A obsahuje vyšší bajt. C obsahuje nižší bajt. Nastav výsledek na nulu. Zdvojení výsledku. Skok při přetečení. Rotuj bit 7 registru C do CY. Rotuj CY do bitu 0 registru A a bit 7 do CY. Při nulovém CY skoč. Jinak přičti DE a skoč při přetečení.
Komentovaný výpis paměti ROM
183
30BC 30BE
HL-AGAIN HL-END
DJNZ #30B1,HL-LOOP POP BC RET
Dokud neproběhlo 16 průchodů, pokračuj. Obnov BC. Hotovo.
PODPROGRAM PŘÍPRAVY NA NÁSOBENÍ NEBO DĚLENÍ Tento podprogram připravuje FP-číslo pro násobení nebo dělení a vrací CY=1 bylo-li číslo nulové. Znaménko výsledku je v registru A a znaménkový bit čísla je nahrazen skutečným numerickým bitem s hodnotou 1. 30C0
PREP-M/D
CALL RET INC XOR SET DEC RET
#34E9,TEST-ZERO C HL (HL) 7,(HL) HL
Jestli-že číslo je nulové, vrať se s CY=1. Ukazuj na znaménkový bajt, vyzvedni znaménko výsledku do A a současně nuluj CY. Nastav pravdivý numerický bit. Opět ukazuj na exponent. Vrať se s nulovým CY.
OPERACE NÁSOBENÍ Doplněk: #04 "multiply" Tento podprogram nejprve zjistí, zda násobená čísla jsou malá celá čísla, a je-li to pravda, použije se k vyzvednutí těchto čísel ze zásobníku podprogram INT-FETCH. Pak se provede HL=HL*DE a INT-STORE k uložení výsledku na zásobník. Každé přetečení při tomto "krátkém" násobení (tedy pokud již výsledek není "malé" celé číslo) způsobí skok na násobení v pětibajtové FP formě. 30CA
MULTIPLY
30E5
30EA
MULT-RSLT
30EF 30F0
MULT-OFLW MULT-LONG
LD OR JR PUSH PUSH PUSH CALL EX EX LD CALL LD XOR LD POP CALL EX POP JR LD OR JR LD CALL POP RET POP CALL
A,(DE) (HL) NZ,#30F0,MULT-LONG DE HL DE #2D7F,INT-FETCH DE,HL (SP),HL B,C #2D7F,INT-FETCH A,B C C,A HL #30A9,HL=HL*DE DE,HL HL C,#30EF,MULT-OFLW A,D E NZ,#30EA,MULT-RSLT C,A #2D8E,INT-STORE DE DE #3293,RE-ST-TWO
Nejsou-li první bajty obou čísel nulové, skoč na "dlouhé" násobení. Uschovej ukazatel na druhé, první a opět na druhé číslo. Vyzvedni znaménko v registru C a číslo v registru DE. Číslo do HL a hned na zásobník, druhý ukazatel do HL. Uschovej první znaménko v B. Vyzvedni druhé znaménko do C a číslo v registru DE. Vytvoř znaménko výsledku v registru A. Ulož je do C. Obnov první číslo v HL. Proveď skutečné násobení. Uschovej výsledek v DE. Obnov ukazatel na první číslo. Pokud došlo k přetečení, skoč na plné násobení. Těchto 5 bajtů zajistí, že 00 FF 00 00 00 je nahrazeno nulou (nebylo by třeba, pokud by toto číslo bylo vyloučeno ze systému). Nyní ulož výsledek na zásobník. Obnov STKEND do DE. Hotovo. Obnov ukazatele na druhé číslo. Proveď "znovu uložení" čísel v plné FP formě (5 bajtů).
Podprogram "plného násobení připraví první číslo pro násobení voláním PREP-M/D, s návratem v případě nuly. Jinak se také připraví druhé číslo voláním PREP-M/D a jestliže je nulové, podprogram nastaví hodnotu výsledku na nulu. Dále se vyzvednou dvě čísla ze zásobníku kalkulátoru a jejich 184
Komentovaný výpis paměti ROM
mantisy jsou vynásobeny obvyklým způsobem, tj. rotací prvního čísla (což je násobitel) doprava a přičtením druhého čísla (což je násobenec) k výsledku v případě, že bit násobitele byl nastaven. Potom jsou sečteny exponenty a testuje se přetečení a podtečení (což dává výsledek nula). Na závěr je výsledek normalizován a uložen na zásobník kalkulátoru se správným znaménkovým bitem v druhém bajtu. XOR CALL RET EXX PUSH EXX PUSH EX CALL EX JR PUSH CALL LD AND SBC EXX PUSH SBC EXX LD JR
A #30C0,PREP-M/D C HL DE DE,HL #30C0,PREP-M/D DE,HL C,#315D,ZERO-RSLT HL #2FBA,FETCH-TWO A,B A HL,HL HL HL,HL B,#21 #3125,STRT-MLT
A=0, takže znaménko prvního čísla jde do A. Připrav první číslo a jestliže je nulové, vrať se (výsledek je již nula). Zaměň registry. Uschovej adresu dalšího literálu. Zaměň registry. Uschovej ukazatel na násobenec. Zaměň ukazatele. Připrav druhé číslo a opět zaměň ukazatele. Byl-li výsledek nula, skoč dopředu. Uschovej ukazatel na výsledek. Vyzvedni dvě čísla ze zásobníku. M5 do A (viz FETCH-TWO). Příprava na odečítání. Nuluj HL pro výsledek. Zaměň registry. Uschovej M1 a N1 (viz FETCH-TWO). Nuluj H'L' pro výsledek. Zaměň registry. B obsahuje #21 pro 33 posunů. Proveď smyčku.
Zde začíná smyčka pro násobitel. 3114
311B
3125
MLT-LOOP
NO-ADD
STRT-MLT
JR ADD EXX ADC EXX EXX RR RR EXX RR RR EXX RR RR EXX RR RRA DJNZ EX EXX EX EXX
NC,#311B,NO-ADD HL,DE
Nedošlo-li k přetečení, skoč na NO-ADD. Jinak přičti násobenec D'E',DE (FETCH-TWO) do výsledku který je vytvářen v H'L' a HL.
HL,DE
H L
Ať už byl nebo nebyl násobenec přičten, posuň výsledek v H'L'HL doprava tak, že každý bit, který ukápne do CY je okamžitě přijat dalším bajtem a
H L B C C
posun pokračuje do B'C' a CA (viz FETCH-TWO a dále).
#3114,MLT-LOOP DE,HL
Poslední bit, který zůstane v CY vyvolá další přičtení násobence k výsledku. Proveď 33-krát tuto smyčku čímž se posoudí všechny bity. Přenes výsledek z
DE,HL
H'L'HL do D'E'DE.
Sečti oba exponenty. POP POP LD
BC HL A,B
Obnov exponenty M1 a N1. Obnov ukazatel na exponentový bajt. Vytvoř součet dvou exponentů v A a
Komentovaný výpis paměti ROM
185
313B
MAKE-EXPT
ADD JR AND DEC CCF
A,C NZ,#313B,MAKE-EXPT A A
oprav CY tak, že nebyl-li součet nulový, nech CY být. Jinak CY vynuluj. Připrav se na zvětšení exponentu o #80.
Zbytek podprogramu je společný jak pro násobení tak pro dělení. 313D
3146
3151
DIVN-EXPT
OFLW-1-CLR
OFLW-2-CLR
Zbytek podprogramy.
RLA CCF RRA JP JR AND INC JR JR EXX BIT EXX JR LD EXX LD EXX
tohoto
3155
TEST-NORM
3159
NEAR-ZERO
315D 315E
ZERO-RSLT SKIP-ZERO
JR LD AND LD JR XOR EXX AND CALL RLCA LD JR INC LD DEC JR
P,#3146,OFLW-1-CLR NC,#31AD,REPORT-6 A A NZ,#3151,OFLW-2-CLR C,#3151,OFLW-2-CLR 7,D NZ,#31AD,REPORT-6 (HL),A A,B
podprogramu
ošetřuje
Těchto pár bajtů rafinovaně vytváří správný exponentový bajt. Rotací registru A doleva a doprava vznikne exponent (skutečný exponent + #80) v A. Je-li P flag nulový není třeba hlásit žádnou chybu. Ohlaš přetečení, jestliže CY=0. Vynuluj CY. Exponentový bajt je kompletní. Je-li A nulové, je potřebný další test na přetečení. Je-li CY=0 a výsledek je již v norm. formě (bit 7 D' je nastaven), pak došlo k přet., které je nutno ohlásit Ale když bit 7 registru D'=0, pak je výsledek v rozsahu, tj. pod hodnotou 2^127. Ulož exponentový bajt. Předej pátý bajt výsledku pro normal. sekvenci, tedy přetečení z L do B'.
normalizaci
a
je
společný
pro
všechny
aritmetické
NC,#316C,NORMALISE A,(HL) A A,#80 Z,#315E,SKIP-ZERO A
Je-li CY=0, normalizuj. Jinak ošetři podtečení (nulový výsledek) nebo téměř podtečení (výsledek 2^-128). Vrať exponent do A a testuj, je-li registr A nulový (pro případ 2^-128) Je-li to pravda, vytvoř 2^-128 v případě normálního čísla, nebo
D #2FFB,ZEROS-4/5
produkuj nuly. Exponent musí být nulový (pro nulu) nebo 1 (pro 2^-128).
(HL),A C,#3195,OFLOW-CLR HL (HL),A HL #3195,OFLOW-CLR
Obnov exponentový bajt. Skoč v případě 2^-128. Jinak do druhého bajtu výsledku na kalkulátorovém zásobníku vlož nulu a převeď výsledek.
Aktuální normalizační operace. 316C 316E
186
NORMALISE SHIFT-ONE
LD EXX BIT EXX JR RLCA RL RL EXX RL
B,#20 7,D NZ,#3186,NORML-NOW E D E
Normalizuj výsledek až 32 posuny doleva v D'E'D E přidáním A dokud bit 7 v registru D' není nastaven na nulu. Registr A obsahuje nulu po sčítání a proto nedojde k žádné změně přesnosti. A obsahuje 5.bajt z registru B' po násobení nebo dělení, ale protože se bere v úvahu vždy jen 32 bitů, nedojde k žádné změně přesnosti. Povšimněte si, že Komentovaný výpis paměti ROM
RL EXX DEC JR DJNZ JR
D (HL) Z,#3159,NEAR-ZERO #316E,SHIFT-ONE #315D,ZERO-RSLT
A je rotováno kruhově s odbočkou při přetečení .... eventuálně náhodný proces. Při každém posunu je dekrementován exponent. Je-li exponent=0, je 2^-129 zaokrouhleno na 2^-128. 32-krát do smyčky. Nebyl-li bit 7 registru D' nikdy 1 je celý výsledek nula.
Ukonči normalizaci posouzením CY. 3186
NORML-NOW
RLA JR CALL JR EXX LD EXX INC JR
NC,#3195,OFLOW-CLR #3004,ADD-BACK NZ,#3195,OFLOW-CLR
Po normalizaci přičti zpět jakékoliv závěrečné CY, které vstoupilo do A. Nepřetéká-li CY hned zpět, skoč dopředu. V opačném případě nastav mantisu na 0.5
D,#80 (HL) Z,#31AD,REPORT-6
a inkrementuj exponent. Tato akce může vést k aritmetickému přetečení.
Závěrečná část tohoto podprogramu slouží k předání výsledku do bajtů rezervovaných pro výsledek na zásobníku kalkulátoru a k opětovnému nastavení ukazatelů. 3195
31AD
OFLOW-CLR
REPORT-6
PUSH INC EXX PUSH EXX POP LD RLA RL RRA LD INC LD INC LD INC LD POP POP EXX POP EXX RET RST DEFB
HL HL
Uschovej ukazatel výsledku. Ukazuj na znaménkový bajt výsledku. Výsledek je přesunut z registrů D'E'D E
DE BC A,B (HL) (HL),A HL (HL),C HL (HL),D HL (HL),E HL DE HL
#08,ERROR-1 #05
do BCDE a pak do ACDE. Znaménkový bit je vyzvednut ze svého předchozího uložení a přenese na správnou pozici v bitu 7 1. bajtu mantisy. Je vložen 1.bajt. Další. Je vložen 2.bajt. Další. Je vložen 3.bajt. Další. Je vložen 4.bajt. Obnov ukazatel na výsledek. Obnov ukazatel na druhé číslo. Zaměň registry. Obnov adresu dalšího literálu. Zaměň registry. Hotovo. Ohlaš: 6-Number too big
OPERACE DĚLENÍ Doplněk: #05 "division" Tento podprogram nejprve připraví dělitel voláním PREP-M/D a hlásí aritmetické přeplnění, je-li dělitel nulový, dále připraví dělenec opětovným voláním PREP-M/D, s návratem v případě nuly. Dále vyzvedne dvě čísla ze zásobníku kalkulátoru a dělí jejich mantisy pomoci běžného dělení tj. zkušebním odečtem dělitele od dělence a jejich obnovením při přetečení. Jinak se přičte jednička k podílu. Maximální přesnost se dosahuje u čtyřbajtového dělení. Po odečtení exponentu se podprogram napojuje v místě, které je společné pro dělení a násobení a je na adrese #313D DIVN-EXPT.
Komentovaný výpis paměti ROM
187
31AF
31D2
31DB
31E2
31F2
31F9 31FA
188
DIVISION
CALL EX XOR CALL JR EX CALL RET EXX PUSH EXX PUSH PUSH CALL EXX PUSH LD LD EXX LD LD XOR LD JR
#3293,RE-ST-TWO DE,HL A #30C0,PREP-M/D C,#31AD,REPORT-6 DE,HL #30C0,PREP-M/D C HL DE HL #2FBA,FETCH-TWO HL H,B L,C H,C L,B A B,#DF #31E2,DIV-START
Zde začíná dělící smyčka. DIV-LOOP RLA RL C EXX RL C RL B EXX DIV-34TH ADD HL,HL EXX ADC HL,HL EXX JR C,#31F2,SUBN-ONLY DIV-START SBC HL,DE EXX SBC HL,DE EXX JR NC,#31F9,NO-RSTORE ADD HL,DE EXX ADC HL,DE EXX AND A JR #31FA,COUNT-ONE SUBN-ONLY AND A SBC HL,DE EXX SBC HL,DE EXX NO-RSTORE SCF COUNT-ONE INC B JP M,#31D2,DIV-LOOP PUSH AF JR Z,#31E2,DIV-START
Použij FP formy. Zaměň ukazatele. A je vynulováno a znaménko 1.čísla jde do A. Připrav dělitele a ohlaš aritmetické přeplnění v případě, že dělitel je nulový. Zaměň ukazatele. Připrav dělence a je-li nulový, vrať se. Zaměň registry. Uschovej adresu dalšího literálu. Zaměň registry. Uschovej ukazatel na dělitel. Uschovej ukazatel na dělenec. Vyzvedni dvě čísla ze zásobníku. Zaměň registry. Uschovej H1 a N1 na zásobník. Kopíruj čtyři bajty dělence z registrů B'C'C B (tedy M2,M3,M4 a M5) do registrů H'L'H L.
Nuluj registry A a CY. B bude počítat od -33 do -1 dvojkové doplňky. Skoč do dělící smyčky pro první zkušební odečet.
Posuň výsledek doleva v B'C'C A za pomoci CY.
Posuň zbytek dělence zprava doleva v H'L'HL před dalším pokusným odečtem. Jestliže bit přetekl do CY, skoč dopředu. Zkušební odečet dělitele v D'E'DE od zbytku dělence v H'L'HL (je zajištěno CY=0 před prvním odečtem, viz předchozí krok). Nedošlo-li k přetečení, skoč dopředu. Jinak obnov tj. přičti zpět dělitel
Protože dělitel nepasuje, vynuluj CY, aby nebyl žádný bit pro podíl. Skoč dopředu. Proveď pouhé odečtení bez obnovení a pokračuj na nastavení CY, protože ztracený bit dělence musí být obnoven a použit pro podíl. Jednička pro podíl B'C'C A. Inkrementace čítače pro každý průchod smyčkou, které je provedena 32-krát pro všechny bity. Uschovej každý 33.bit pro přesnost (aktuální CY). Ještě jeden zkušební odečet pro každý 34.bit Komentovaný výpis paměti ROM
Poznámka: Skok je proveden do špatného místa. 34.bit se nikdy nezíská pokud se nebude posouvat dělenec. Proto například důležité výsledky jako 1/10 a 1/1000 nejsou zaokrouhleny tak, jak by měli být. Zaokrouhlení se nikdy neprovede pokud záleží na 34.bitu. Skok měl být na #31DB DIV-34TH tedy bajt #3200 měl, obsahovat hodnotu #DA místo hodnoty #E1. LD LD EXX LD LD POP RR POP RR EXX POP POP LD SUB JP
E,A D,C
Nyní přesuň čtyři bajty tvořící mantisu výsledku z B'C'C A do D'E'D E.
E,C D,B AF B AF B
Potom ulož 34. a 33. bit do B' aby byly později při normalizaci vyzvednuty.
BC HL A,B C #313D,DIVN-EXPT
Obnov exponentové bajty M1 a N1. Obnov ukazatel na výsledek. Vlož do A rozdíl mezi dvěma exponentovými bajty s nastavením CY v případě potřeby. Výstup přes DIVN-EXPT.
ODŘÍZNUTÍ DESETINNÉ ČÁSTI ČÍSLA Doplněk: #3A "truncate" Podprogram vrací výsledek po odříznutí desetinné části čísla x jako poslední hodnotu na zásobníku kalkulátoru. Například T(2.4)=2 a také T(-2.4)=-2. Podprogram se okamžitě vrací v tom případě, kdy x je ve formě "malého" celého čísla. Nula je použita jako výsledek, jestliže exponentový bajt je menší než #81 (neboť ABS x < 1). Jestliže x je "malé" celé číslo, nebo exponentový bajt je větší než #AO, pak je x podprogramem vráceno ve své původní formě. V ostatních případech je nastaven správný počet bajtů čísla x na nulu a v případě potřeby je další bajt rozdělen maskou. 3214
TRUNCATE
3221
T-GR-ZERO
LD AND RET CP JR LD LD JR CP JR
A,(HL) A Z #81 NC,#3221,T-GR-ZERO (HL),#00 A,#20 #3272,NIL-BYTES #91 NZ,#323F,T-SMALL
Vyzvedni exponentový bajt čísla x do registru A. Je-li A nula, vrať se, neboť x je již "malé" celé číslo. Je-li exponent větší než #80, skoč. Jinak nastav exponent na nulu. Ulož 32 do registru A. Za pomoci NIL-BYTES vynuluj všechny bajty čísla x. Jestliže se exponent nerovná #91, skoč.
Dalších 26 bajtů je zde proto, aby otestovalo, zda x náhodou není rovno číslu -65536 (#: 91 80 00 00 00). V případě pozitivního výsledku porovnání jsou tyto bajty přepsány na #: 00 FF 00 00 00. A to je CHYBA! Jak již bylo řečeno okolo adresy #303B, není systém SPECTRA schopen takové číslo zpracovat. Zde je vlastně provedeno INT(-65536) a jako výsledek je vytvořena hodnota -1. To je škoda, protože kdyby se s číslem nic nedělalo, bylo by vše v perfektním pořádku. Jednoduchou nápravou by bylo vynechání 28 bajtů od adresy #3223 do adresy #323E. INC INC INC LD AND DEC OR DEC
HL HL HL A,#80 (HL) HL (HL) HL
HL ukazuje na 4. bajt x kde končí 17 bitů celočíselné části čísla x za prvním bitem. První bit je vyzvednut do registru A s použitím masky #80. Tento a předchozích 5 bitů je společně testováno na nulu. HL ukazuje na druhý bajt x.
Komentovaný výpis paměti ROM
189
3233
T-FIRST
JR LD XOR DEC JR LD INC LD DEC LD JR
NZ,#3233,T-FIRST A,#80 (HL) HL NZ,#326C,T-EXPNENT (HL),A HL (HL),#FF HL A,#18 #3272,NIL-BYTES
Test končí, nebyla-li nalezena nula. Jinak test na hodnotu -65536: sled čísel #:91 80 00 00 00 je ukončen a ponechá Z flag nastaven. HL ukazuje na první bajt x. Je-li Z flag nulový, provede se skok. První bajt je nastaven na nulu a HL ukazuje na druhý bajt. Druhý bajt bude #FF a HL opět ukazuje na první bajt. Je vynulováno posledních 24 bitů pomocí NIL-BYTES, se dokončí stvoření 00 FF 00 00 00.
Leží-li exponentový bajt čísla x v rozsahu #81 až #90 včetně, potom T(x) je "malým" celým číslem a bude kompresováno do jednoho nebo dvou bajtů. ALe nejdříve se otestuje velikost x. 323F
T-SMALL
3252
T-NUMERIC
325E
T-TEST
3261
T-SHIFT
3267
T-STORE
JR
NC,#326D,X-LARGE
PUSH CPL ADD INC LD INC LD DEC DEC LD BIT JR DEC SET LD SUB ADD JR LD LD SUB JR LD SRL RR DJNZ CALL POP RET
DE A,#91 HL D,(HL) HL E,(HL) HL HL C,#00 7,D Z,#3252,T-NUMERIC C 7,D B,#08 B A,B C,#325E,T-TEST E,D D,#00 B Z,#3267,T-STORE B,A D E #3261,T-SHIFT #2D8E,INT-STORE DE
Skoč s exponentovým bajtem #92 a více (bylo by lepší testovat hodnotu #91). Uschovej STKEND v DE. Rozsah 129<=A<=144 je převeden na 126>=A>=111. Rozsah je nyní 15>=A>=0. HL ukazuje na druhý bajt a ten je přenesen do D. Třetí bajt do E. HL opět ukazuje na první bajt. Předpokládej kladné číslo. Testuj záporné číslo (bit 7 registru D je 1) Při kladném čísle skoč. Změň znaménko. Vlož skutečný numerický bit do registru D. Testuj, zda A>=8 (jen jeden bajt), nebo je-li třeba dvou bajtů. Ponech A nezměněné. Skoč, jsou-li potřeba dva bajty. Dej jeden bajt do E Nastav D na nulu. Nyní 1<=A<=7 počítá potřebné posuny. Není-li nutný posun skoč. B bude počítat posuvy. Posunuj B-krát doprava D a E. aby vzniklo správné číslo. Opakuj do vynulování B. Uschovej výsledek na zásobník. Obnov STKEND v DE. Hotovo.
Zbývá posoudit velké hodnoty čísla x. 326C 326D
T-EXPNENT X-LARGE
LD SUB RET NEG
A,(HL) #A0 P
Vyzvedni exponentový bajt čísla x do registru A. Odečti 160=#A0 od exponentu. Při plus se vrať - x má nevýznamnou celočíselnou část. Jinak neguj zbytek, čímž získáš počet nulových bitů.
Zde budou vynulovány bity mantisy. 3272
190
NIL-BYTES
PUSH DE EX DE,HL
Uschovej aktuální hodnotu DE (STKEND). HL ukazuje jedno místo za pátý bajt. Komentovaný výpis paměti ROM
327E
BYTE-ZERO
3283
BITS-ZERO
328A
LESS-MASK
3290
IX-END
DEC LD SRL SRL SRL JR LD DEC DJNZ AND JR LD LD SLA DJNZ AND LD EX POP RET
HL B,A B B B Z,#3283,BITS-ZERO (HL),#00 HL #327E,BYTE-ZERO #07 Z,#3290,IX-END B,A A,#FF A #328A,LESS-MASK (HL) (HL),A DE,HL DE
a následovně přímo na pátý bajt čísla x. Vezmi do registru B počet bitů, které mají být vynulovány, a vyděl jej osmi, abys získal počet bajtů, kterých se to týká. Jestliže výsledek je nulový, skoč dopředu. Nastav B bajtů na nulu.
Vezmi A (mod 8) - počet bitů, které mají být nulovány. Ale v případě, že se nemá už nic dělat, skoč na konec. B bude počítat bity. Připrav masku. Při každém průchodu smyčkou je zprava do A vsunuta nula, čímž se vytváří správná maska. Nepotřebné bity jsou pomocí masky vynulovány. Vrať ukazatel do HL. Vrať STKEND do DE. Hotovo.
PODPROGRAM "RE-STACK TWO" Tento podprogram vytváří ze dvou "malých" celých čísel plnohodnotná čísla v FP formě. Toho je dosaženo voláním následujícího podprogramu dvakrát. 3293 3296
RE-ST-TWO RESTK-SUB
CALL #3269,RESTK-SUB EX DE,HL
Volej podprogram a pokračuj do něj jako druhé zavolání Při každém volání zaměň ukazatele.
PODPROGRAM "RE-STACK" Doplněk: #3D "re-stack" Tento podprogram vyzvedne a opět uloží jedno číslo, které se ovšem změní z "malého" celého čísla na číslo v plnohodnotném pětibajtovém FP vyjádření. Pro jedno číslo je používán programem ARCTAN a přes kalkulátorový doplněk funkcemi EXP, LN a "get-argt". 3297
32B1 32B2
RE-STACK
RS-NRMLSE RSTK-LOOP
LD AND RET PUSH CALL XOR INC LD DEC LD LD LD AND JR OR LD JR LD LD LD EX DEC
A,(HL) A NZ DE #2D7F,INT-FETCH A HL (HL),A HL (HL),A B,#91 A,D A NZ,#32B1,RS-NRMLSE E B,D Z,#32BD,RS-STORE D,E E,B B,#89 DE,HL B
Není-li první bajt nulový vrať se neboť číslo určitě není "malé" celé číslo. Uschovej ukazatel z DE. Vyzvedni znaménko do C a číslo do DE. Vyčisti registr A. Ukazuj na 5.místo. Nastav 5.bajt na nulu. Ukazuj na 4.místo. Nastav 4.bajt=0. Bajty 2 a 3 budou obsahovat mantisu. Nastav B=145 pro exponent, tedy až šestnáct bitů čísla. Jestliže je D nulové, bude potřeba maximálně 8 bitů. Je zapotřebí více než 8 bitů. Je otestováno také E. Nuluj B (=nulový exponent v případě, že E je také nula) Je-li E skutečně nulové, skoč. Přenes E do D (D bylo nulové, ale E ne). Nastav E na nulu. Dej do B exponent 137 - ne více než 8 bitů. Ukazatel do DE, číslo do HL. Dekrementuj exponent při každém posunu.
Komentovaný výpis paměti ROM
191
32BD
192
RS-STORE
ADD JR RRC RR RR EX DEC LD DEC LD DEC LD POP RET
HL,HL NC,#32B2,RSTK-LOOP C H L DE,HL HL (HL),E HL (HL),D HL (HL),B DE
Posuň číslo doprava o jednu pozici. Dokud CY=0, skákej zpět do smyčky. Dej znaménkový bit do CY a vlož jej na své místo do čísla, které je právě posunuto o jedno místo. Ukazatel na čtvrtý bajt zpět do HL. Ukazuj na 3.místo. Uschovej 3.bajt. Ukazuj na 2.místo. Uschovej 2.bajt. Ukazuj na 1.místo. Uschovej exponentový bajt. Obnov původní ukazatel v DE. Hotovo.
Komentovaný výpis paměti ROM
FLOATING POINT KALKULÁTOR
TABULKA KONSTANT Tato první tabulka obsahuje pět užitečných a často používaných čísel: nula, jedna, polovina, polovina PI a deset. Čísla jsou uložena ve staženém tvaru, který je expandován podprogramem STACK LITERALS na požadovaný tvar floating-point (=FP tvar). data 32C5
stk-zero
32C8
stk-one
32CC
stk-half
32CE
stk-pi/2
32D3
stk-ten
DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB
#00 #B0 #00 #40 #B0 #00 #01 #30 #00 #F1 #49 #0F #DA #A2 #40 #B0 #00 #0A
konstanta
expandovaný tvar
nula
00 00 00 00 00
jedna
00 00 01 00 00
polovina
80 00 00 00 00
polovina pi 81 49 0F DA A2
deset
00 00 0A 00 00
TABULKA ADRES Druhá tabulka slouží k vyhledávání adres 66ti operačních podprogramů kalkulátoru. Doplňky, které umožňují indexování v této tabulce jsou odvozeny buď z řídících kódů, použitých v podprogramu SCANNING viz. #2734, nebo z literálů, které následují po instrukci RST #28. doplněk 32D7 32D9 32DB 32DD 32DF 32E1 32E3 32E5 32E7 32E9 32EB 32ED 32EF 32F1 32F3 32F5 32F7 32F9 32FB 32FD 32FF
00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14
název
adresa
skok-pravda záměna výmaz odečtení násobení dělení umocnění číslo OR číslo číslo AND číslo číslo <= číslo číslo >= číslo číslo <> číslo číslo > číslo číslo < číslo číslo = číslo sčítání řetězec AND číslo řetězec <= řetězec řetězec >= řetězec řetězec <> řetězec řetězec > řetězec
368F 343C 33A1 300F 30CA 31AF 3851 351B 3524 353B 353B 353B 353B 353B 353B 3014 352D 353B 353B 353B 353B
doplněk 3319 331B 331D 331F 3321 3323 3325 3327 3329 332B 332D 332F 3331 3333 3335 3337 3339 333B 333D 333F 3341
21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35
název
adresa
tan 37DA asn 3833 acs 3843 atn 37E2 ln 3713 exp 36C4 int 36AF sqr 384A sgn 3492 abs 346A peek 34AC in 34A5 usr-no 34B3 str$ 361F chr$ 35C9 not 3501 zdvojení 33C0 n-mod-m 36A0 relativní skok 3686 stk-data 33C6 dec-jr-nz 367A
Komentovaný výpis paměti ROM
193
3301 3303 3305 3307 3309 330B 330D 330F 3311 3313 3315 3317
15 16 17 18 19 1A 1B 1C 1D 1E 1F 20
řetězec < řetězec řetězec = řetězec řetězec + řetězec val$ usr$ načtení do A negace code val len sin cos
353B 353B 359C 35DE 34BC 3645 346E 3669 35DE 3674 37B5 37AA
3343 3345 3347 3349 334B 334D 334F 3351 3353 3355 3357 3359
36 37 38 39 3A 3B 3C 3D 3E 3F 40 41
číslo < 0 číslo > 0 konec výpočtu get-argument int se zaokr. fp-calc-2 e-to-fp re-stack serie 06 atd. stk-nula atd. st-mem-0 atd. get-mem-0 atd.
3506 34F9 369B 3783 3214 33A2 2D4F 3297 3449 341B 342D 340F
Poznámka: Poslední čtyři podprogramy jsou víceúčelové a vstupuje se do nich s parametrem, který je kopií bitů 0 až 4 původního literálu: Doplněk #3E: série#06, série#08 a série#0C odpovídá literálům: #86,#88 a #8C. Doplněk #3F: stk-nula, stk-jedna, stk-polovina, stk-pi/2, stk-deset odpovídá literálům #A0 až #A4. Doplněk #40: st-mem-0 až st-mem-5 odpovídá literálům #C0 až #C5. Doplněk #41: get-mem-0 až get-mem-5 odpovídá literálům #EO až #E5.
PODPROGRAM "CALCULATE“ Tento podprogram provádí výpočty s čísly ve formě s pohyblivou řádovou tečkou. (Dále jen FP). Výpočty lze rozdělit do tří skupin: a) Binární operace například sčítání, kdy dvě FP čísla jsou sečtena a výsledek pak tvoří "poslední hodnotu". b) Unární operace například sin, kdy "poslední hodnota" je změněna tak, že je výsledkem dané operace. c) Manipulační operace například st-mem-0, kde "poslední hodnota“ je okopírována do prvních pěti bajtů paměti kalkulátoru. Operace, které se mají provést jsou specifikovány sledem datových bajtů takzvaných literálů, které následují po instrukci RST#28 a tento sled musí být zakončen literálem #38 - konec výpočtu. V případě potřeby vykonání jediné početní operace je možné vložit doplněk do registru B a vyvolat operaci jediného výpočtu pomocí literálu #3B. Také je možné volat tento použít systémovou proměnnou BREG podprogramu nastavuje registry literálů, které jsou testovány. konstant. Parametry jsou použity
podprogram rekursivně, tedy ze sama sebe, a v takovém případě lze jako čítač, který řídí počet operací před návratem. První část tohoto na požadované hodnoty, vypočítává doplňky a případné parametry z Doplněk slouží k vyhledání adresy příslušného podprogramu v tabulce při volání víceúčelových podprogramů.
Poznámka: FP číslo může být ve skutečnosti také soubor řetězcových parametrů. 335B
CALCULATE
CALL #35BF,STK-PNTRS
335E
GEN-ENT-1
LD
A,B
3362
GEN-ENT-2
LD EXX EX
(#5C67),A (BREG)
194
(SP),HL
Předpokládej unární operaci a proto nastav HL tak, aby ukazovalo na 1.bajt "poslední hodnoty" a DE na STKEND. Jinak předej doplněk jednoduché operace do BREG, při rekurzívním volání se nejedná o doplněk, ale o parametr (=čítač). Návr. adr. podprogramu je uložena v zrcadlovém HL. Toto číslo je také ukaz. na 1.literál. Vstup v tomto místě Komentovaný výpis paměti ROM
3365
336C
3380
RE-ENTRY
SCAN-ENT
FIRST-3D
338C
DOUBLE-A
338E
ENT-TABLE
33A1
delete
EXX LD EXX LD INC PUSH AND JP LD AND RRCA RRCA RRCA RRCA ADD LD LD AND JR CP JR EXX LD LD LD ADD EXX RLCA LD LD LD ADD LD INC LD LD EX PUSH EXX LD RET
(#5C65),DE (STKEND) A,(HL) HL HL A P,#3380,FIRST-3D D,A #60
A,#7C L,A A,D #1F #338E,ENT-TABLE #18 NC,#338C,DOUBLE-A BC,#FFFB D,H E,L HL,BC
L,A DE,#32D7 H,#00 HL,DE E,(HL) HL D,(HL) HL,#3365 (SP),HL DE
se používá, když BREG je čítač a nemá se zničit. Zde začíná smyčka obsl. všechny literály následující za volací instrukcí. Přepni zrcadlové registry a vyzvedni literál pro tuto smyčku. H'L' ukazuje na další literál a je krátce uschováno na zásobníku. Tento bod je používán pro podprogram SINGLE CALCULATION nalezení pož. podpr. Testuj registr A a odděl jed. liter. od víceúčelových. Skoč s literálem #00-#3D Uschovej literál v registru D. Pokračuj pouze s bity 5 a 6 a čtyřmi posuny z nich udělej bity 1 a 2.
Požadované doplňky jsou #3E-#41 a L obsahuje požadovaný doplněk. Vytvoř parametr M tak, že použiješ bity 1,2,3 a 4 z původního literálu. Najdi adresu požadovaného programu. Při odskoku proveď unární operaci. Všechny podpr., které jsou binárními operacemi vyžadují, aby HL ukazovalo na první operand a DE na druhý ("poslední hodnotu") tak, jak jsou na zásob. kalkulátoru.
Protože každá položka v tabulce je dvoubajtová, je vytvořený doplněk zdvojnásoben. Bázová adresa tabulky. Adresa požadované položky v tabulce je vytvořena v HL a adresa požadovaného podprogramu
je vyzvednuta do DE. Adresa opětovného vstupu je uložena na zásobníku pod adresu požadovaného podprogramu. Přepni na hlavní registry. BC,(#5C66)(STKEND-hi) BREG je uložena do B, čímž se vrací dopl. jediné operace. Nyní je proveden nepřímý skok do požadovaného podpr.
PODPROGRAM "DELETE“ Doplněk: #02 "delete" Tento podprogram obsahuje pouze instrukci RET. Literál #02 způsobí, že tento program je považován za binární operaci. Proto se do něj vstupuje s prvním číslem adresovaným HL a druhým číslem adresovaným DE a vytvořený výsledek bude opět adresován registrovým párem HL. Instrukce RET tedy způsobí, že první číslo je považováno za "poslední hodnotu" a druhé číslo je vymazáno. Druhé číslo samozřejmě není vymazáno z paměti, ale stává se pouze neaktivním a pravděpodobně bude brzy přepsáno.
PODPROGRAM "SINGLE OPERATION" Doplněk: #3B "fp-calc-2" Tento podprogram je volán z podprogramu SCANNING na adrese #2757 a používá se k provedení jednoduché aritmetické operace. Doplněk uvažované operace se předává kalkulátoru v registru B odkud je předán do systémové proměnné BREG. Komentovaný výpis paměti ROM
195
Výsledkem provedení tohoto podprogramu je zejména provedení skoku do příslušného podprogramu pro jedinou operaci. 33A2
FP-CALC-2
POP LD EXX JR
AF A,(#5C67) (BREG) #336C,SCAN-ENT
Odhoď návratovou adresu. Převeď doplněk do A. Přepni na zrcadlové registry. Nalezni požadovanou adresu, ulož ji na zásobník a proveď příslušnou operaci.
PODPROGRAM "TEST 5-SPACES" Podprogram testuje, zda je v paměti dostatek místa pro pět bajtů FP čísla, které má být přidáno na zásobník kalkulátoru. 33A9
TEST-5-SP
PUSH PUSH LD CALL POP POP RET
DE HL BC,#0005 #1F05,TEST-ROOM HL DE
Krátce uschovej DE a také HL. Test bude na 5 bajtů Proveď test. Obnov HL a také DE. Hotovo.
PODPROGRAM "STACK NUMBER" Tento podprogram je volán z příkazu BEEP a z podprogramu SCANNING dvakrát, aby okopíroval STKEND do DE, přenesl FP číslo na zásobník kalkulátoru a opět nastavil STKEND na hodnotu v DE. Pro skutečný přesun je použit podprogram MOVE-FP. 33B4
STACK-NUM
LD DE,(#5C65) (STKEND) CALL #33C0,MOVE-FP LD (#5C65),DE (STKEND) RET
Okopíruj STKEND do DE jako cílovou adresu. Přesuň číslo. Obnov hodnotu STKEND. Hotovo.
PODPROGRAM "MOVE A FLOATING - POINT NUMBER" Doplněk: #31 "duplicate" Tento program přenese FP číslo na vrchol zásobníku kalkulátoru (ve třech případech) nebo z vrcholu kalkulátoru do paměti kalkulátoru (v jednom případě). Je také používán kalkulátorem pro obyčejné zdvojení čísla na vrcholu kalkulátoru, čímž se zásobník kalkulátoru rozšíří o pět bajtů. 33C0
MOVE-FP
CALL #33A9,TEST-5-SP LDIR RET
Testuje se místo. Přenes. Hotovo.
PODPROGRAM "STACK LITERALS" Doplněk: #34 "stk-data" Tento podprogram vytvoří z dodaného čísla 2,3,4 nebo 5 literálů a umístí je jako poslední hodnotu na zásobník kalkulátoru. Je-li tento podprogram vyvolán literálem #34, jsou uvažované literály uloženy za touto konstantou, je-li volán podprogramem SERIES GENERATOR, jsou literály dodány podprogramem vytvářejícím postoupnosti čísel a je-li volán podprogramy SKIP KONSTANTS nebo STACK A KONSTANTS, jsou literály získány z tabulky konstant na adrese #32C5-#32D6. V každém případě je první literál vydělen hodnotou #40 a celočíselná hodnota podílu plus 1 určí zda bude použito 1, 2, 3 nebo 4 následujících literálů jako čísla mantisy. Každý nevyplněný bajt z pěti bajtů pro FP číslo je nastaven na nulu. 196
Komentovaný výpis paměti ROM
První literál se také používá k určení exponentu po snížení modulo #40 pokud ovšem zbytek není nulový. V tom případě se použije druhý literál tak jak je, bez snižování modulo #40. V každém případě se k literálu přičte #50, čímž se vytvoří zvětšený exponentový bajt e (skutečný exponent e' plus #80). Zbývajících pět bajtů je uloženo na zásobník včetně potřebných nul a podprogram vrací zpět. 33C6
STK-DATA
LD LD
H,D L,E
33C8
STK-CONST
CALL EXX PUSH EXX EX PUSH LD AND RLCA RLCA LD
#33A9,TEST-5-SP
INC LD AND JR INC LD ADD LD LD SUB INC INC LD LDIR POP EX EXX POP EXX LD XOR DEC RET LD INC JR
C A,(HL) #3F NZ,#33DE,FORM-EXP HL A,(HL) A,#50 (DE),A A,#05 C HL DE B,#00
33DE
33F1
FORM-EXP
STK-ZEROS
HL (SP),HL BC A,(HL) #C0
C,A
BC (SP),HL HL B,A A B Z (DE),A DE #33F1,STK-ZEROS
Tento podprogram vykoná manipulační operaci přičtení poslední hodnoty na zásobník kalkulátoru a HL ukazuje za poslední hodnotu (výsledek). Testuj potřebný prostor. Přepni na zrcadlové registry. Uschovej ukazatel na další literál. Přepni zpět. Zaměň výsledný ukazatel a ukazatel na další literál. Uschovej krátce BC. Vyzvedni první literál do A. Vyděl ho hodnotou #40 pro dosažení hodnot 0,1,2 nebo 3.
Celočíselná část e je předána do C a zvětšena pro dosažení hodnoty 1,2,3 nebo 4 (= počet liter. mantisy). Opět je vyzvednut literál, snížen o hodnotu modulo #40 a bude použit při nenulovém zbytku. Jinak bude použit další neredukovaný literál. Exponent e je formován přičtením hodnoty #50 a předán na zásobník DE kalkulátoru jako 1. z 5 hodnot výsledku. C literálů je vyzvednuto ze zdroje
a uloženo do bajtů výsledku. Obnov BC. Zaměň zpět ukazatel výsledku a ukazatel literálu ze zásobníku do H'L'. Počet nulových bajtů je udán hodnotou 5-C-1 a tento počet nul je přidán k výsledku, aby byl doplněn požadovaný počet bajtů.
PODPROGRAM "SKIP KONSTANTS" Do tohoto podprogramu se vstupuje s registrovým párem HL obsahujícím bázovou adresu kalkulátorové tabulky konstant a registr A obsahuje parametr určující jednu z pěti konstant. Podprogram provádí nulové operace přenášením pěti bajtů každé nepotřebné konstanty na adresy #0000, #0001, #0002, #0003 a #0004 v paměti ROM až do nalezení požadované konstanty. Na výstupu obsahuje HL bázovou adresu požadované konstanty v tabulce konstant. 33F7 33F8
SKIP-CONS SKIP-NEXT
AND A RET Z PUSH AF
Je-li parametr nula nebo byla-li nalezena potřebná konstanta, vrať se. Uschovej parametr
Komentovaný výpis paměti ROM
197
PUSH LD CALL POP POP DEC JR
DE DE,#0000 #33C8,STK-CONST DE AF A #33F8,SKIP-NEXT
a ukazatel výsledku. Mrtvá adresa. Proveď imaginární uložení expandované konstanty. Obnov ukazatel výsledku a parametr. Počítej smyčky a posuď další hodnoty čítače.
PODPROGRAM "MEMORY LOCATION" Podprogram nalezne bázovou adresu každých pěti bajtů v paměťové oblasti kalkulátoru na kterou nebo z které má být přeneseno FP číslo do nebo ze zásobníku kalkulátoru. Tato operace se provede pětinásobným přičtením dodaného parametru k bázové adrese pro oblast jejíž adresa je v registrovém páru HL. Povšimněte si, že při zpracování proměnné FOR-NEXT jsou ukazatele zaměněny tak, aby proměnná byla považována za oblast kalkulátoru (viz #1D20). 3406
LOC-MEM
LD RLCA RLCA ADD LD LD ADD RET
C,A
A,C C,A B,#00 HL,BC
Kopíruj parametr do C. Zdvoj parametr. Zdvoj výsledek. Přičti hodnotu parametru, což dá 5 násobek původní hodn. Převeď výsledek do registrového páru BC. Vytvoř novou bázovou adresu. Hotovo.
PODPROGRAM "GET FROM MEMORY AREA" Doplňky: #E0 až #E5 "get-mem-0" až "get-mem-5" Podprogram je volán použitím literálů #E0 až #E5 a parametry odvozené z těchto literálů jsou v registru A. Podprogram volá MEMORY LOCATION k uložení požadované zdrojové adresy do HL a MOVE A FLOATING-POINT NUMBER k okopírování příslušných pěti bajtů z paměti kalkulátoru, aby vytvořil novou "poslední hodnotu". 340F
GET-MEM-0 etc.
PUSH LD CALL CALL POP RET
DE HL,(#5C68) (MEM) #3406,LOC-MEM #33C0,MOVE-FP HL
Uschovej ukazatel výsledku. Vyzvedni ukazatel na aktuální paměťovou oblast. Bázová adresa je nalezena. Pět bajtů přeneseno. Ukazatel výsledku nastaven. Hotovo.
PODPROGRAM "STACK A KONSTANTS" Doplněk: #A0 až #A4 "stk-nula" , "stk-jedna" , "stk-půl" "stk-pi/2" , "stk-deset". Tento podprogram používá SKIP KONSTANTS k nalezení bázové adresy požadované konstanty z tabulky konstant a potom STACK LITERALS, aby se dosáhlo expandované formy konstanty jako "poslední hod." na zásobníku kalkulátoru. 341B
198
STK-ZERO etc.
LD LD EXX PUSH LD EXX CALL CALL EXX POP
H,D L,E
Nastav HL jako ukazatel výsledku.
#33F7,SKIP-CONS #33C8,STK-CONST
Přepni na zrcadlové registry. Uschovej adresu dalšího literálu. Bázová adresa tabulky konstant. Zpět na hlavní registry. Nalezni požadovanou bázovou adresu. Expanduj konstantu.
HL
Obnov ukazatel na další literál.
HL HL,#32C5
Komentovaný výpis paměti ROM
EXX RET
Hotovo.
PODPROGRAM "STORE IN MEMORY AREA" Doplněk: #CO až #C5 "st-mem-0" až "st-mem-5" Tento podprogram se volá použitím literálů #C0 až #C5 a parametry odvozené z těchto literálů jsou v registru A. Podprogram je velmi podobný podprogramu GET FROM MEMORY, ale zdrojové a cílové ukazatele jsou zaměněny. 342D
ST-MEM-0 etc.
PUSH EX LD CALL EX CALL EX POP RET
HL DE,HL HL,(#5C68) (MEM) #3406,LOC-MEM DE,HL #33C0,MOVE-FP DE,HL HL
Uschovej ukazatel výsledku. Zdroj krátce do DE. Vyzvedni ukazatel na aktuální paměťovou oblast. Je nalezena bázová adresa. Je zaměněn zdrojový a cílový ukazatel. Přenes pět bajtů. STKEND do DE. Ukazatel výsledku do HL. Hotovo.
Povšimněte si, že ukazatele HL a DE zůstávají tak jak byly, ukazujíce na STKEND-5 a STKEND, takže poslední hodnota zůstává na zásobníku kalkulátoru. Je-li to třeba, může být vyřazena použitím "delete".
PODPROGRAM "EXCHANGE" (ZÁMĚNA) Doplněk: #01 "exchange" Tato binární operace zamění první a druhé číslo na vrcholu zásobníku kalkulátoru. 343C 343E
EXCHANGE SWAP-BYTE
LD LD LD EX LD LD INC INC DJNZ EX RET
B,#05 A,(DE) C,(HL) DE,HL (DE),A (HL),C HL DE #343E,SWAP-BYTE DE,HL
Jde o pět bajtů. Každý bajt druhého čísla a každý bajt prvního čísla. Přepni zdroj na cíl. Na první a na druhé číslo. Přesuň se na posouzení dalšího páru bajtů. Zaměň pět bajtů. Dej do pořádku ukazatele, protože číslo 5 je liché. Hotovo.
PODPROGRAM "SERIES GENERATOR" (GENERÁTOR ŘAD) Doplňky: #86, #88 a #8C "series-06", "series-08" a "series-0C" Tento důležitý podprogram generuje řady rozvojem podle Čebyševových polynomů a jejich hodnoty jsou pak použity k výpočtu hodnot funkcí SIN, ATN, LN a EXP a tím pádem i dalších aritmetických funkcí, které jsou s předchozími v nějakém aritmetickém vztahu (COS, TAN ,ASN, ACS ....SQR). Polynomy jsou generovány pro n=1,2,...,rekurentním vztahem : T n+1(z)=2*z*T n(z)-T n-1(z), kde Tn(z) je n-tý prvek Čebyševova polynomu argumentu (z). Řada ve skutečnosti vypadá takto : T0, 2*T1, 2*T2,.... 2*Tn-1, kde n je 6 pro SIN, 8 pro EXP a 12 pro LN a ATN. Koeficienty mocnin hodnoty (z) v těchto polynomech mohou být nalezeny v knize Handbook of Mathemetical Functions od M. Abramovitze a I. A. Steguna (V Doveru 1965), strana 795. Jednoduše řečeno, podprogram je volán s poslední hodnotou na zásobníku kalkulátoru, řekněme Z, což je číslo mající nějaký jednoduchý vztah k argumentu, řekněme X, např. pro funkci SIN X. Volající podprogram také dodává seznam požadovaných konstant (např. 6 konstant pro SIN). SERIES GENERÁTOR pak pracuje s těmito daty a vrací volajícímu podprogramu "poslední hodnotu", která obsahuje jednoduchý výsledek pro požadovanou funkci např. SIN X.
Komentovaný výpis paměti ROM
199
Podprogram může být rozdělen na čtyři části : 1) Nastavení čítače průchodů smyčkou : Volající podprogram předá své parametry v registru A pro použití jako čítač. Do kalkulátoru se vstoupí v bodě GEN-ENT-1, takže čítač může být nastaven. 3449
SERIES-06 etc.
LD CALL
B,A #335E,GEN-ENT-1
Předej parametr do B. Toto je ve skutečnosti RST #28, ale s nastavením čítače.
2) Práce s poslední hodnotou Z : Smyčka generátoru vyžaduje, aby hodnota 2*Z byla uložena v mem-0, v mem-2 má být uložena nula, která má být zároveň poslední hodnotou. DEFB DEFB DEFB DEFB DEFB DEFB
#31,zdvojení #0F,součet #C0,st-mem-0 #02,výmaz #A0,stk-nula #C2,st-mem-2
Z,Z 2*Z 2*Z mem-0 obsahuje 2*Z. 0 0 mem-2 obsahuje 0.
3) Hlavní smyčka : Řada je generována ve smyčce s použitím BREG jako čítače. Konstanty z volajícího podprogramu jsou postupně ukládány na zásobník podprogramem STK-DATA. Je proveden opětovný vstup do kalkulátoru v bodě GEN-ENT-2, tak aby se nezničila hodnota BREG a řada se vytváří v této formě: B(R)=2*Z*B(R-1)-B(R-2)+A(R), pro R=1,2,...,N, kde A(1),A(2),.....,A(N) jsou konstanty dodané volajícím podprogramem (SIN,ATN,LN a EXP) a B(0)=0=B(-1). (R+1)ní smyčka začíná s B(R) na zásobníku a s 2*Z, B(R-2) a B(R-1) v mem-0, mem-1 a mem-2. 3453
G-LOOP
DEFB DEFB DEFB DEFB DEFB DEFB DEFB
#31,zdvojení #E0,get-mem-0 #04,násobení #E2,get-mem-2 #C1,st-mem-1 #03,odečet #38,konec výpočtu
B(R),B(R) B(R),B(R),2*Z B(R),2*B(R)*Z B(R),2*B(R)*Z,B(R-1) B(R-1) do mem-1 B(R),2*B(R)*Z-B(R-1)
Na zásobník kalkulátoru je umístěna další konstanta. CALL
#33C6,STK-DATA
B(R),2*B(R)*Z-B(R-1),A(R+1)
Toto je opětovný vstup do kalkulátoru bez poškození BREG. CALL DEFB DEFB DEFB DEFB DEFB DEFB
#3362,GEN-ENT-2 #0F,součet B(R),2*B(R)*Z-B(R-1)+A(R+1) #01,záměna 2*B(R)*Z-B(R-1)+A(R+1),B(R) #C2,st-mem-2 B(R) do mem-2 #02,výmaz 2*B(R)*Z-B(R-1)+A(R+1)=B(R+1) #35,dec-jr-nz B(R+1) #EE,na #3453,G-LOOP
4) Odečtení čísla B(N-2) : Smyčka ponechává B(N) na zásobníku a požadovaný výsledek je dán hodnotou B(N)-B(N-2). DEFB DEFB DEFB RET
200
#E1,get-mem-1 #03,odečet #38,konec výpočtu
B(N),B(N-2) B(N)-B(N-2) Hotovo.
Komentovaný výpis paměti ROM
FUNKCE "ABSOLUTE MAGNITUDE" Doplněk: #2A "abs" Tento podprogram provede unární operaci tím, že zajistí, aby znaménkový bit FP čísla byl vynulován. "Malá celá čísla" musí být posouzena odděleně. Většinu práce však vykoná následující podprogram "unární mínus". 346A
ABS
LD JR
B,#FF #3474,NEG-TEST
B je nastaveno na #FF. Je provedeno unární mínus.
OPERACE UNARY MINUS Doplněk: #1B "negate" Tento podprogram provede unární operaci tím, že změní znaménko poslední hodnoty na zásobníku kalkulátoru. Nula zůstává nezměněna. FP čísla jsou zpracována tak, že jejich znaménkový bit je nulován pro "abs" nebo překlopen pro "negate". "Malá celá čísla" mají vynulován znaménkový bajt pro "abs" nebo změněn pro "negate". 346E
NEGATE
CALL RET LD
#34E9,TEST-ZERO C B,#00
Je-li číslo nula, návrat s bajty 00 00 00 00 00 zůstanou nezměněny. B je nastaveno na #00 pro "negate".
Zde je vstup pro "ABS". 3474
NEG-TEST
LD AND JR INC LD AND OR RLA CCF RRA LD DEC RET
A,(HL) A Z,#3483,INT-CASE HL A,B #80 (HL)
Jestliže první bajt je nulový, provede se zpracovaní "malého celého čísla". Ukazuj na druhý bajt. Vyzvedni #FF pro "abs" a #00 pro "negate". Změň na #80 pro "abs" a #00 pro "negate". Nastaví se bit 7 pro "abs", nic se nezmění pro "negate". Nyní je změněn bit 7, což způsobí, že bit 7 2.bajtu je nulován.
(HL),A HL
Nový bajt je uložen. HL ukazuje opět na první bajt. Hotovo.
V případě celého čísla dochází k podobné operaci se znaménkovým bajtem. 3483
INT-CASE
PUSH PUSH CALL POP LD OR CPL LD CALL POP RET
DE HL #2D7F,INT-FETCH HL A,B C C,A #2D8E,INT-STORE DE
Ulož STKEND v DE. Uschovej ukazatel na číslo v HL. Vyzvedni znaménko do C a číslo do DE. Obnov ukazatel na číslo v HL. Vlož #FF pro "abs" a #00 pro "negate". #FF pro "abs",žádná změna pro "negate". #00 pro "abs" a změněný bajt pro "negate" uschovej v C. Uschovej výsledek na zásobníku a vrať STKEND do DE. Hotovo.
Komentovaný výpis paměti ROM
201
FUNKCE "SIGNUM" (ZNAMÉNKO) Doplněk: #29 "sgn" Tento podprogram provádí funkci SGN X a proto vrací jako poslední hodnotu 1 když X>0, O když X=0 a -1 když X<0. 3492
SGN
CALL RET PUSH LD INC RL DEC SBC LD CALL POP RET
#34E9,TEST-ZERO C DE DE,#0001 HL (HL) HL A,A C,A #2D8E,INT-STORE DE
Je-li X nulové vrať se s poslední hodnotou nula. Uschovej ukazatel na STKEND. Vlož do DE jedničku. Ukazuj na další bajt čísla X. Rotuj bit 7 do CY a ukazuj na původní adresu. C bude obsahovat #00 pro kladné X a #FF pro záporné X. Ulož 1 nebo -1 podle potřeby. Obnov ukazatel na STKEND. Hotovo.
FUNKCE "IN" Doplněk: #2C "in" Tento podprogram provádí funkci IN X. Provede vstup na úrovni procesoru z portu X, jehož hodnota je v BC, a provede instrukci IN A,(C). 34A5
IN
CALL IN JR
#1E99,FIND-INT2 A,(C) #34B0,IN-PK-STK
"Poslední hodnota" X kompresována do BC. Signál je přijat. Skok na uložení výsledku na zásobník kalkulátoru.
FUNKCE "PEEK" Doplněk: #2B "peek" Tento podprogram provádí funkci PEEK X. "Poslední hodnota" je odebrána ze zásobníku za pomoci FIND-INT2 a nahrazena hodnotou uloženou na příslušném paměťovém místě. 34AC
PEEK
34B0
IN-PK-STK
CALL LD JP
#1E99,FIND-INT2 A,(BC) #2D28,STACK-A
"Poslední hodnota" je kompresována do BC. Vyzvedni požadovaný bajt. Výstup přes stack A.
FUNKCE "USR" Doplněk: #2D "usr-no" Tento podprogram ("USR číslo" je něco jiného než "USR řetězec"), obsluhuje funkci USR X, kde X je číslo. Hodnota čísla X je uložena do BC, návratová adresa je uložena na zásobník a program je proveden od adresy X. 34B3
USR-NO
CALL LD PUSH PUSH RET
#1E99,FIND-INT2 HL,#2D2B HL BC
"Poslední hodnota" je kompresována do BC. Vlož návratovou adresu podprogramu STACK-BC. Ulož návratovou adresu a proveď nepřímý skok na tento podprogram. Hotovo.
Poznámka: Je zajímavé, že registrový pár IY je znovu nastaven na svou původní hodnotu po návratu přes STACK-BC, ale důležitý ukazatel na poslední literál, který je v H’L‘, obnoven není. Proto pro úspěšný návrat do BASICu musí zrcadlové HL obsahovat adresu instrukce "end-calc" v podprogramu SCANNING, která je na adrese #2758.
202
Komentovaný výpis paměti ROM
FUNKCE "USR STRING" Doplněk: #19 "usr-$" Podprogram provede funkci USR X$, kde X$ je řetězec, a v BC vrací adresu bitové matice znaku uživatelsky definované grafiky, odpovídající znaku uloženému v X$. Podprogram hlásí chybu A, když X$ není jediné písmeno v rozsahu od "a" do "u" nebo znak uživatelsky definované grafiky. 34BC
USR-$
34D3
USR-RANGE
34E4 34E7
USR-STACK REPORT-A
CALL DEC LD OR JR LD CALL JR SUB JR CP JR INC DEC ADD ADD ADD CP JR LD ADD LD JR INC JP RST DEFB
#2BF1,STK-FETCH BC A,B C NZ,#34E7,REPORT-A A,(DE) #2C8D,ALPHA C,#34D3,USR-RANGE #90 C,#34E7,REPORT-A #15 NC,#34E7,REPORT-A A A A,A A,A A,A #A8 NC,#34E7,REPORT-A BC,(#5C7B) (UDG) A,C C,A NC,#34E4,USR-STACK B #2D2B,STACK-BC #08,ERROR-1 #09
Vyzvedni parametry řetězce X$. Sniž délku o jedna pro test. Nebyla-li délka jedna, skoč a ohlaš chybu. Jinak vyzvedni jediné kód řetězce. Jestliže představuje písmeno, skoč na vyzvednutí jeho adresy. Sniž adresu na skutečných 0 - 20 a ohlaš chybu A, je-li znak mimo rozsah. Opět testuj rozsah a ohlaš chybu A, je-li znak mimo rozsah. Uprav rozsah na 1 - 21, jako rozsah pro "a" až "u". Nyní je rozsah 0-20 Vynásobením osmi se získá doplněk pro adresu. Testuj rozsah doplňku a ohlaš chybu A, jeli mimo rozsah. Vyzvedni adresu 1. bajtu uživ. definované grafiky do BC a přičti C k doplňku. Výsledek vlož zpět do C. Nedošlo-li k přenosu, skoč, jinak zvětši B. Ulož adresu. Ohlaš: A-Invalid argument.
PODPROGRAM "TEST-ZERO" (TEST-NULA) Podprogram je volán přinejmenším devětkrát k otestování FP čísla je-li nulové. Tento test vyžaduje, aby první čtyři bajty čísla byly nulové. Podprogram se vrací s CY=1 bylo-li číslo skutečně nula. 34E9
TEST-ZERO
PUSH PUSH LD LD INC OR INC OR INC OR LD POP POP RET SCF RET
HL BC B,A A,(HL) HL (HL) HL (HL) HL (HL) A,B BC HL NZ
Uschovej HL a také BC. Uschovej hodnotu A v registru B. Vyzvedni 1. bajt. Ukazuj na 2. bajt. Proveď logické OR. Ukazuj na 3. bajt. Proveď logické OR. Ukazuj na 4. bajt. Proveď logické OR. Obnov původní hodnotu v registru A, v registrech BC a v registrech HL. Vrať se s CY=0, pokud byl kterýkoliv ze čtyř bajtů<>0. Nastav CY=1 jako signál, že číslo bylo nula a vrať se.
Komentovaný výpis paměti ROM
203
OPERACE "GREATER THAN ZERO" (VĚTŠÍ NEŽ NULA) Doplněk: #37 "greater-0" Podprogram vrací jako "poslední hodnotu" číslo 1, byla-li aktuální "poslední hodnota" větší než nula, jinak vrací číslo 0. Je také využíván jinými podprogramy, při skoku "při plus". 34F9
GREATER-0
CALL RET LD JR
#34E9,TEST-ZERO C A,#FF #3507,SIGN-TO-C
Je poslední hodnota nula ? Vrať jestliže ano. Proveď LESS THAN ZERO, ale signalizuj, že je potřeba provést opačnou akci.
FUNKCE "NOT" Doplněk: #30 "not" Podprogram vrací jako "poslední hodnotu" číslo 1 jestliže byla aktuální "poslední hodnota" nulová, jinak vrací číslo nula. Je také využíván jinými podprogramy pro "skok při nule". 3501
NOT
CALL JR
#34E9,TEST-ZERO #350B,FP-0/1
CY bude 1 jedině když poslední hodnota byla 0, což už je správný výsledek.
OPERACE "LESS THAN ZERO" (MENŠÍ NEŽ NULA) Doplněk: #36 "less-0" Podprogram vrací jako "poslední hodnotu" číslo 1, byla-li aktuální "poslední hodnota" menší než nula, jinak vrací číslo 0. Je také využíván jinými podprogramy při skoku "při mínus". 3506 3507
LESS-0 SIGN-TO-C
XOR INC XOR DEC RLCA
A HL (HL) HL
Vynuluj registr A. Ukazuj na znaménkový bajt. CY=0 pro kladná čísla a CY=1 pro záporná čísla. Při vstupu z GREATER-0 jde do CY opačné znaménko.
PODPROGRAM "ZERO OR ONE" (NULA NEBO JEDNA) Tento podprogram nastaví poslední hodnotu na nulu jestliže CY=0 nebo na jedničku jestliže CY=1. Při zavolání z "E-TO-FP" vytváří tuto nulu nebo jedničku v mem-0. 350B
204
FP-0/1
PUSH LD LD INC LD INC RLA LD RRA INC LD INC LD POP RET
HL A,#00 (HL),A HL (HL),A HL (HL),A HL (HL),A HL (HL),A HL
Uschovej ukazatel na výsledek. Vynuluj A bez porušení CY. Nastav 1.bajt na 0. Ukazuj na 2. bajt. Nastav 2.bajt na 0. Ukazuj na 3. bajt. Rotuj CY do A, takže A bude 1, bylo-li CY=1, jinak A=0. Nastav třetí bajt na tuto hodnotu a zajisti opět nulové A. Ukazuj na 4. bajt. Nastav jej na nulu. Ukazuj na 5. bajt. Nastav jej na nulu. Obnov ukazatel výsledku. Hotovo.
Komentovaný výpis paměti ROM
OPERACE "OR" Doplněk: #07 "or" Podprogram provádí binární operaci "X OR Y" a vrací X, jestliže Y bylo nulové, a jinak hodnotu nula. 351B
OR
EX CALL EX RET SCF JR
DE,HL #34E9,TEST-ZERO DE,HL C #350B,FP-0/1
HL ukazuje na Y, tedy druhé číslo. Testuj jestli je Y nulové. Obnov ukazatele. Jestliže Y=0, vrať se; X je nyní poslední hodnotou. Nastav CY a nastav "poslední hodnotu" na jedna.
OPERACE "NUMBER AND NUMBER“ Doplněk: #08 "no-&-no" Podprogram provádí binární operaci "X AND Y" a vrací X jestliže Y není nula, v ostatních případech hodnotu nula. 3524
NO-&-NO
EX CALL EX RET AND JR
DE,HL #34E9,TEST-ZERO DE,HL NC A #350B,FP-0/1
HL ukazuje na Y, tedy druhé číslo. Testuj, zda Y je nulové. Zaměň ukazatele zpět. Vrať se s X jako poslední hodnotou, nebylo-li Y nula. Nuluj CY a nastav poslední hodnotu na nulu.
OPERACE "STRING AND NUMBER“ Doplněk: #10 "str-&-no" Podprogram provádí binární operaci "X$ AND Y" a vrací X$ jestliže Y je nenulové, jinak vrací nulový řetězec. 352D
STR-&-NO
EX CALL EX RET PUSH DEC XOR LD DEC LD POP RET
DE,HL #34E9,TEST-ZERO DE,HL NC DE DE A (DE),A DE (DE),A DE
HL ukazuje na Y, DE na X$. Testuj, zda Y je nulové. Zaměň ukazatele zpět. Vrať se s X$ jako poslední hodnotou, když Y nebylo nula. Uschovej ukazatel na číslo. Ukazuj na 5. bajt param. řetěz. = vyšší bajt délky. Nuluj registr A. Vyšší bajt délky je nyní nastaven na 0. Ukazuj na nižší bajt délky. Také jej nastav na nulu. Obnov ukazatele. Vrať se s parametry řetězce jako "poslední hodnotou".
OPERACE "COMPARISON“ Doplňky: #09 až #0E a #11 až #16 "no-l-eql", "no-gr-eq", "nos-neql", "no-grtr", "no-less", "nos-eql", "str-l-eql", "str-gr-eq", "strs-neql", "str-grtr", "str-less" a "strs-eql". 353B
NO-L-EQL etc.
3543
EX-OR-NOT
LD SUB BIT JR DEC RRCA JR
A,B #08 2,A NZ,#3543,EX-OR-NOT A NC,#354E,NU-OR-STR
Doplněk do registru A. Rozsah je #01 - #06 a #09 - #0E. Tento rozsah je změněn na #00 - #02,#04 - #06,#08 - #0A a #0C - #0E. Dále je snížen na #00 - #07 a CY=1 pro ">=" a "<". Operace s CY=1
Komentovaný výpis paměti ROM
205
354E
NU-OR-STR
3559
STRINGS
3564
BYTE-COMP
356B
SECND-LOW
3572
BOTH-NULL
3575
SEC-PLUS
3585
FRST-LESS
3588
STR-TEST
358C
END-TESTS
206
PUSH PUSH CALL POP EX POP BIT JR RRCA PUSH CALL JR RRCA PUSH CALL PUSH PUSH CALL POP LD OR EX LD JR OR POP JR POP CCF JR POP JR OR JR LD SUB JR JR DEC INC INC EX DEC JR POP POP AND PUSH RST DEFB DEFB POP PUSH CALL POP PUSH CALL POP
AF HL #343C,EXCHANGE DE DE,HL AF 2,A NZ,#3559,STRINGS AF #300F,SUBTRACT #358C,END-TESTS AF #2BF1,STK-FETCH DE BC #2BF1,STK-FETCH HL A,H L (SP),HL A,B NZ,#3575,SEC-PLUS C BC Z,#3572,BOTH-NULL AF #3588,STR-TEST AF #3588,STR-TEST C Z,#3585,FRST-LESS A,(DE) (HL) C,#3585,FRST-LESS NZ,#356B,SECND-LOW BC DE HL (SP),HL HL #3564,BYTE-COMP BC AF A AF #28,FP-CALC #A0,stk-nula #38,konec výpočtu AF AF C,#3501,NOT AF AF NC,#34F9,GREATER-0 AF
jsou považovány za své komplementární operace jakmile jsou hodnoty zaměněny.
Číselná porovnání jsou oddělena od řetězcových porovnání otestováním bitu 2. Číselné oper. mají rozsah #00-#01 s CY=1 pro "=" a "<>". Uschovej doplněk. Čísla jsou odečtena pro závěrečné testy. Řetězc. porov. mají rozsah #02-#03 s CY=1 pro "=" a "<>". Uschovej doplněk. Délky a počáteční adresy řetězců jsou vyzvednuty ze zásobníku kalkulátoru.
Délka 2. řetězce.
Skoč pokud druhý řetězec není nulový. Zde je 2. řetězec buď nulový nebo menší než 1. řetězec.
CY je komplementováno k dosažení správného výsledku testu. Zde je CY použito tak, jak je. První řetězec je nyní nulový, 2. ne. Ani jeden řetězec není nulový takže mohou být porovnány jejich další bajty. První Druhý Bajty takže
bajt je menší. bajt je menší. se rovnají, délky jsou dekrementovány a
provede se skok na BYTE-COMP k porovnání dalších bajtů.
CY je vynulováno pro dosažení správných výsledků testu. Pro řetězcové testy je na zás. kalkulátoru uložena 0.
Tyto tři testy, dávají správné výsledky pro všech dvanáct porovnání. Počáteční CY je =1 pro "<>" a "=" a výsledné
Komentovaný výpis paměti ROM
RRCA CALL RET
CY je nastaveno pro ">”, “<” a “=”. NC,#3501,NOT
Hotovo.
OPERACE "STRING CONCATENATION“ Doplněk: #17 "strs-add" Tento podprogram provádí binární operaci A$+B$. Parametry obou řetězců jsou vyzvednuty a je vypočtena celková délka. V pracovním prostoru je vytvořen dostatečný prostor pro oba řetězce, které jsou pak do něj překopírovány. Výsledkem tohoto podprogramu je proto vytvoření přechodné proměnné A$+B$, která se nachází v pracovním prostoru. 359C
35B7
STRS-ADD
OTHER-STR
CALL PUSH PUSH CALL POP PUSH PUSH PUSH ADD LD LD RST CALL POP POP LD OR JR LDIR POP POP LD OR JR LDIR
#2BF1,STK-FETCH DE BC #2BF1,STK-FETCH HL HL DE BC HL,BC B,H C,L #30,BC-SPACES #2AB2,STK-STO-$ BC HL A,B C Z,#35B7,OTHER-STR BC HL A,B C Z,#35BF,STK-PNTRS
Parametry druhého řetězce jsou vyzvednuty a uschovány.
Parametry prvního řetězce jsou vyzvednuty. Délky jsou nyní v registrových párech HL a BC. Parametry 1. řetězce jsou uschovány. Je vypočtena celková délka obou řetězců a uložena do BC. Je vytvořen pracovní prostor. Param. nového řetězce jsou předány na zásobník kalkul. Jsou obnoveny parametry 1. řetězce a
pokud není nulový, je okopírován do pracovního prostoru. Identická procedura následuje pro druhý řetězec, čímž se dosáhne výsledku A$+B$.
PODPROGRAM "STK-PNTRS" Podprogram vrací HL jako ukazatel na první bajt poslední hodnoty, tedy STKEND-5 a DE ukazuje jedno místo za poslední hodnotu, tedy na STKEND. 35BF
STK-PNTRS
LD LD PUSH ADD POP RET
HL,(#5C65) (STKEND) Vyzvedni aktuální hodnotu STKEND. DE,#FFFB Nastav DE na -5. HL Uschovej STKEND. HL,DE Vypočti STKEND - 5. DE Vyzvedni STKEND do DE. Vrať se.
FUNKCE "CHR$" Doplněk #2F: "chrs" Podprogram zpracuje funkci CHR$ X a vytvoří příslušný znak v pracovním prostoru. 35C9
CHRS
CALL JR JR
#2DD5,FP-TO-A C,#35DC,REPORT-B NZ,#35DC,REPORT-B
Poslední hodnota do A. Je-li x>255, ohlaš chybu. Je-li x záporné číslo, ohlaš chybu.
Komentovaný výpis paměti ROM
207
PUSH LD RST POP LD CALL EX RET 35DC
REPORT-B
AF BC,#0001 #30,BC-SPACES AF (DE),A #2AB2,STK-STO-$ DE,HL
RST #08,ERROR-1 DEFB #0A
Uschovej hodnotu x a vytvoř jedno místo v pracovním prostoru. Vyzvedni x a vlož jej do místa v pracovním prostoru. ULOŽ parametry tohoto řetězce na zásobník kalkulátoru. Zaměň ukazatele a vrať se. Ohlaš: B-Integer out of range
FUNKCE "VAL" A "VAL$" Doplněk #1D: "val". Doplněk #18: "val$". Podprogram provádí funkce VAL X$ a VAL$ X$. Při obsluze VAL X$ se provede číselné ohodnocení výrazu a výsledek se uloží jako poslední hodnota na zásobník kalkulátoru. Při obsluze VAL$ X$ se provede řetězcové ohodnocení výrazu a parametry řetězce se uloží jako poslední hodnota na zásobník kalkulátoru. Doplněk vstupuje v registru B. 35DE
VAL
360C
V-RPORT-C
208
LD PUSH LD ADD SBC PUSH CALL PUSH INC RST POP LD PUSH LDIR EX DEC LD RES CALL RST CP JR POP POP XOR AND JP LD SET CALL POP LD JR
HL,(#5C5D) (CH-ADD) HL A,B A,#E3 A,A AF #2BF1,STK-FETCH DE BC #30,BC-SPACES HL (#5C5D),DE (CH-ADD) DE
Aktuální hodnota CH-ADD je uschována na zásobníku. Doplněk do A. Vytvoř #00 a CY=1 pro "val" nebo #FB a CY=0 pro "val$". Vytvoř #FF (bit 6=1) pro "val" nebo #00 (bit 6=0) "val$" Uschovej vlajku. Vyzvedni parametry řetězce, uschovej jeho začátek, zvětši délku a vytvoř místo v pracovním prostoru. Obnov začátek řetězce v HL. Ukazatel na první nově vytvořené místo jde do CH-ADD a na zásobník. Kopíruj řetězec do vytvořeného prostoru. DE,HL Zaměň ukazatele. HL Bajt "navíc" (HL),#0D je nahrazen znakem "CR" (ENTER). 7,(IY+1) (FLAGS) Nuluj vlajku "syntax/run" #24FB,SCANNING a proveď kontrolu správnosti syntaxe. #18,GET-CHAR Vyzvedni znak za řetězcem. #0D Pokud to není znak "CR", NZ,#360C,V-RPORT-C ohlaš chybu. HL Obnov začátek řetězce v HL. AF Vyzvedni vlajku "val/val$" (IY+1) (FLAGS) a testuj bit 6 oproti #40 výsledku kontroly syntaxe. NZ,#1C8A,REPORT-C Ohlaš chybu, pokud se neshodují. (#5C5D),HL (CH-ADD) Začátek řetězce do CH-ADD. 7,(IY+1) (FLAGS) Signál: program v běhu. #24FB,SCANNING Řetěz je zprac. jako "další výraz" a jeho hod. uložena. HL Vyzvedni (#5C5D),HL (CH-ADD) a obnov původní hodnotu v CH-ADD. #35BF,STK-PNTRS Vrať se přes STK-PNTRS, což nastaví systémové ukazatele.
Komentovaný výpis paměti ROM
FUNKCE "STR$" Doplněk: #2E "str$" Podprogram provede funkci STR$ X a vrací parametry řetězce, obsahujícího ten samý text, který by se objevil na obrazovce při provedení příkazu PRINT X. 361F
STR$
LD RST LD PUSH LD PUSH LD CALL CALL POP CALL POP LD AND SBC LD LD CALL EX RET
BC,#0001 #30,BC-SPACES (#5C5B),HL (K-CUR) HL HL,(#5C51) (CURCHL) HL A,#FF #1601,CHAN-OPEN #2DE3,PRINT-FP HL #1615,CHAN-FLAG DE HL,(#5C5B) (K-CUR) A HL,DE B,H C,L #2AB2,STK-STO-$ DE,HL
Vytvoř jedno místo v pracovního prostoru, kopíruj jeho adresu do K-CUR a také ji ulož na zásobník. Aktuální kanálová adresa je uložena na zásobník. Otevři kanál "R", což umožní výstup řetězce do pracovní oblasti. Poslední hodnota X, je vytištěna do pracovního prostoru. Obnov adresu aktuálního kanálu do HL a obnov také příznaky, které mu přináleží. Obnov počáteční adresu řetězce. Adresa kurzoru ukazuje jedno místo za řetězec a proto rozdíl ukazatelů je délkou řetězce, která je převedena do BC. Parametry řetězce jsou uloženy na zásobník kalkulátoru. Zaměň ukazatele a vrať se.
PODPROGRAM "READ-IN" Doplněk: #1A "read-in" Tento podprogram je volán přes kalkulátor pomocí doplňku z prvního řádku podprogramu INKEY$. Umožňuje načítání dat přes různé proudy, které jsou ve standardním SPECTRU. Stejně jako INKEY$, vrací i tento podprogram parametry řetězce. 3645
READ-IN
365F
R-I-STORE
CALL CP JP LD PUSH CALL CALL LD JR INC RST LD CALL POP CALL JP
#1E94,FIND-INT1 #10 NC,#1E9F,REPORT-B HL,(#5C51) (CURCHL) HL #1601,CHAN-OPEN #15E6,INPUT-AD BC,#0000 NC,#365F,R-I-STORE C #30,BC-SPACES (DE),A #2AB2,STK-STO-$ HL #1615,CHAN-FLAG #35BF,STK-PNTRS
Kompresuj číselný parametr do A a jestliže není menší než 16, ohlaš chybu. Aktuální kanálová adresa je uložena na zásobník. Otevři kanál specifikovaný parametrem a přijmi jakoby "hodnotu klávesy". Délka řetězce při "neplnění" je 0. Skoč, jestliže nebyl žádný signál. Nastav délku na 1, vytvoř tento prostor, a vlož do něj řetězec. Předej parametry řetězce na zásobník kalkulátoru. Vyzvedni kanálovou adresu a obnov příslušné vlajky. Vrať se přes STK-PNTRS, což nastaví systémové ukazatele.
FUNKCE "CODE" Doplněk: #1C "CODE" Podprogram provede funkci CODE A$ a vrací kód prvního znaku z řetězce A$ nebo 0, pokud byl řetězec A$ nulový. 3669
CODE
CALL LD
#2BF1,STK-FETCH A,B
Vyzvedni parametry řetězce. Testuj délku
Komentovaný výpis paměti ROM
209
3671
STK-CODE
OR JR LD JP
C Z,#3671,STK-CODE A,(DE) #2D28,STACK-A
a pokud je nulové, skoč dopředu. Vyzvedni kód prvního znaku a před návratem jej ulož na zásobník kalkulátoru.
FUNKCE "LEN" Doplněk: #1E "len" Podprogram provede funkci LEN A$ a vrací délku řetězce jako poslední hodnotu na zásobníku kalkulátoru. 3674
LEN
CALL JP
#2BF1,STK-FETCH #2D2B,STACK-BC
Vyzvedni parametry řetězce a proveď návrat přes STACK-BC, který uloží posl. hodnotu.
PODPROGRAM "DECREASE THE COUNTER" Doplněk: #35 "dec-jr-nz" Podprogram je využíván pouze podprogramem SERIES GENERATOR a ve skutečnosti provádí instrukci DJNZ, ale čítačem je proměnná BREG a ne registr B. 367A
DEC-JR-NZ
EXX PUSH LD DEC POP JR INC EXX RET
HL HL,#5C67 (HL) HL NZ,#3687,JUMP-2 HL
Přepni na zrcadlové registry a uschovej ukazatel na další literál. HL ukazuje na BREG. Dekrementace BREG. Obnovení ukazatele na další literál. Skoč při nenulovém BREG. Překroč další literál. Přepni na hlavní registry a vrať se.
PODPROGRAM "JUMP" Doplněk: #33 "jump" Podprogram provede nepodmíněný skok při zavolání literálem #33. Je také používán podprogramy DECREASE THE COUNTER a JUMP ON TRUE. 3686 3687
JUMP JUMP-2
EXX LD LD RLA SBC LD ADD EXX RET
E,(HL) A,E A,A D,A HL,DE
Přepni na zrcadlové registry. Vyzvedni délku skoku do registru E'. V registru A se vytvoří hodnota #00 pro kladná čísla nebo #FF pro záporná čísla a je převedena do D'. H'L' obsahuje cílovou adresu. Přepni na hlavní registry. Hotovo.
PODPROGRAM "JUMP ON TRUE" Doplněk: #00 "jump-true" Podprogram provede podmíněný skok, jestliže "poslední hodnota" na zásobníku kalkulátoru je pravdivá. Její adresa je v DE. 368F
210
JUMP-TRUE
INC INC LD DEC DEC
DE DE A,(DE) DE DE
Posuň ukazatel na třetí bajt čísla, který je buď nula nebo jedna a vyzvedni je do A. Opět ukazuj na první bajt. Komentovaný výpis paměti ROM
AND JR EXX INC EXX RET
A NZ,#3686,JUMP HL
Je třetí bajt nula? Proveď skok, jestliže není nulový (=pravda). Přepni na zrcadlové registry. Překroč literál udávající délku skoku. Přepni na hlavní registry. Hotovo.
PODPROGRAM "END-CALC" Doplněk: #38 "end-calc" Podprogram ukončí operaci RST #28. 369B
END-CALC
POP EXX EX EXX RET
AF (SP).HL
Zahoď adresu zpětných návratů do kalkulátoru. Přepni na zrcadlové registry a ulož adresu z HL na zásobník. Přepni na hlavní registry. Skoč na dřívější adresu dodanou z HL.
PODPROGRAM "MODULUS" Doplněk: #32 "n-mod-m" Podprogram počítá N (mod M), kde M je kladné celé číslo na vrcholu zásobníku kalkulátoru a N je celé číslo pod vrcholem zásobníku. Podprogram vrací celočíselnou část podílu INT(N/M) na vrcholu zásobníku (tedy jako poslední hodnotu) a pod vrchol zásobníku uloží zbytek N-INT(N/M). Podprogram se používá při výpočtu náhodných čísel ke snížení N mod 65537. 36A0
N-MOD-M
RST DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB RET
#28,FP-CALC #C0,st-mem-0 #02,výmaz #31,zdvojení #E0,get-mem-0 #05,dělení #27,int #E0,get-mem-0 #01,záměna #C0,st-mem-0 #04,násobení #03,odečítání #E0,get-mem-0 #38,konec výpočtu
N,M N,M (M do mem-0) N N,N N,N,M N,N/M N,INT(N/M) N,INT(N/M),M N,M,INT(N/M) INT(N/M) do mem-0. N,M*INT(N/M) N-M*INT(N/M) N-M*INT(N/M),INT(N/M) Hotovo.
FUNKCE "INT" Doplněk: #27 "int" Podprogram vrací jako poslední hodnotu celočíselnou část čísla, které je při vstupu na vrcholu zásobníku kalkulátoru. Tedy INT 2.4 dává 2, ale protože podprogram zaokrouhluje směrem dolů, bude INT -2.4 roven -3. 36AF
INT
RST DEFB DEFB DEFB DEFB
#28,FP-CALC #31,zdvojení #36,<0 #00,skok-pravda #04,na #36B7,X-NEG
X X,X X,(1/0) (logická hodnota) X X
Pro případ, že X>=0, se nyní nalezne celočíselná část X.
Komentovaný výpis paměti ROM
211
DEFB DEFB RET
#3A,truncate #38,konec výpočtu
I(X) Hotovo.
Pro záporné celé číslo se vrací hodnota I(X), pro ostatní záporná čísla se vrací I(X)-1. 36B7
X-NEG
DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB
#31,zdvojení #3A,truncate #C0,st-mem-0 #03,odečítání #E0,get-mem-0 #01,záměna #30,not #00,skok-pravda #03,na #36C2,EXIT
X,X X,I(X) I(X) jde do mem-0. X-I(X) X-I(X),I(X) I(X),X-I(X) I(X),(1/0) (logická hodnota). I(X) I(X)
Pro záporná celá čísla se provede přeskok.
36C2
DEFB DEFB DEFB RET
EXIT
#A1,stk-jedna #03,odečítání #38,konec výpočtu
I(X),1 I(X)-1 I(X) nebo I(X)-1
FUNKCE "EXPONENTIAL" Doplněk: #26 "exp" Podprogram provádí funkci EXP X a je prvním ze čtyř podprogramů, které GENERATOR k vytváření Čebyševových polynomů. Aproximace INT X je nalezena takto: a) b) c) d) e) f)
používají
SERIES
X je děleno LN 2 k získání Y, takže 2 na Y-tou dává požadovaný výsledek. Je nalezena hodnota N pro kterou platí, že N=INT Y. Je nalezena hodnota W pro kterou platí, že W=Y-N, kde 0<=W<=1. Je vytvořen argument Z takový, že Z=2*W-1. Použitím SERIES GENERATOR se získá hodnota 2^W. Konečně se přičte N k exponentu, což dává 2^(N+W), neboli 2^Y a tedy požadovaný výsledek EXP X.
36C4
EXP
1. 2. 3. 4. 212
RST DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB
#28,FP-CALC #3D,re-stack #34,stk-data #F1,exponent #81 #38,#AA,#3B,#29 #04,násobení #31,zdvojení #27,int 1C46 #C3,st-mem-3 #03,odečítání #31,zdvojení #0F,sčítání #A1,stk-jedna #03,odečítání #88,serie-08 #13,exponent #63 #36,(#00,#00,#00) #58,exponent #68 #65,#66,(#00,#00) #9D,exponent #6D #78,#65,#40,(#00) #A2,exponent #72
X X (X ve formě FP). X,1/LN2
X/LN2 (dále jen Y,Y Y,INT Y (dále N do mem-3. Y-N (dále jen W,W 2*W 2*W,1 2*W-1 (dále jen Z
Y). N). W).
Z).
Komentovaný výpis paměti ROM
5. 6. 7. 8.
3703
REPORT-6
3705
N-NEGTV
370C
RESULT-OK
370E
RSLT-ZERO
DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB CALL JR JR ADD JR RST DEFB JR SUB JR NEG LD RET RST DEFB DEFB DEFB RET
#60,#32,#C9,(#00) #E7,exponent #77 #21,#F7,#AF,#24 #EB,exponent #7B #2F,#B0,#B0,#14 #EE,exponent #7E #7E,#BB,#94,#58 #F1,exponent #81 #3A,#7E,#F8,#CF #E3,get-mem-3 #38,konec výpočtu #2DD5,FP-TO-A NZ,#3705,N-NEGTV C,#3703,REPORT-6 A,(HL) NC,#370C,RESULT-OK #08,ERROR-1 #05 C,#370E,RSLT-ZERO (HL) NC,#370E,RSLT-ZERO (HL),A #28,FP-CALC #02,výmaz #A0,stk-nula #38,konec výpočtu
2^W 2^W,N Do registru A je vložena absolutní hodnota N mod 256. Skoč dopředu při záporném N. Ohlaš chybu, je-li ABS N > 255. Přičti ABS N k exponentu. Skoč, je-li e>255. Ohlaš: 6-Number too big. Výsledek má být 0, jestliže n < -255. Odečti ABS N od exponentu, protože N bylo záporné. Výsledek bude nula pro e < 0. Mínus e je změněno na plus e. Vlož exponent e. Hotovo. Použij kalkulátor a vlož exponent e = 0. Hotovo.
FUNKCE PŘIROZENÉHO LOGARITMU Doplněk: #25 "ln" Tento podprogram provádí funkci LN x a je druhým ze podprogram SERIES GENERATOR k vytváření Čebyševových polynomů.
čtyř
podprogramů,
které
používají
Aproximace LN x je nalezena následovně: a) Testuje se x a je ohlášena chyba A, pokud x není kladné. b) Dále je x rozděleno na exponent e' a mantisu x'=x/(2^e'), kde x' >= .5 ale x' < 1. c) Jsou formovány požadované hodnoty y1 nebo y2. Je-li x' > .8, pak y1 = e'*LN2, jinak y2 =(e'-1)*LN2. d) Jestliže x' > .8, pak je na zásobník úložna hodnota x' -1, jinak 2*x'-1. e) Jestliže x' > .8, pak bude argument z = 2.5*x'-3, jinak z = 5*x'-3. Vždy pak musí platit že -1 <= z <= 1 (což je podmínka pro konvergenci řady). f) K vytvoření požadované funkce se použije podprogram "SERIES GENERATOR". g) Nakonec se užije obyčejné násobení a sčítání a LN x se vrací jako poslední hodnota na zásobníku kalkulátoru. 3713
LN
RST
#28,FP-CALC
x
#3D,re-stack #31,zdvojení #37,>0 #00,skok-pravda #04,na 371C,VALID #38,konec výpočtu
x (v plné FP formě) x,x x,(1/0) (logická hodnota). x x
Proveď krok a). DEFB DEFB DEFB DEFB DEFB DEFB
Komentovaný výpis paměti ROM
213
371A
REPORT-A
RST DEFB
#08,ERROR-1 #09
Ohlaš: A-Invalid argument
#A0,stk-nula #02,výmaz #38,konec výpočtu A,(HL) (HL),#80 #2D28,STACK-A #28,FP-CALC #34,stk-data #38,exponent #88 #00,(#00,#00,#00) #03,odečítání
x,0 x x Exponent e jde do registru A. x je sníženo na x'. Na zásobníku je:x',e. x',e x',e,128 (dekadicky) x',e
#01,záměna #31,zdvojení #34,stk-data #F0,exponent #80 #4C,#CC,#CC,#CD #03,odečítání #37,>0 #00,skok-pravda #08,na 373D,GRE.8 #01,záměna #A1,stk-jedna #03,odečítání #01,záměna #38,konec výpočtu (HL) #28,FP-CALC #01,záměna #34,stk-data #F0,exponent #80 #31,#72,#17,#F8 #04,násobení
e',x' e',x',x' e',x',x',0.8
Proveď krok b). 371C
VALID
DEFB DEFB DEFB LD LD CALL RST DEFB DEFB DEFB DEFB
x',e'
Proveď krok c).
373D
GRE.8
DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB INC RST DEFB DEFB DEFB DEFB DEFB
e',x',x'-0.8 e',x',(1/0) e',x' e',x' x',e' x',e',1 x',e'-1 e'-1,x' e'-1,x' e'-1,2*x' postup pro x' větší x',e' x',e',LN2
postup pro x' menší 2*x',e'-1 2*x',e'-1,LN2
x',e'*LN2 (=y1)
2*x',(e'-1)*LN2 (=y2)
#01,záměna #A2,stk-polovina #03,odečítání #A2,stk-polovina #03,odečítání
y1,x' y1,x',.5 y1,x'-.5 y1,x'-.5,.5 y1,x'-1
y2,2*x' y2,2*x',.5 y2,2*x'-.5 y2,2*x'-.5,.5 y2,2*x'-1
#31,zdvojení #34,stk-data #32,exponent #82 #20,(#00,#00,#00) #04,násobení #A2,stk-polovina #03,odečítání
y1,x'-1,x'-1 y1,x'-1,x'-1,2.5
y2,2*x'-1.2*x'-1 y2,2*x'-1,2*x'-1,2.5
y1,x'-1,2.5*x'-2.5 y1,x'-1,2.5*x'-2.5,.5 y1,x'-1,2.5*x'-3 (=z)
y2,2*x'-1,5*x'-2.5 y2,2*x'-1,5*x'-2.5,.5 y2,2*x'-1,5*x'-3 (=z)
Proveď krok d). DEFB DEFB DEFB DEFB DEFB Proveď krok e). DEFB DEFB DEFB DEFB DEFB DEFB DEFB 214
Komentovaný výpis paměti ROM
Proveď krok f).
1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12.
DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB
#8C,série-0C #11,exponent #61 #AC,(#00,#00,#00) #14,exponent #64 #09,(#00,#00,#00) #56,exponent #66 #DA,#A5,(#00,#00) #59,exponent #69 #30,#C5,(#00,#00) #5C,exponent #6C #90,#AA,(#00,#00) #9E,exponent #6E #70,#6F,#61,(#00) #A1,exponent #71 #CB,#DA,#96,(#00) #A4,exponent #74 #31,#9F,#B4,(#00) #E7,exponent #77 #A0,#FE,#5C,#FC #EA,exponent #7A #1B,#43,#CA,#36 #ED,exponent #7D #A7,#9C,#7E,#5E #F0,exponent #80 #6E,#23,#80,#93
Nyní je poslední hodnota:
y1,x'-1,z
y2,2*x'-1,z
LNx'/(x'-1)
LN(2*x')/(2*x'-1)
LN(2^e'),LNx' LN((2^e')*x') LN x Poslední hodnota je LN x.
LN(2^(e'-1)),LN(2*x') LN(2^(e'-1)*2*x')
Proveď krok g). DEFB DEFB DEFB RET
#04,násobení #0F,sčítání #38,konec výpočtu
PODPROGRAM "REDUKCE ARGUMENTU" Doplněk #39: "get-argt" Podprogram převede argument funkce SIN nebo COS na hodnotu v. hodnotu y, pro které platí: y=x/(2*PI)-INT(x/2*PI)+.5), kde .5 > y >= -.5 . Podprogram vrací: a) v=4*y pokud -1 <= 4*y <= 1 b) v=2 až 4*y pokud 1 < 4*y < 2 c) v=4*y-2 pokud -2 <= 4*y < -1 Ve všech případech -1 <= v <= 1 a SIN (PI* v/2)=SIN x. 3783
GET-ARGT
RST DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB
#28,FP-CALC #3D,re-stack #34,stk-data #EE,exponent #7E #22,#F9,#83,#6E #04,násobení #31,zdvojení #A2,stk-polovina #0F,sčítání
Program
nejprve
nalezne
x x (v plné FP formě) x,1/(2*PI)
x/(2*PI) x/(2*PI),x/(2*PI) x/(2*PI),x/(2*PI),.5 x/(2*PI),x/(2*PI)+.5
Komentovaný výpis paměti ROM
215
DEFB DEFB
#27,int 1C46 #03,odečítání
x/(2*PI),INT(x/(2*PI)+.5) x/(2*PI)-INT(x/(2*PI)+.5)=y
Poznámka: přičtení 0.5 a provedení INT zaokrouhlí výsledek na nejbližší celé číslo. DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB RET
#31,zdvojení #0F,sčítání #31,zdvojení #0F,sčítání #31,zdvojení #2A,abs #A1,stk-jedna #03,odečítání #31,zdvojení #37,>0 #C0,st-mem-0 #00,skok-pravda #04,na #37A1,ZPLUS #02,výmaz #38,konec výpočtu
y,y 2*y 2*y,2*y 4*y 4*y,4*y 4*y,ABS(4*y) 4*y,ABS(4*y),1 4*y,ABS(4*y)-1=z 4*y,z,z 4*y,z,(1/0) Mem-0 obsahuje výsledek testu. 4*y,z 4*y,z 4*y 4*y=v (ad a)
Po provedení skoku pokračuj zde. 37A1
ZPLUS
37A8
YNEG
DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB RET
#A1,stk-jedna #03,odečítání #01,záměna #36,<0 #00,skok-pravda #02,na #37A8,YNEG #1B,negace #38,konec výpočtu
4*y,z,1 4*x,z-1 z-1,4*y z-1,(1/0) z-1 z-1 1-z 1-z=v (ad b) z-1=v (ad c)
FUNKCE "COS" Doplněk #20: "cos" Podprogram vrací poslední hodnotu jako aproximaci COS x. Používá výraz: COS x=SIN (PI*W/2), kde -1 <= W <= 1.Při derivaci W podle x používá podprogram výsledek testu z předchozího podprogramu. Tento je uložen v mem-0. Podprogram pokračuje skokem do podprogramu SINE v bodě C-ENT a vrací poslední hodnotu COS x. 37AA
COS
RST DEFB DEFB DEFB DEFB DEFB DEFB DEFB
#28,FP-CALC #39,get-argt #2A,abs #A1,stk-jedna #03,odečítání #E0,get-mem-0 #00,skok-pravda #06,na #37B7,C-ENT
x v ABS ABS ABS ABS ABS ABS
v v,1 v-1 v-1,(1/0) v-1 v-1 =W
Pokud nedošlo ke skoku, pokračuj zde. DEFB DEFB DEFB
216
#1B,negace #33,skok #03,na #37B7,C-ENT
1-ABS v 1-ABS v 1-ABS v =W
Komentovaný výpis paměti ROM
FUNKCE "SINUS" Doplněk #1F: "sin" Podprogram je třetím ze čtyř, které používají podprogram Čebyševových polynomů. Aproximace SIN x je nalezena následovně:
"SERIES
GENERATOR"
k
vytváření
a) Argument x je redukován a v tomto případě se provede přímo W=v. Povšimněte si,že -1 <= W <= 1 (pro konvergenci řady). b) Je vytvořen argument Z, takový, že Z=2*W*W-1. C) Použije se "SERIES GENERATOR" k získání (SIN (PI*W/2))/W. d) Konečně prostým násobením se získá hodnota SIN x. 37B5
SIN
RST
Proveď krok a). DEFB
#28 FP-CALC
x
#39,get-argt
W
#31,zdvojení #31,zdvojení #04,násobení #31,zdvojení #0F,sčítání #A1,stk-jedna #03,odečítání
W,W W,W,W W,W*W W,W*W,W*W W,2*W*W W,2*W*W,1 W,2*W*W-1 =Z
#86,série-06 #14,exponent #64 #E6,(#00,#00,#00) #5C,exponent #6C #1F,#0B,(#00,#00) #A3,exponent #73 #8F,#38,#EE,(#00) #E9,exponent #79 #15,#63,#BB,#23 #EE,exponent #7E #92,#0D,#CD,#ED #F1,exponent #81 #23,#5D,#1B,#EA
W,Z
Proveď krok b). 37B7
C-ENT
DEFB DEFB DEFB DEFB DEFB DEFB DEFB
Proveď krok c).
1. 2. 3. 4. 5. 6.
DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB
Po posledním průchodu smyčkou je poslední hodnota (SIN(PI*W/2))/W. DEFB DEFB RET
#04,násobení SIN (PI*W/2)=SIN x (nebo COS x) #38,konec výpočtu Poslední hodnota na zásobníku kalkulátoru je SIN x (nebo COS x).
FUNKCE "TAN" Doplněk #21: "tan" Podprogram vrací poslední hodnotu SIN x/COS x s aritmetickým přetečením, je-li COS x=0. 37DA
TAN
RST DEFB DEFB DEFB DEFB
#28,FP-CALC #31,zdvojení #1F,sin #01,záměna #20,cos
Komentovaný výpis paměti ROM
x x,x x,SIN x SIN x,x SIN x,COS x 217
DEFB #05,dělení DEFB #38,konec výpočtu RET
Je-li to potřeba, ohlaš aritmetické přetečení. TAN x Poslední hodnota na zásobníku kalkulátoru je TAN X.
FUNKCE "ARCTAN" Doplněk #24: "atn" Podprogram je posledním ze čtyř, které používají podprogram "SERIES GENERATOR“ k vytváření Čebyševových polynomů. Podprogram vrací reálné číslo mezi –PI/2 a PI/2, které se rovná hodnotě v radianech úhlu, jehož TAN je x. Aproximace ATN x je nalezena takto: Hodnoty W a Y jsou nalezeny a1) Jestliže -1 < x < 1 pak a2) Jestliže 1 <=x pak a1) Jestliže x<=-1 pak
pro tyto W=0 W=PI/2 W=-PI/2
tři případy hodnoty x a argument Z je & Y=x b1) argument Z=2*Y*Y-1 & Y=-1/x b2) argument Z=2*Y*Y-1 & Y=-1/x b3) argument Z=2*Y*Y-1
pak formován takto: =2*x*x-1 =2/(x*x)-1 =2/(x*x)-1
Ve všech případech musí být splněna podmínka pro konvergenci řad y: -1 <= Y <= 1. c) Použije se "SERIES GENERATOR" k získání požadované funkce. d) Konečně prostým násobením a sčítáním se získá hodnota ATN x. Proveď krok a). 37E2
ATN
37F8
SMALL
CALL LD CP JR RST DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB RST DEFB
#3297,RE-STACK A,(HL) #81 C,#37F8,SMALL #28,FP-CALC #A1,stk-jedna #1B,negace #01,záměna #05,dělení #31,zdvojení #36,<0 #A3,stk-pi/2 #01,záměna #00,skok-pravda #06,na #37FA,CASES #1B,negace #33,skok #03,na #37FA,CASES #28,FP-CALC #A0,stk-nula
Použij FP formu x. Vyzvedni exponent x. Jestliže x=Y skoč dopředu v případě 1. x x,1 x,-1 -1,x -1/x -1/x,-1/x -1/x,(1/0) -1/x,(1/0),PI/2 -1/x,PI/2,(1/0) -1/x,PI/2 Skok vpřed v případě 2. -1/x,-PI/2
#01,záměna #31,zdvojení #31,zdvojení #04,násobení #31,zdvojení #0F,sčítání #A1,stk-jedna #03,odečítání
W,Y W,Y,Y W,Y,Y,Y W,Y,Y*Y W,Y,Y*Y,Y*Y W,Y,2*Y*Y W,Y,2*Y*Y,1 W,Y,2*Y*Y-1=Z
Skok vpřed v případě 3. Y Y,0
Proveď krok b). 37FA
CASES
DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB
1.
218
DEFB #8C,série-0C DEFB #10,exponent #60 DEFB #B2,(#00,#00,#00)
W,Y,Z
Komentovaný výpis paměti ROM
2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12.
DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB
#13,exponent #63 #0E,(#00,#00,#00) #55,exponent #65 #E4,#8D,(#00,#00) #58,exponent #68 #39,#BC,(#00,#00) #5B,exponent #6B #98,#FD,(#00,#00) #9E,exponent #6E #00,#36,#75,(#00) #A0,exponent #70 #DB,#E8,#B4,(#00) #63,exponent #73 #42,#C4,(#00,#00) #E6,exponent #76 #B5,#09,#36,#BE #E9,exponent #79 #36,#73,#1B,#5D #EC,exponent #7C #D8,#DE,#63,#BE #F0,exponent #80 #61,#A1,#B3,#0C
Po posledním průchodu smyčkou je poslední hodnota: 1.) ATN X/X
2.) ATN (-1/X)/(-1/X)
3.) ATN(-1/X)/(-1/X)
Proveď krok d). DEFB #04,násobení DEFB #0F,sčítání DEFB #38,konec výpočtu RET
1.) W,ATN X ATN X
2.) W,ATN(-1/X)
3.) W,ATN(-1/X)
Poslední hodnota na zásobníku kalkulátoru je ATN X.
FUNKCE "ARCSIN" Doplněk #22: "asn" Podprogram vrací reálné číslo mezi -PI/2 a PI/2, které se rovná hodnotě úhlu v rad,jehož SIN je x. Jestliže y=ASN x, potom x=SIN y. Podprogram používá trigonometrickou identitu: TAN (y/2)=SIN y/1*(1+COS y) 3833
ASN
RST DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB RET
#28,FP-CALC #31,zdvojení #31, " #04,násobení #A1,stk-jedna #03,odčítání #1B,negace #28,sqr #A1,stk-jedna #0F,sčítání #05,dělení #24,atn #31,zdvojení #0F,sčítání #38,konec výpočtu
x x,x x,x,x x,x*x x,x*x,1 x,x*x-1 x,1-x*x x,SQR(1-x*x) x,SQR(1-x*x),1 x,1+SQR(1-x*x) x/(1+SQR(1-x*x)) =TAN(y/2) y/2 y/2,y/2 y=ASN x
Komentovaný výpis paměti ROM
219
Poslední hodnota na zásobníku kalkulátoru je ASN x.
FUNKCE "ARCCOS" Doplněk #23: "acs" Podprogram provede ACS x a vrací reálné číslo od 0 do PI včetně, které je rovno velikosti úhlu v rad, jehož COS je x. Podprogram používá vztah: ACS x = PI/2 - ASN x. 3843
ACS
RST DEFB DEFB DEFN DEFB DEFB RET
#28,FP-CALC #22,asn #A3,stk-pi/2 #03,odčítání #1B,negace #38,konec výpočtu
x ASN x ASN x,PI/2 ASN x-PI/2 PI/2-ASN x=ACS x
FUNKCE "SQUARE ROOT" (=druhá odmocnina) Doplněk #28: "sqr" Podprogram provede SQR x a vrací kladnou druhou odmocninu reál. čísla x, je-li x kladné a nulu, je-li x nula. Záporné x vyvolá chybové hlášení A-Invalid argument (v podpr.EXPONENTATION). Podprogram provádí SQR jako x^0.5 a proto po uložení konstanty 0.5 pokračuje přímo podprogram EXPONENTATION. 384A
SQR
RST DEFB DEFB DEFB DEFB DEFB DEFB
#28,FP-CALC #31,zdvojení #30,not #00,skok-pravda #1E,na #386C,LAST #A2,stk-polovina #38,konec výpočtu
x x,x x,(1/0) x x x,.5
OPERACE "EXPONENTATION" Doplněk #06: "to-power" Podprogram provádí binární operaci x na y, kterou považuje za ekvivalentní EXP (Y * LN x). Pokud x=0, výsledek je 1 pokud y=0 (0^0=1), vrací 0 když je y kladné. Při záporném y je hlášena chyba. 3851
TO-POWER
RST DEFB DEFB DEFB DEFB DEFB
#28,FP-CALC #01,záměna #31,zdvojení #30,not #00,skok-pravda #07,na #385D,XIS0
x,y y,x y,x,x y,x,(1/0) y,x y,x
Je-li x=0, provede se skok. DEFB DEFB DEFB JP
#25,ln #04,násobení #38,konec výpočtu #36C4,EXP
y,LN x (pro x<0 chybové hlášení) y*LN x
Zde se posoudí 3 případy pro nulové x. 385D
220
XIS0
DEFB #02,výmaz DEFB #31,zdvojení DEFB #30,not
y y,y y,(1/0)
Komentovaný výpis paměti ROM
DEFB #00,skok-pravda DEFB #09,na #386A,ONE
y y
Skoč je-li x=0 a y=0. DEFB DEFB DEFB DEFB DEFB
#A0,stk-nula #01,záměna #37,>0 #00,skok-pravda #06,na #386C,LAST
y,0 0,y 0,(1/0) 0
Skoč je-li x=0 a y kladné.
386A
ONE
386C
LAST
DEFB DEFB DEFB DEFB DEFB DEFB RET
#A1,stk-jedna #01,záměna #05,dělení #02,výmaz #A1,stk-jedna #38,konec výpočtu
0,1 1,0 Dělení nulou-chyba. 1
386E ..... 3CFF
DEFB #FF,#FF,......
ROM Spectrum 48 nevyužívá
3D00 až 3FFF
DEFB matice znakového souboru ASCII #20-#7F.
Př. písmeno "A" je zde uloženo takto: DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB
#00 #3C #42 #42 #7E #42 #42 #00
00000000 00111100 01000010 01000010 01111110 01000010 01000010 00000000
Komentovaný výpis paměti ROM
221
Přehled systémových proměnných:
Písmena ve sloupci Pozn. mají následující význam: X Pokud změníte obsah této proměnné, systém se může zhroutit. M Změnou hodnoty této proměnné nezískáte žádný efekt. Číslice ve sloupci Pozn. udávají velikost proměnné v bajtech. Ve sloupci Obsah je uvedena hodnota proměnné po zapnutí počítače. Pokud není hodnota uvedena, nemá tato proměnná po zapnutí rozumný obsah.
Pozn. N8 N1 1 1 N2 N1 N2 X38 2 1 1 1 X1 X2 N2 N1 2 1 2 1 1 2 X2 N2 X2 X2 X2 X2 X2 X2 2 X2 2 X2 X2 X2 N1 N2 1 X1 2 2 1 222
Adresa
5C00 5C08 5C09 5C0A 5C0B 5C0D 5C0F 5C10 5C36 5C38 5C39 5C3A 5C3B 5C3D 5C3F 5C41 5C42 5C44 5C45 5C47 5C48 5C49 5C4B 5C4D 5C4F 5C51 5C53 5C55 5C57 5C59 5C5B 5C5D 5C5F 5C61 5C63 5C65 5C67 5C68 5C6A 5C6B 5C6C 5C6E 5C70
23552 23560 23561 23562 23563 23565 23566 23568 23606 23608 23609 23610 23611 23613 23615 23617 23618 23620 23621 23623 23624 23625 23627 23629 23631 23633 23635 23637 23639 23641 23643 23645 23647 23649 23651 23653 23655 23656 23658 23659 23660 23662 23664
Jméno
Obsah
KSTATE LAST-K REPDEL REPPER DEFADD K-DATA TVDATA STRMS CHARS RASP PIP ERR-NR FLAGS ERR-SP LIST-SP MODE NEWPPC NSPPC PPC SUBPPC BORDCR E-PPC VARS DEST CHANS CURCHL PROG NXTLIN DATADD E-LINE K-CUR CH-ADD X-PTR WORKSP STKBOT STKEND BREG MEM FLAGS2 DF-SZ S-TOP OLDPPC OSPPC
DEFS DEFB DEFB DEFB DEFW DEFB DEFB DEFS DEFW DEFB DEFB DEFB DEFS DEFW DEFW DEFB DEFS DEFS DEFS DEFS DEFB DEFS DEFW DEFS DEFW DEFW DEFW DEFS DEFS DEFW DEFS DEFS DEFS DEFW DEFW DEFW DEFS DEFW DEFS DEFB DEFS DEFS DEFS
Význam 8 0 35 5 0 0 0,0 2*28 #3C00 64 0 255 1 #FF54 #FF54 0 2 2 2 2 %00111000 2 #5CCB 2 #5CB6 #5CBB #5CCB 2 2 #5CCC 2 2 2 #5D08 #5D08 #5D08 1 #5C92 1 2 2 2 1
Pracovní místo je využíváno při čtení kláves. Zde je uložen kód naposledy stisknuté klávesy. Čas (v 1/50 sekundy), po kterém se začne klávesa opakovat, Čas (v 1/50 sekundy), mezi opakováním kláves. Adresa argumentu uživatelské funkce. Druhý bajt řízení barev (vložený z klávesnice). Bajty barvy, AT a TAB při výstupu na obrazovku. Adresy kanálů. Adresa generátoru znaků zmenšená o 256. Délka varovného bzučáku. Délka pípnutí klávesnice. O jednu méně než číslo hlášení (chyby). Různé příznaky pro řízení systému BASIC. Adresa položky na zásobníku, která se používá při chybě. Adresa návratu z automatického výpisu programu. Určuje režim kurzoru (K, L, C, E nebo G). Číslo řádky, na kterou se má skočit. Číslo přikážu v řádce určené NEWPPC, Číslo řádky, která se právě vykonává. Číslo právě vykonávaného příkazu. Barva pozadí*8; dále obsahuje atributy pro dolní část obr. Číslo aktivní řádky (ta na které je kurzor). Adresa začátku proměnných. Adresa proměnné, do které se přiřazuje. Adresa, kde jsou uložené informace o kanálech. Adresa kanálu, který používán pro vstup a výstup. Adresa začátku programu v BASICu. Adresa další řádky v programu. Adresa ukončení poslední položky v příkazu DATA. Adresa právě napsaného příkazu. Adresa kurzoru. Adresa znaku, který se bude interpretovat. Adresa výskytu syntaktické chyby (t.j. před znakem ?). Adresa dočasné pracovní paměti. Adresa dna zásobníku kalkulátoru. Adresa vrcholu zásobníku a začátek volné paměti. Registr b kalkulátoru. Adresa pamětí kalkulátoru. Další příznaky. Počet řádek v dolní oblasti obrazovky (editační řádek). Počet řádek při automatickém výpisu programu. Číslo řádky, na kterou skočí příkaz CONTINUE. Číslo příkazu, na který skočí příkaz CONTINUE. Komentovaný výpis paměti ROM
N1 N2 N2 2 3 2 1 1 1 1 1 2 2 2 X1 X1 X1 X1 1 1 1 N1 N1 1 N30 2 2 2
5C71 5C72 5C74 5C76 5C78 5C7B 5C7D 5C7E 5C7F 5C80 5C81 5C82 5C84 5C86 5C88 5C89 5C8A 5C8B 5C8C 5C8D 5C8E 5C8F 5C90 5C91 5C92 5CB0 5CB2 5CB4
23665 23666 23668 23670 23672 23675 23677 23678 23679 23680 23681 23682 23684 23686 23688 23689 23690 23691 23692 23693 23694 23695 23696 23697 23698 23728 23730 23732
FLAGX STRLEN T-ADDR SEED FRAMES UDG COORDS
DEFS DEFS DEFS DEFW DEFS DEFW DEFS DEFS P-POSN DEFS PR-CC DEFS DEFS ECHO-E DEFW DF-CC DEFS DF-CCL DEFS S-POSN DEFS DEFS S-POSNL DEFS DEFB SCR-CT DEFS ATTR-P DEFB MASK-P DEFB ATTR-T DEFB MASK-T DEFB P-FLAG DEFS MEMBOT DEFS NMIADD DEFS RAMTOP DEFW P-RAMT DEFW
1 2 2 0 3 #FF58 1 1 1 1 1 23*256+33 2 2 1 1 1 23 1 %00111000 0 %00111000 0 1 30 2 #FF57 #FFFF
Různé příznaky. Délka pravě vyhodnocovaného řetězce (před přiřazením). Adresa další položky v tabulce syntaxe. Násada pro generování náhodných čísel. Čítač snímků. Je zvětšen každých 20ms. Adresa prvního uživatelsky definovaného znaku. Souřadnice x posledně vykresleného bodu. Souřadnice y posledně vykresleného bodu. Pozice tisku na ZX-Printer. Dolní bajt adresy bajtu při výstupu řádky na ZX-Printer Není využito. Adresa ve spodní části obr., za kterou nelze dát kurzor Adresa výstupu znaku na obrazovku. Jako DF CC, ale pro dolní část obrazovky. Pozice sloupce pro výstup znaku příkazem PRINT. Pozice řádky pro výstup znaku příkazem PRINT. Jako S-POSN, ale pro dolní část obrazovky. Pozice řádky jako S-POSN, ale pro dolní část obrazovky. Počet řádků+1, po jejichž vypsání se výpis zastaví. Nastavené barvy. Příznak transparentních barev. Dočasně platné barvy. Jako MASK-P, ale dočasné. Další příznaky. Oblast vyhrazená pro kalkulátor. Používá podprogram pro obsluhu NMI. Adresa posledního bajtu, který používá BASIC. Adresa posledního bajtu fyzické paměti.
Komentovaný výpis paměti ROM
223
REJSTŘÍK
ÚVOD . . . . . . . . . . . . . . . . . . . . . . . . . . .
5
PODPROGRAMY 0000 0008 0010 0018 0020 0028 0030 0038 0053 0066 0074 007D
RESTARTŮ A START . . ERROR-1 . PRINT-A-1 SET-CHAR . NEXT-CHAR FP-CALC . BC-SPACES MASK-INT . ERROR-2 . RESET . . CH-ADD+1 . SKIP-OVER
TABULKY . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
7 7 7 7 7 7 7 8 8 8 8 9 9
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
12 12 13 14 14 15
PODPROGRAMY PRO OVLÁDÁNÍ REPRODUKTORU . . . . . . . . . . 03B5 BEEPER . . . . . . . . . . . . . . . . . . . . 03FB BEEP . . . . . . . . . . . . . . . . . . . . .
18 18 19
PODPROGRAMY 04C2 053F 0556 05E3 0605 07CB 0802 0808 08B6 092C 0970
SAVE - LOAD SA-BYTES . . SA/LD-RET . LD-BYTES . . LD-EDGE-2 . SAVE-ETC . . VR-CONTRL . LD-BLOCK . . LD-CONTRL . ME-CONTRL . ME-ENTER . . SA-CONTRL .
PODPROGRAMY 09F4 0A23 0A3D 0A4F 0A5F 0A69 0A6D 0AD9 0ADC OB03 0B24 0B7F 0BDB 0C0A
OBSLUHUJÍCÍ TISK PRINT-OUT . . . PO-BACK-1 . . . PO-RIGHT . . . . PO-ENTER . . . . PO-COMMA . . . . PO-QUEST . . . . PO-TV-2 . . . . PO-ABLE . . . . PO-STORE . . . . PO-FETCH . . . . PO-ANY . . . . . PR-ALL . . . . . PO-ATTR . . . . PO-MSG . . . . .
KLÁVESNICOVÉ PODPROGRAMY 028E KEY-SCAN . . 02BF KEYBOARD . . 0310 K-REPEAT . . 031E K-TEST . . . 0333 K-DECODE . .
224
. . . . . .
. . . . . . . . . . .
. . . . . .
. . . . . .
VERIFY . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
22 22 24 24 26 27 32 33 33 35 37 38
NA OBRAZOVKU A TISKÁRNU . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
40 40 40 41 41 41 41 41 43 43 43 43 44 46 46 Komentovaný výpis paměti ROM
0C3B 0C41 0C55 0D4D 0D6B 0DAF 0DD9 0DFE 0E44 0E88 0E9B 0EAC 0ECD 0EDF 0EF4
PO-SAVE . PO-SEARCH PO-SCR . . TEMPS . . CLS . . . CL-ALL . . CL-SET . . CL-SC-ALL CL-LINE . CL-ATTR . CL-ADDR . COPY . . . COPY-BUFF CLEAR-PRB COPY-LINE
. . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
47 47 48 50 51 52 52 53 54 55 55 56 56 57 57
EDITORU . EDITOR . . ADD-CHAR . ED-EDIT . ED-DOWN . ED-LEFT . ED-RIGHT . ED-DELETE ED-IGNORE ED-ENTER . ED-EDGE . ED-UP . . ED-SYMBOL ED-ERROR . CLEAR-SP . KEY-INPUT ED-COPY . SET-HL . . REMOVE-FP
. . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . .
59 59 60 60 61 61 61 62 62 62 62 63 63 63 64 64 65 67 67
PROVÁDĚCÍ PODPROGRAMY 11B7 NEW . . . 12A2 MAIN-EXEC 155D MAIN-ADD . 15D4 WAIT-KEY . 15E6 INPUT-AD . 15EF OUT-CODE . 1601 CHAN-OPEN 1615 CHAN-FLAG 1634 CHAN-K . . 1642 CHAN-S . . 164D CHAN-P . . 1652 ONE-SPACE 1664 POINTERS . 168F LINE-ZERO 169E RESERVE . 16B0 SET-MIN . 16D4 REC-EDIT . 16DB INDEXER-1 16E5 CLOSE . . 1701 CLOSE-2 . 171C CLOSE-STR
. . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . .
68 68 70 73 74 75 75 75 76 76 76 76 77 77 78 78 79 79 79 79 80 80
PODPROGRAMY 0F2C 0F81 0FA9 0FF3 1007 100C 1015 101E 1024 1031 1059 1076 107F 1097 10A8 111D 1190 11A7
Komentovaný výpis paměti ROM
225
171E 1736 175D 1781 1785 1789 1793 1795 17F5 17F9 1855 18B6 18C1 18E1 190F 1925 196E 1980 198B 19B9 19DD 19E5 19FB 1A1B
STR-DATA . OPEN . . . OPEN-2 . . OPEN-K . . OPEN-S . . OPEN-P . . CAT-ETC . AUTO-LIST LLIST . . LIST . . . OUT-LINE . NUMBER . . OUT-FLASH OUT-CURS . LN-FETCH . OUT-SP-2 . LINE-ADDR CP-LINES . EACH-STMT NEXT-ONE . DIFFER . . RECLAIM-1 E-LINE-NO OUT-NUM-1
. . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . .
80 81 81 82 82 82 83 83 84 84 85 86 86 86 87 87 88 89 89 90 90 90 91 91
INTERPRETACE PŘÍKAZŮ V 1B17 LINE-SCAN 1B28 STMT-LOOP 1B6F SEPARATOR 1B76 STMT-RET . 1B8A LINE-RUN . 1B9E LINE-NEW . 1BB2 REM . . . 1BB3 LINE-END . 1BBF LINE-USE . 1BD1 NEXT-LINE 1BEE CHECK-END 1BF4 STMT-NEXT 1C0D CLASS-03 . 1C10 CLASS-00 . 1C16 JUMP-C-R . 1C1F CLASS-01 . 1C22 VAR-A-1 . 1C56 VAL-FET-1 1C6C CLASS-04 . 1C79 NEXT-2NUM 1C96 PERMS . . 1CBE CLASS-09 . 1CDB CLASS-0B . 1CDE FETCH-NUM
BASICOVÉM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
ŘÁDKU . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . .
93 96 96 97 97 97 98 98 98 98 99 99 99 100 100 100 100 100 101 101 102 102 103 103 103
PŘÍKAZOVÉ PODPROGRAMY 1CEE STOP . . . 1CF0 IF . . . . 1D03 FOR . . . 1D86 LOOK-PROG 1DAB NEXT . . . 1DDA NEXT-LOOP
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
104 104 104 104 106 107 108
226
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
Komentovaný výpis paměti ROM
1DED 1E27 1E39 1E42 1E4F 1E5F 1E67 1E7A 1E80 1E85 1E94 1EA1 1EAC 1EED 1F05 1F1A 1F23 1F3A 1F54 1F60 1FC3 1FC9 1FCD 1FF5 1FFC 2045 204E 2070 2089 21B9 21D0 21D6 21E1 226C 2294 22AA 22CB 22DC 2307 2314 2320 2382 247D 24B7
READ . . . DATA . . . PASS-BY . RESTORE . RANDOMIZE CONTINUE . GO-TO . . OUT . . . POKE . . . TWO-PARAM FIND-INT1 RUN . . . CLEAR . . GO-SUB . . TEST-ROOM FREE-MEM . RETURN . . PAUSE . . BREAK-KEY DEF-FN . . UNSTACK-Z LPRINT . . PRINT . . PRINT-CR . PR-ITEM-1 PR-END-Z . PR-POSN-1 STR-ALTER INPUT . . IN-ASSIGN IN-STOP . IN-CHAN-K CO-TEMP-1 CO-CHANGE BORDER . . PIXEL-ADD POINT-SUB PLOT . . . STK-TO-BC STK-TO-A . CIRCLE . . DRAW . . . CD-PRMS1 . DRAW-LINE
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
108 109 109 109 109 110 110 110 110 110 111 111 111 112 112 112 113 113 113 114 115 115 115 115 116 117 117 117 117 120 120 120 121 123 123 124 124 125 125 125 126 128 132 133
HODNOCENÍ VÝRAZŮ . . . 24FB SCANNING . 2530 SYNTAX-Z . 25AF S-U-PLUS . 25B3 S-QUOTE . 25E8 S-BRACKET 25F8 S-RND . . 2627 S-PI . . . 2634 S-INKEY$ . 2668 S-SCREEN$ 2672 S-ATTR . . 267B S-POINT . 26C9 S-LETTER .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
135 135 136 138 138 138 139 139 139 140 140 140 141
Komentovaný výpis paměti ROM
227
27BD 28AB 28B2 2951 2996 2A52 2AB6 2ACC 2AEE 2AF4 2AFF 2BA6 2BAF 2BC6 2BEA 2BF1 2C02 2C88 2C8D 2C9B 2D1B 2D22 2D28 2D2B 2D3B
. . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . .
145 147 148 151 152 155 156 156 157 157 158 161 161 162 162 162 163 165 165 165 167 167 167 167 168
PODRPOGRAMY E-TO-FP . . INT-FETCH . P-INT-STO . FP-TO-BC . . LOG(2^A) . . FP-TO-A . . PRINT-FP . . CA=10*A+C . PREP-ADD . . FETCH-TWO . SHIFT-FP . . ADD-BACK . . SUBTRACT . . ADDITION . . HL=HL*DE . . PREP-M/D . . MULTIPLY . . DIVISION . . TRUNCATE . . RE-ST-TWO . RE-STACK . .
. . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . .
169 169 170 170 171 171 172 172 178 178 179 180 180 181 181 183 184 184 188 189 191 191
FLOATING POINT KALKULÁTOR 335B CALCULATE . . 33A2 FP-CALC-2 . . 33A9 TEST-5-SP . . 33C0 MOVE-FP . . . 33C6 STK-DATA . . . 33F7 SKIP-CONS . . 3406 LOC-MEM . . . 340F GET-MEM-0 . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
193 194 196 196 196 197 197 198 198
ARITMETICKÉ 2D4F 2D7F 2D8C 2DA2 2DC1 2DD5 2DE3 2F8B 2F9B 2FBA 2FDD 3004 300F 3014 30A9 30C0 30CA 31AF 3214 3293 3297
228
S-FN-SBRN FN-SKPOVR LOOK-VARS STK-F-ARG STK-VAR . SLICING . STK-STORE INT-EXP1 . DE,(DE+1) GET-HL*DE LET . . . L-ENTER . L-ADD$ . . L-STRING . L-FIRST . STK-FETCH DIM . . . ALPHANUM . ALPHA . . DEC-TO-FP NUMERIC . STK-DIGIT STACK-A . STACK-BC . INT-TO-FP
Komentovaný výpis paměti ROM
341B 342D 343C 3449 346A 346E 3492 34A5 34AC 34B3 34BC 34E9 34F9 3501 3506 350B 351B 3524 352D 353B 359C 35BF 35C9 35DE 361F 3645 3669 3674 367A 3686 368F 369B 36A0 36AF 36C4 3713 3783 37AA 37B5 37DA 37E2 3833 3843 384A 3851
STK-ZERO . ST-MEM-0 . EXCHANGE . SERIES-06 ABS . . . NEGATE . . SGN . . . IN . . . . PEEK . . . USR-NO . . USR-$ . . TEST-ZERO GREATER-0 NOT . . . LESS-0 . . FP-0/1 . . OR . . . . NO-&-NO . STR-&-NO . NO-L-EQL . STRS-ADD . STK-PNTRS CHRS . . . VAL . . . STR$ . . . READ-IN . CODE . . . LEN . . . DEC-JR-NZ JUMP . . . JUMP-TRUE END-CALC . N-MOD-M . INT . . . EXP . . . LN . . . . GET-ARGT . COS . . . SIN . . . TAN . . . ATN . . . ASN . . . ACS . . . SQR . . . TO-POWER .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
198 199 199 200 201 201 202 202 202 202 203 203 204 204 204 204 205 205 205 205 207 207 207 208 209 209 209 210 210 210 210 211 211 211 212 213 215 216 217 217 218 219 220 220 220
Přehled systémových proměnných . . . . . . . . . . . . . .
222
REJSTŘÍK . . . . . . . . . . . . . . . . . . . . . . . . .
224
Komentovaný výpis paměti ROM
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
229
Elektronická verzia: .1.20 Peter Turányi alias Softhouse http://softhouse.speccy.cz Ďakujem Lukášovi Macurovi za pomoc s OCR a korektúrami Zdeňkovi Starému za skeny