MONITOR ROM - ZX Spectrum - 1 - Predmluva ========= Sinclair ZX Spectrum je nasledovnikem pocitace ZX-81,ktery zase nahradil pocitac ZX-80. Spectrum ma 16K monitorovy program. Tento byl vytvoren primo s vyuzitim 4K programu z pocitace ZX-81,ale je zde tolik novych rysu, ze rozdily prevazuji nad podobnostmi. Psani teto knizky nas oba velmi zajimalo a bavilo. Naucili jsme se hodne o technikach programovani ve strojovem kodu procesoru Z80 a jaksi pocitujeme, ze se nam podarilo odhalit tajemstvi Spectra. Radi bychom podekovali: Nasim rodinam, Alfredu Milgromovi,nasemu vydavateli,ktery nam velmi pomohl. Filipu Mitchellovi,jehoz poznamky byly velice informativni, Clive Sinclairovi a jeho teamu Sinclair Research Ltd.,ktery dokazal vyrobit takovouto vyzyvajici a uzitecnou masinku. Napsano v lednu 1983 . Yan Logan,Lincoln,Spojene kralovstvi, Frank O'Hara,Londyn,Spojene kralovstvi. U V O D ******* 16K monitorovy program Spectra je slozity program ve strojovem kodu procesoru Z80. Jeho struktura je velmi zretelna a to proto,ze je rozdelena do tri hlavnich casti: a) Vstupni a vystupni rutiny b) Basicky interpreter (prekladac) c) Manipulace s vyrazy Tyto bloky jsou ale jeste prilis velke na to,aby je bylo mozno snadno pochopit v celku a proto je monitorovy program v teto knize rozdelen do deseti casti: RESTARTOVACI RUTINY A TABULKY Na zacatku monitoroveho programu jsou ruzne restartovaci programy,ktere jsou volany jednobajtovymi instrukcemi RST. Tyto restarty jsou vyuzity vsechny. Napr. RST #08 je vyuzivan pro hlaseni ruznych sdeleni nebo chyb. Tabulky v te- to casti monitoroveho programu obsahuji nezkracene tvary klicovych slov a kody tlacitek. KLAVESNICOVA RUTINA Klavesnice je testovana kazdou 1/50 sec a po testu je na prislusnou systemovou promennou ulozen kod stlacene klavesy.Vsechna tlacitka na klavesnici "opakuji" jestlize jsou stlacena delsi dobu. O to se stara take tato rutina. REPRODUKTOROVA RUTINA Spectrum ma vestaveny reproduktor a tony vznikaji opakovanym pouzitim instruk- ce OUT. V ridici rutine byla venovana velka pozornost tomu,aby bylo zajisteno, ze zadany ton bude mit prislusnou vysku a delku trvani. RUTINY OBSLUHUJICI KAZETOVY MAGNETOFON Jednou ze slabych stranek pocitace ZX-81 bylo to,ze jen velmi mala cast jeho monitoroveho programu byla urcena k obsluze kazetoveho magnetofonu. Ale ve Spectru je to uz rozsahly blok strojoveho kodu a da se rici,ze jednim z nejuspesnejsich rysu Spectra je prave vysoky standart nahravacich rutin. Basicke programy nebo bloky dat jsou ukladany pomoci hlavickoveho bloku,ktery ma 17 bajtu a je ukladan prvni. Hlavicka popisuje charakter dat ukladanych v nasledujicim bloku.Jedinou "nevyhodou" tohoto systemu je to,ze neni mozno zabezpecit utajeni bloku dat. RUTINY OBSLUHUJICI SCREEN A PRINTER Vsechny ostatni vstupni a vystupni rutiny jsou "vektorovany" pomoci kanalovych a streamovych (proudovych) adres. Ve standartnim Spectru je vstup mozny pouze z klavesnice,ale vystup muze byt smerovan na tiskarnu a horni nebo dolni cast televizniho displeje. Hlavni "vstupni" rutina v teto casti monitoroveho pro- gramu je EDITOR,ktery umoznuje uzivateli vkladat znaky do dolni casti tele- vizniho displeje. Rutina PRINT OUT je dosti pomala,protoze je spolecna pro vsechny druhy tisku.Napriklad pridani jednoho bajtu na displej v sobe zahrnuje tez soucasne posouzeni stavu funkci OVER a INVERSE pri kazdem pouziti teto rutiny. PROVADECI RUTINY V teto casti monitoroveho programu muzeme najit iniciacni rutinu a hlavni provadeci smycku basickeho prekladace. Ve Spectru je kontrolovana syntaxe basickeho radku,ktery je posleze ulozen do programove oblasti,jestlize mel cislo,jinak je okamzite vykonan,coz muze ve svem dusledku vest k ruznym situacim. ( Zretelne je to videt v pripade operace RUN ). MONITOR ROM - ZX Spectrum - 3 - RUTINY RESTARTU A TABULKY ************************* START - Uplny start systemu --------------------------- Maskovane preruseni je znemozneno a registrovy par DE je nastaven tak,aby obsahoval nejvyssi moznou adresu pameti RAM. 0000 DI ;Zakaz preruseni (i testu klavesnice) XOR A ;#00 pro start (ale #FF pro NEW) LD DE,#FFFF ;Nejvyssi adresa RAM JP #11CB ;Skok dopredu na START/NEW ERROR-1 - Rutina obslouzeni chybovych hlaseni --------------------------------------------- Chybovy ukazatel je nastaven tak,aby ukazoval na pozici chyby. 0008 LD HL,(#5C5D) ;Adresa dosazena prekladacem je okopirovana LD (#5C5F),HL ;do chyboveho ukazatele,drive nez se bude JR #0053 ;pokracovat PRINT-A-1 - Rutina pro tisk znaku --------------------------------- Registr A obsahuje kod znaku,ktery ma byt vytisten. 0010 JP #15F2 ;Okamzity skok dopredu DEFB #FF,#FF,#FF ;Nevyuzita mista DEFB #FF,#FF GET-CHAR - Rutina pro nacteni znaku ----------------------------------- Obsah mista adresovaneho systemovou promennou CH-ADD je precten.Navrat, jestlize se jedna o znak pouzitelny k tisku,jinak je CH-ADD inkrementovana a testy se opakuji. 0018 LD HL,(#5C5D) ;Vyzvedni hodnotu adresovanou LD A,(HL) ;systemovou promennou CH-ADD 001C CALL #007D ;Zjisti,jestli se jedna o znak pouzitelny RET NC ;k tisku a vrat se je-li to pravda NEXT-CHAR - Rutina pro nacteni dalsiho znaku -------------------------------------------- Pri interpretaci basickeho radku je tato rutina opakovane vyvolavana, coz zpusobuje postupovani po radku. 0020 CALL #0074 ;Je nutno inkrementovat CH-ADD JR #001C ;Skok zpet a test nove hodnoty DEFB #FF,#FF,#FF ;Nevyuzita mista FP-CALC - Rutina kalkulator --------------------------- Kalkulator pracujici s pohublivou radovou carkou zacina na adrese #335B 0028 JP #335B ;Okamzite skoc dopredu na CALCULATE DEFB #FF,#FF,#FF ;Nevyuzita mista DEFB #FF,#FF BC-SPACES - Rutina pro vytvoreni BC prostoru -------------------------------------------- Tato rutina vytvari volna mista v pracovnim prostoru.Pocet vytvarenych mist je dan hodnotou ulozenou v regegistru BC. 0030 PUSH BC ;Uschovej citac LD HL,(#5C61) ;Vyzvedni soucasnou adresu pracovniho PUSH HL ;prostoru a uschovej ji pred vstupem JP #169E ;do pracovni rutiny MASK-INT - Rutina maskovaneho preruseni --------------------------------------- Hodiny realneho casu ve SPECTRU jsou inkrementovany a soucasne je testovana klavesnice kdykoliv dojde k maskovanemu preruseni. 0038 PUSH AF ;Uschovej registry PUSH HL LD HL,(#5C78) ;Dolni dva bajty systemove promenne jsou INC HL ;inkrementovany kazdych 20 ms.(Evropska norma) LD (#5C78),HL LD A,H ;Nejvyssi bajt teto promenne je inkrementovan OR L ;pouze tehdy,je-li hodnota nizsich dvou bajtu JR NZ,#0048 ;nulova INC (IY+64) ;(FRAMES-3) MONITOR ROM - ZX Spectrum - 5 - TABULKA TOKENS -------------- Vsechny TOKENS,ktere SPECTRUM pouziva jsou expandovany odkazy na tuto tabulku.Posledni bajt kazdeho token je "invertovan" nastavenim bitu 7. 0095 BF 52 4E C4 49 4E 4B 45 ? R N D I N K E 009D 59 A4 50 C9 46 CE 50 4F Y $ P I F N P O 00A5 49 4E D4 53 43 52 45 45 I N T S C R E E 00AD 4E A4 41 54 54 D2 41 D4 N $ A T T R A T 00B5 54 41 C2 56 41 4C A4 43 T A B V A L $ C 00BD 4F 44 C5 56 41 CC 4C 45 O D E V A L L E 00C5 CE 53 49 CE 43 4F D3 54 N S I N C O S T 00CD 41 CE 41 53 CE 41 43 D3 A N A S N A C S 00D5 41 54 CE 4C CE 45 58 D0 A T N L N E X P 00DD 49 4E D4 53 51 D2 53 47 I N T S Q R S G 00E5 CE 41 42 D3 50 45 45 CB N A B S P E E K 00ED 49 CE 55 53 D2 53 54 52 I N U S R S T R 00F5 A4 43 48 52 A4 4E 4F D4 $ C H R $ N O T 00FD 42 49 CE 4F D2 41 4E C4 B I N O R A N D 0105 3C BD 3E BD 3C BE 4C 49 < = > = < > L I 010D 4E C5 54 48 45 CE 54 CF N E T H E N T O 0115 53 54 45 D0 44 45 46 20 S T E P D E F 011D 46 CE 43 41 D4 46 4F 52 F N A C T F O R 0125 4D 41 D4 4D 4F 56 C5 45 M A T M O V E E 012D 52 41 53 C5 4F 50 45 4E R A S E O P E N 0135 20 A3 43 4C 4F 53 45 20 # C L O S E 013D A3 4D 45 52 47 C5 56 45 # M E R G E V E 0145 52 49 46 D9 42 45 45 D0 R I F Y B E E P 014D 43 49 52 43 4C C5 49 4E C I R C L E I N 0155 CB 50 41 50 45 D2 46 4C K P A P E R F L 015D 41 53 C8 42 52 49 47 48 A S H B R I G H 0165 D4 49 4E 56 45 52 53 C5 T I N V E R S E 016D 4F 56 45 D2 4F 55 D4 4C O V E R O U T L 0175 50 52 49 4E D4 4C 4C 49 P R I N T L L I 017D 53 D4 53 54 4F D0 52 45 S T S T O P R E 0185 41 C4 44 41 54 C1 52 45 A D D A T A R E 018D 53 54 4F 52 C5 4F 45 D7 S T O R E N E W 0195 42 4F 52 44 45 D2 43 4F B O R D E R C O 019D 4E 54 49 4E 55 C5 44 49 N T I N U E D I 01A5 CD 52 45 CD 46 4F D2 47 M R E M F O R G 01AD 4F 20 54 CF 47 4F 20 53 O T O G O S 01B5 55 C2 49 4E 50 55 D4 4C U B I N P U T L 01BD 4F 41 C4 4C 49 53 D4 4C O A D L I S T L 01C5 45 D4 50 41 55 53 C5 4E E T P A U S E N 01CD 45 58 D4 50 4F 4B C5 50 E X T P O K E P 01D5 52 49 4E D4 50 4C 4F D4 R I N T P L O T 01DD 52 55 CE 53 41 56 C5 52 R U N S A V E R 01E5 41 4E 44 4F 4D 49 5A C5 A N D O M I Z E 01ED 49 C6 43 4C D3 44 52 41 I F C L S D R A 01F5 D7 43 4C 45 41 D2 52 45 W C L E A R R E 01FD 54 55 52 CE 43 4F 50 D9 T U R N C O P Y MONITOR ROM - ZX Spectrum - 7 - KLAVESNICOVE RUTINY ******************* KEY-SCAN - Rutina vyhodnoceni klavesnice ---------------------------------------- Tato velmi dulezita rutina je vyvolavana z hlavni klavesnicove rutiny a z ru- tiny INKEY$ (pri SCANNINGu).Ve vsech pripadech obsahuje registr E hodnotu v rozsahu #00 - #27 byla-li stlacena nektera z klaves,nebo hodnotu #FF, nebyla-li stlacena zadna klavesa.Registr D obsahuje hodnotu,ktera indikuje stisteni SHIFTovacich klaves.Jestlize byly stisteny obe SHIFTovaci klavesy, obsahuji registry D a E hodnoty pro CAPS SHIFT a SYMBOL SHIFT.Jestlize nebyla stistena zadna klavesa obsahuje registrovy par DE hodnotu #FFFF.Nulovy indi- kator se vraci vynulovan,kdyz doslo ke stisteni dvou klaves a ani jedna z nich nebyla klavesa SHIFT. 028E LD L,#2F ;Pocatecni hodnota bude pro kazdy radek: ;#2F,#2E...,#28 (8 radku) LD DE,#FFFF ;Nastav registrovy par DE na signal ;"zadna klavesa" LD BC,#FEFE ;Registr C obsahuje adresu portu, ;registr B je citac Nyni se vstoupi do smycky,ktera bude vykonana osmkrat a pri kazdem pruchodu se bude zacinat s novou pocatecni hodnotou v registru L jak bylo uvedeno vyse. 0296 IN A,(C) ;Je precten specifikovany port.Stistena klavesa CPL ;v teto radce nastavi prislusny bit (bity 0 az 4) AND #1F ;Nebyla-li stistena zadna klavesa provede se JR Z,#02AB ;odskok,jinak jsou klavesove bity ulozeny LD H,A ;do registru H a kod "prvni" klavesy v tomto LD A,L ;radku je ulozen do registru A.Jestlize 029F INC D ;byly stisteny 3 klavesy,nemuze registr D RET NZ ;obsahovat hodnotu #FF a provede se navrat 02A1 SUB #08 ;V teto smycce je opakovane odecitana hodnota SRL H ;#08,dokud neni nalezen klavesovy bit JR NC,#02A1 ;Okopiruj predchozi klavesovou hodnotu LD D,E ;do registru D a uloz novou klavesovou hodnotu LD E,A ;do registru E a skoc zpet,jsou-li jeste dalsi JR NZ,#029F ;stisknute klavesy v tomto radku.Radka byla 02AB DEC L ;prozkoumana,takze pocatecni hodnota muze byt RLC B ;snizena.Citac je posunut doleva a provede se JR C,#0296 ;odskok,jestlize se nejednalo o posledni radek ;Nyni se provedou ctyri testy: LD A,D ;Pokud registr D obsahuje hodnotu #FF,je za- INC A ;roven s touto hodnotou prijata i jakakoliv RET Z ;hodnota v registru E a je-li v registru D CP #28 ;hodnota #28 (CAPS SHIFT),je opet prijata i RET Z ;jakakoliv hodnota v registru E a je-li v re- CP #19 ;gistru D hodnota #19 (SYMBOL SHIFT) je take RET Z ;prijata i jakakoliv hodnota v registru E LD A,E ;Je ovsem mozne,ze v registru E je hodnota LD E,D ;pro SYMBOL SHIFT a toto musi byt zvazeno LD D,A CP #18 ;Z=0,jestlize se nejednalo o SYMBOL SHIFT RET ;a nejakou klavesu KEYBOARD - Rutina klavesnice ---------------------------- Tato rutina je volana pri kazdem maskovanem preruseni,coz se deje 50krat za sekundu,je-li procesor v modu IM1.Ukolem tohoto podprogramu je otestovat klavesnici a dekodovat hodnoty stistenych klaves.Vysledny kod stistene klavesy je predan do systemove promenne LAST-K,pokud to umozni "opakovaci statut". Po ulozeni ziskaneho kodu do LAST-K je nastaven bit 5 v systemove promenne FLAGS jako signal,ze byla stlacena klavesa.Je vyuzivan zdvojeny system systemovych promennych KSTATE (KSTATE0-KSTATE3 [1.set] a KSTATE4-KSTATE7 [2.set]),ktery umoznuje detekci stisteni dalsi klavesy i kdyz program jeste pokracuje v opakovaci periode predchozi klavesy.System prijme novou klavesu, byla-li stistena alespon 1/10 sec.,coz odpovida peti volanim rutiny klavesnice. 02BF CALL #028E ;Kod klavesy je ulozen do registru DE RET NZ ;Bylo-li stlaceno vice klaves (mimo SHIFTU) LD HL,#5C00 ;provede se navrat.Zacne se s KSTATE0 02C6 BIT 7,(HL) ;Je-li system volny (tj.KSTATE0/4 obsahuji JR NZ,#02D1 ;hodnoty #FF),provede se odskok dopredu INC HL ;HL ukazuje na citac peti volani,ktery je na- DEC (HL) ;sle dovne dekrementovan a provede se odskok, DEC HL ;nebyl-li 1.set volny JR NZ,#02D1 LD (HL),#FF ;Signal: 1.set volny MONITOR ROM - ZX Spectrum - 9 - K-DECODE - Rutina dekodovani klavesnice --------------------------------------- Do tohoto podprogramu se vstupuje s "hlavnim kodem" v registru E,s hodnotou systemove promenne FLAGS v registru D,hodnotou MODE v registru C a se SHIFT bajtem v registru B. Posouzenim techto ctyr hodnot s pomoci sesti klavesovych tabulek je ziskan "finalni kod",ktery je na vystupu ulozen v registru A. 0333 LD A,E ;Okopiruj "hlavni kod".Pokud se jedna CP #3A ;o posouzeni cislicovych klaves,ENTERu,SPACE JR C,#0367 ;a obou SHIFTu,provede se skok DEC C ;Dekrementuj hodnotu MODE a skoc dopredu, JP M,#034F ;vyzaduji-li to mody K,L,C nebo mod E JR Z,#0341 ;Pouze graficky mod je ponechan a "finalni kod" ADD A,#4F ;je vypocitan primo z "hlavniho kodu".Pricti RET ;doplnek a vrat se s "finalnim kodem" 0341 LD HL,#01EB ;Jsou posouzeny znaky v EXTENDED MODE.Bazova INC B ;adresa tabulky "b".Nebyla-li stisknuta zadna JR Z,#034A ;ze SHIFTovych klaves,uzij tabulku "b", LD HL,#0205 ;jinak pouzij bazovou tabulku "c" 034A LD D,#00 ;Obslouzeni tabulek "b-f".Ve vsech pripadech ADD HL,DE ;je nalezen a predan "finalni kod".Vynuluj LD A,(HL) ;registr D,najdi v tabulce "finalni kod" RET ;a vrat se 034F LD HL,#0229 ;Zde jsou posuzovany znaky v modech K,L a C BIT 0,B ;Ale nejprve se musi pracovat s kody JR Z,#034A ;pro SYMBOL SHIFT.Bazova adresa tabulky "e" BIT 3,D ;Jedna-li se o SYMBOL SHIFT+pismeno,skoc zpet JR Z,#0364 ;Nachazis-li se v modu K,skoc dopredu BIT 3,(IY+48) ;(FLAGS2) Byl-li nastaven CAPS LOCK,vrat se RET NZ ;s "finalnim kodem" INC B ;Byl-li stisten CAPS SHIFT,vrat se s tim RET NZ ;samym ADD A,#20 ;Jedna-li se o male pismeno,je treba pricist RET ;#20 k hlavnimu CODE a provest navrat 0364 ADD A,#A5 ;Ciselne hodnoty pro "TOKENS" jsou ziskany RET ;prictenim hodnoty #A5 k "hlavnimu kodu" 0367 CP #30 ;Nyni jsou posuzovany ciselne klavesy,SPACE, RET C ;ENTER a oba SHIFTy.Pokracuj pouze tehdy, DEC C ;jedna-li se o cislo,tzn. vrat se pri SPACE JP M,#039D ;(#20),ENTER (#0D) nebo obou SHIFTech (#0E) JR NZ,#0389 ;Nyni rozdel ciselne klavesy do tri skupin LD HL,#0254 ;a to podle modu K,L,C a modu G.Pokracuj BIT 5,B ;v modu E.Bazova adresa tabulky "f".Pouzij tu- JR Z,#034A ;to tabulku pro SYMBOL SHIFT a ciselne klavesy CP #38 ;v EXTENDED MODU.Jedna-li se o klavesy 8 a 9 JR NC,#0382 ;skoc dopredu.Ciselne klavesy 0 az 7 maji dat SUB #20 ;bud kod papiru nebo inkoustu,kdyz je stlacen INC B ;CAPS SHIFT.Rozsah #30 az #37 je snizen na #10 RET Z ;az #17 a jestlize nebyl uzit CAPS LOCK,navrat ADD A,#08 ;s hodnotou tohoto papiru,ale kdyby byl rozsah RET ;#18 az #1E,znamena to,ze jde o barvu inkoustu 0382 SUB #36 ;Klavesy 8 a 9 musi davat BRIGHT a FLASH.Hod- INC B ;noty #38 a #39 davaji 02 a 03.Nebyl-li pouzit RET Z ;CAPS SHIFT,provede se navrat (jedna se o kod ADD A,#FE ;BRIGHT).Odecti 2 ( vzniknou hodnoty 0 a 1 - RET ;- FLASH) a navrat s temito kody 0389 LD HL,#0230 ;Ciselne klavesy v grafickem modu maji dat CP #39 ;skupinu grafickych znaku (#80 az #8F),graficky JR Z,#034A ;kod (#0F) a kod pro DELETE (#0C).Bazova adresa CP #30 ;tabulky "d".Pouzij tuto tabulku primo jak pro JR Z,#034A ;klavesu 9,ktera provede GRAPHCS,tak pro klave- AND #07 ;su 0,ktera provede DELETE.Pro klavesy 1 az 8 ADD A,#80 ;uprav rozsah na hodnoty #80 az #87 a pokud ne- INC B ;byla stlacena ani jedna ze SHIFTovych klaves, RET Z ;proved navrat XOR #0F ;Byl-li stlacen nektery SHIFT,uprav rozsah RET ;na hodnoty #88 az #8F a vrat se 039D INC B ;Nakonec se posuzuji cislicove klavesy v mo- RET Z ;dech K,L & C.Pokud nebyl stisten zadny SHIFT, BIT 5,B ;vrat se primo s "finalni kody" #30 az #39 LD HL,#0230 ;Je-li stisknuta klavesa CAPS SHIFT,pouzij JR NZ,#034A ;tabulku "d".Nyni mohou byt nalezeny kody pro SUB #10 ;ruzne cislicove klavesy pri pouziti SYMBOL CP #22 ;SHIFTu.Sniz rozsah na #20 az #29 a oddel za- JR Z,#03B2 ;vinac (@) od ostatnich CP #20 ;Znak "_" musi byt take oddelen a proto se RET NZ ;vrat s "finalnimi kody" #21,#23 az #29 LD A,#5F ;Uloz do registru A kod znaku "_" a vrat se RET 03B2 LD A,#40 ;Uloz do registru A kod znaku "@" a vrat se RET MONITOR ROM - ZX Spectrum - 11 - Rutina prikazu BEEP ------------------- Pred vstupem do tohoto podprogramu musi byt na vrcholu zasobniku ulozena vyska tonu P a pod ni delka trvani t. 03F8 RST #28 ;Volani rutiny FP-CALC DEFB #31 ;zdvojeni t,P,P DEFB #27 ;INT t,P,i (i = INT P) DEFB #C0 ;ST-MEM-0 t,P,i (i uloz do MEM-0) DEFB #03 ;rozdil t,p (p je zlomkova cast P) DEFB #34 ;STK-DATA konstanata k na zasobnik DEFB #EC ;exponent #7C (k=0.0577622606) DEFB #6C,#98,#1F,#F5 DEFB #04 ;nasobeni t,pK DEFB #A1 ;STK-jedna t,pK,1 DEFB #0F ;soucet t,pK+1 DEFB #38 ;konec vypoctu Ted se provede rada testu i - (celociselna hodnota vysky tonu). 0407 LD HL,#5C92 ;Toto je MEM-0-1(MEMBOT) LD A,(HL) ;Vyzvedni exponent i a vyvolej chybu,pokud se AND A ;nejedna o "kratkou" formu JR NZ,#046C INC HL ;kopiruj znamenkovy bajt do registru C LD C,(HL) INC HL ;Kopiruj nizsi bajt do registru B a A LD B,(HL) LD A,B RLA SBC A,A CP C JR NZ,#046C ;Vyvolej chybu pokud neplati,ze -128<=i<=+127 INC HL CP (HL) JR NZ,#046C LD A,B ;Dale testuj nizsi bajt ADD A,#3C JP P,#0425 ;Akceptuj jen -60<=i<=+69 JP PO,#046C ;Odmitni hodnoty od -128 do -61 Poznamka: Rozsah +70 az +127 bude zamitnut pozdeji.Nyni muze byt nalezena spravna frekvence pro vysku i. 0425 LD B,#FA ;Zacni "6" oktav pod strednim C 0427 INC B ;Opakovane snizuj i,aby byla nalezena SUB #0C ;spravna oktava JR NC,#0427 ADD A,#0C ;Pricti zpet posledni odecet PUSH BC ;Uschovej cislo oktavy LD HL,#046E ;Bazova adresa tabulky pultonu CALL #3406 ;Prohledej tabulku a nalezenou FP hodnotu CALL #33B4 ;predej na zasobnik kalkulatoru Nyni se vezme v uvahu zlomkova cast vysky. RST #28 ;t,pK+1,C DEFB #04 ;nasobeni t,C*(pK+1) DEFB #38 ;konec vypoctu Konecna frekvence f je nalezena modifikaci posledni hodnoty podle cisla oktavy. POP AF ;Vyzvedni cislo oktavy a vynasob "posledni ADD A,(HL) ;hodnotu"+2^x (x=cislo oktavy) LD (HL),A RST #28 ;t,f DEFB #C0 ;frekvence je provizorne ulozena v MEM-0 DEFB #02 ;vymaz Vypocet trvani tonu DEFB #31 ;zdvojeni t,t DEFB #38 ;konec vypoctu CALL #1E94 ;Hodnota INT t musi byt v rozsahu #00 az #0A CP #0B JR NC,#046C MONITOR ROM - ZX Spectrum - 13 - RUTINY SAVE - LOAD - VERIFY *************************** Vstupni bod pro tyto rutiny je na adrese #0605 - atd. (Nicmene skutecne podprogramy pro SAVE,LOAD nebo VERIFY bloku bajtu zacinaji od #04C2). Ve vsech pripadech obsahuje DE pocet bajtu. V IX je adresa umisteni zacatku bloku dat v pameti.Registr A obsahuje #00 pro hlavicku a #FF pro vlastni blok dat.Rychlost prenosu je 1200 bit/sec. SA-BYTES -------- Je volana pro SAVE hlavicky z #098A a pozdeji pro vlastni blok dat z #099E. 04C2 LD HL,#053F ;Ulozeni adresy SA/LD-RET do zasobniku PUSH HL LD HL,#1F80 ;konstanta 5 sec pro zavadeci signal hlavicky BIT 7,A JR Z,#04D0 ;Skok, kdyz se zaznamena va hlavicka LD HL,#0C98 04D0 EX AF,AF' ;Ulozeni podmink. registru INC DE ;Delka o jednicku zvetsena DEC IX ;Bazova adresa snizena DI ;Zakaz preruseni LD A,#02 ;Maska pro MIC,BORDER cerveny LD B,A ;Prenos hodnoty 2 do B Nyni nasleduje rutina pro tvorbu pulsu zavadeciho signalu.Pulsy MIC - on a MIC - off jsou dlouhe 2.168 T (taktu hodin).Barva BORDERu se meni v temze rytmu z cervene do cyanu (pri vzestupne a sestupne hrane signalu. 04D8 DJNZ #04D8 ;Hlavni casovaci perioda OUT (#FE),A ;MIC on-off,BORDER cerveny-cyan v kazdem XOR #0F ;pruchodu LD B,#A4 ;Hlavni casovaci konstanta DEC L ;Snizeni nizsiho bajtu citace JR NZ,#04D8 ;Skok pro dalsi puls DEC B ;Delsi pruchod,redukce o 13 T stavu DEC H ;Snizeni vyssiho bajtu citace a zpet pro JP P,#04D8 ;dalsi puls dokud neni zavadeci cast kompletni Dale je vyslan synchronizacni puls (sync): LD B,#2F 04EA DJNZ #04EA ;MIC off; 657T od OUT k OUT OUT (#FE),A ;MIC on a cervena LD A,#0D ;Signal MIC off a cyan LD B,#37 ;MIC on; 735T od OUT k OUT 04F2 DJNZ #04F2 OUT (#FE),A ;MIC off a BORDER cyan Bajt indikace bude zaznamenan jako prvni. LD BC,#3B0E ;3B je casovaci konstanta,#0E signalizuje EX AF,AF' ;MIC off a zlutou.Indikacni bajt do registru LD L,A ;A a jeho prevod do L s odeslanim JP #0507 ;Skok do zaznamove smycky Je zaznamenan indikacni bajt,dal uz nasleduji bajty dat.Posledni je paritni bajt,ktery je konstruovan prubezne postupnym porovnavanim hodnot vsech zazna- menavanych bajtu (pro kontrolu spravnosti zaznamu pri verifikaci a nacitani). 04FE LD A,D ;Citac delky dat je testovan a kdyz dosahne 0, OR E JR Z,#050E ;skoci na SA-PARITY LD L,(IX+0) ;Do L dalsi bajt pro zaznam 0505 LD A,H ;H je momentalne paritni bajt XOR L ;Porovnavani s novym bajtem zaznamu 0507 LD H,A ;Novy paritni bajt do H (pri 1.vstupu ;indikacni bajt inicial. parity bajt) LD A,#01 ;Signal MIC on a modra. CY jako SCF ;navesti pro 8 bitu zaznamenavaneho bajtu JP #0525 ;Skok do tvorby bajtu a jeho zaznam na pasek 050E LD L,H ;Pred poslanim paritniho bajtu k nahrani,je JR #0505 ;bajt preveden do L.Konecna podoba paritniho ;bajtu.Skok zpet Nasledujici rutina tvaruje jednotlive bity nahravaneho bajtu tak,ze kazdy obsahuje on i off puls,pricemz pulsy pro bity log.1 jsou presne dvakrat delsi nez pulsy bitu log. 0 (o 855 T). 0511 LD A,C ;Druhy pruchod; MIC off a zluta BIT 7,B ;Indikator nuly je 1 (pri 2.pruchodu ) 0514 DJNZ #0514 ;Hlavni casovaci smycka,801 T pri 2.pruchodu JR NC,#051C ;Skok na kratsi pruchod pri tvorbe log.0 LD B,#42 ;Pri log.1 o 855 T vic MONITOR ROM - ZX Spectrum - 15 - JR NZ,#0574 ;Cekaci smycka.Pokracuje pri zachyceni dvou CALL #05E3 ;po sobe jdoucich hran v dane periode JR NC,#056B ;Nyni bude prijat jen zavadeci signal 0580 LD B,#9C ;Casovaci konstanta CALL #05E3 ;Pokracuje pri zachyceni dvou po sobe jdoucich JR NC,#056B ;hran v dane periode.Tyto hrany musi byt LD A,#C6 ;zachyceny behem 3600 T CP B JR NC,#056C INC H ;Pocet paru hran je ukladan do registru H, JR NZ,#0580 ;dokud jich neni 256.Po zavadecim signalu pri- 058F LD B,#C9 ;chazeji casti on a off pulsu sync.Casovaci CALL #05E7 ;konstanta.Kazda hrana je testovana dokud JR NC,#056B ;nejsou nalezeny dve hrany blizko sebe LD A,B ;(startovaci puls sync.) CP #D4 JR NC,#058F ;Na konci musi byt jeste konecna hrana casti CALL #05E7 ;on synchronizacniho pulsu RET NC ;Ted uz se mohou nacitat bajty hlavicky nebo LD A,C ;programu (bloku dat) v operacich LOAD,VERIFY XOR #03 ;Prvni bajt je typovy.BORDER na modrou a zlutou LD C,A LD H,#00 ;Inicializace bajtu parity na 0 LD B,#B0 ;Casovaci konstanta pro typovy bajt JR #05C8 ;Skok do smycky cteni bajtu Smycka cteni bajtu se pouziva k nacteni vzdy jednoho bajtu.Prvni je typovy, nasledovan datovymi a na zaver bajt paritni. 05A9 EX AF,AF' ;Ulozeni indikatoru JR NZ,#05B3 ;Skok pro typovy bajt JR NC,#05BD ;Skok pri VERIFY nahravky LD (IX+0),L ;Ulozeni nacteneho bajtu na spravnou adresu JR #05C2 ;Skok pro nacteni dalsiho bajtu 05B3 RL C ;Docasne ulozeni CY XOR L ;Navrat,kdyz se typovy bajt lisi od typoveho RET NZ ;bajtu z pasky; CY=0 LD A,C ;CY je obnoveno na puvodni hodnotu RRA LD C,A INC DE ;Citac je inkrementovan,aby byla kompenzovana JR #05C4 ;jeho dekrementace po skoku Pri verifikaci je nove nacteny bajt porovnavan s puvodnim. 05BD LD A,(IX+0) ;Zjisteni hodnoty puvodniho bajtu a porovnani XOR L ;s prave nactenym bajtem RET NZ ;Navrat pri nerovnosti ;Nyni bude nacten novy bajt 05C2 INC IX ;Zvyseni adresy pro ulozeni dalsiho bajtu 05C4 DEC DE ;Snizeni citace delky bloku EX AF,AF' ;Ulozeni indikatoru LD B,#B2 ;Casovaci konstanta 05C8 LD L,#01 ;Ulozeni znackoveho bitu ;Tato smycka sestavuje nacitany bajt do reg. L 05CA CALL #05E3 ;Nalezeni delky pulsu jednotlivych bitu a na- RET NC ;vrat pri nespravne (vetsi) delce pulsu (CY=0) LD A,#CB ;Porovnani delky oproti asi 2400 T,kdy pro 0 CP B ;je CY=0 a pro 1 je CY=1 RL L ;Ulozeni noveho bitu do registru L LD B,#B0 ;Casovaci konstanta pro dasi bit JP NC,#05CA ;Nejednalo-li se o 8my bit,skok zpet do smycky LD A,H ;Ulozeni paritniho bajtu do registru H XOR L ;Porovnani s registrem L LD H,A ;Vysledek zpet do H.Pruchody se opakuji do vy- LD A,D ;nulovani citace DE,pak paritni bajt=0 OR E JR NZ,#05A9 ;Je-li DE nenulovy,skoc zpet pro dalsi bajt LD A,H ;Test paritniho bajtu CP #01 ;Je-li paritni bajt 0,navrat s CY=1,jinak CY=0 RET Dve nasledujici rutiny jsou nejdulezitejsi casti operaci LOAD a VERIFY.Vstupu- je se do nich s casovou konstantou v registru B a barvou BORDERu i "typem hra- ny" v registru C.Navrat z techto rutin je s CY=1,kdyz pozadovany pocet hran byl nalezen v povolene periode - pak zmena v registru B ukazuje,za jak dlouho byla hrana nebo hrany nalezeny.CY=0 pri chybe.Z flag=0 pokud byla stisknuta klavesa BREAK.Z flag=1 znamena "bez nalezu a provede se navrat.LD-EDGE-2 slouzi pro nalezeni delky kompletniho pulsu.LD-EDGE-1 slouzi k urceni casu, ktery uplyne do nalezeni hrany. 05E3 CALL #05E7 RET NC 05E7 LD A,#16 ;Cekani 350 T pred vstupem do vzorkovaci smycky 05E9 DEC A JR NZ,#05E9 AND A MONITOR ROM - ZX Spectrum - 17 - JP Z,#1C8A RST #20 ;Nacteni dalsiho znaku a zvyseni systemove CALL #28B2 ;promenne CH-ADD.Vyhledani retezce v oblasti SET 7,C ;promennych.Nastaveni bitu 7 v nazvu pole JR NC,#0672 ;Skok dopredu,jedna-li se o existujici pole LD HL,#0000 ;Signal:uziti noveho pole LD A,(#5C74) ;Porovnani obsahu T-ADDR a vyvolani chyboveho DEC A ;hlaseni pri pozadovani SAVE nebo VERIFY JR Z,#0685 ;noveho pole 0670 RST #08 ;Ohlas: 2 - Variable not found DEFB #1 0672 JP NZ,#1C8A ;Pokracovani v praci s existujicim polem CALL #2530 ;Skok dopredu pri kontrole syntaxe JR Z,#0692 INC HL ;Nizsi bajt delky pole je presouvan do pracovni LD A,(HL) ;oblasti a je nasledovan prislusnym vyssim LD (IX+11),A ;bajtem delky pole INC HL LDC A,(HL) LD (IX+12),A INC HL 0685 LD (IX+14),C ;Tato cast je spolecna pro "nova" i "stara" LD A,#01 ;pole.Kopie jmena pole.Je pole ciselne? BIT 6,C JR Z,#068F ;Skoc,kdyz je ciselne INC A ;Je znakove.Uloze typ na prvni adresu 068F LD (IX+0),A ;hlavickove oblasti 0692 EX DE,HL ;Test posledni casti prikazu.Ulozeni ukazetele RST #20 ;do DE.Nacteni dalsiho znaku a zvyseni CH-ADD CP #29 ;Je konec zavorky ")" ? JR NZ,#0672 ;kdyz ne,tak nahlas "REPORT-C" RST #20 ;Nacteni dalsiho znaku a zvyseni CH-ADD CALL #1BEE ;Pokracuj na dalsi cast prikazu pri zjistovani EX DE,HL ;syntaxe.Ukazatel zpet do HL (indikuje JP #075A ;zacatek pole) 06A0 CP #AA ;Test na token SCREEN$ JR NZ,#06C3 ;Neni-token SCREEN$,skoc dopredu LD A,(#5C74) CP #03 ;Je zakazano MERGE "nazev" SCREEN$ JP Z,#1C8A RST #20 ;Vyzvednuti nasledujiciho znaku a zvyseni CH-ADD CALL #1BEE ;Posun na dalsi cast pri zajistovani syntaxe LD (IX+11),#00 ;Do hlavicky je ulozen pocet nahravanych bajtu, LD (IX+12),#1B ;coz je pro obrazovou pamet prave #1B00 LD HL,#4000 ;Adresa prvniho bajtu je #4000,toto cislo LD (IX+13),L LD (IX+14),H ;je tez ulozeno do hlavicky JR #0710 06C3 CP #AF ;Test na token CODE JR NZ,#0716 ;Neni-li token CODE,skoc dopredu LD A,(#5C74) CP #03 ;Neni dovoleno MERGE "nazev" CODE JP Z,#1C8A RST #20 ;Vyzvednuti nasledujiciho zn. a zvyseni CH-ADD CALL #2048 JR NZ,#06E1 ;Skok,kdyz prikaz pokracuje LD A,(#5C74) AND A ;Neni povoleno SAVE "nazev" CODE bez JP Z,#1C8A ;uvedeni parametru CALL #1CE6 ;Ulozeni 0 na zasobnik kalkulatoru JR #06F0 ;pro startovaci adresu 06E1 CALL #1C82 ;Hledani startovaci adresy.Vyzvedni 1.cislo RST #18 ;za CODE CP #2C JR Z,#06F5 ;Nasleduje-li dalsi cislo skok dopredu, LD A,(#5C74) ;prvni cislo bylo startovaci adresou AND A ;Neno povoleno SAVE CODE bez parametru JP Z,#1C8A ;startovaci adresy a delky 06F0 CALL #1CE6 ;Ulozeni 0 do kalkulatoru zasobniku JR #06F9 ;pro pocet bajtu 06F5 RST #20 ;Zjisteni poctu bajtu.Vyzvednuti nasledujiciho CALL #1C82 ;znaku a zvyseni CH-ADD.Zjisteni poctu bajtu ;Parametry jsou v hlavickove casti pracovni 06F9 CALL #1BEE ;oblasti.Posun na dalsi cast prikazu pri CALL #1E99 ;zjistovani syntaxe.Prenos delky do BC a jeji LD (IX+11),C ;ulozeni do hlavicky LD (IX+12),B CALL #1E99 ;Prenos startovaci adresy do BC a jeji ulozeni LD (IX+13),C ;do hlavicky LD (IX+14),B LD H,B ;Prenos ukazatele do HL jako obvykle LD L,C 0710 LD (IX+0),#03 ;SCREEN$ a CODE jsou oba typu 3.Vloz cislo pro JR #075A ;typ bloku dat a vrat se na drahu MONITOR ROM - ZX Spectrum - 19 - 07A6 INC DE ;Smycka pro vypsani znaku noveho jmena.Jmeno LD A,(DE) ;bude prijato dosahne-li citac prinejmensim CP (HL) ;nuly.Kazdy "novy" znak je porovnavan se INC HL ;znakem "puvodnim" pri negativnim vysledku se JR NZ,#07AD ;odskakuje,aby nedoslo k pripocteni znaku INC C ;Vypsani noveho znaku 07AD RST #10 ;Smycka pro 10 znaku DJNZ #07A6 ;Prosel-li citac v registru C nulou,bude jmeno BIT 7,C ;akceptovano.Kod #00 zpusobi,ze nasledujici JR NZ,#0767 ;text bude tisten od leveho okraje obrazovky LD A,#0D ;na dalsim radku.Jmeno hlavicky bylo zjisteno RST #10 ;a nyni je treba zjistit o jaky typ operace se POP HL ;jedna.Obnoveni ukazatele SCREEN$ a CODE LD A,(IX+0) ;pri operaci VERIFY CP #03 JR Z,#07CB LD A,(#5C74) ;Identifikator operace do registru A DEC A ;Jedna-li se o LOAD,je proveden odskok JP Z,#0808 ;na rutinu LOAD,jde-li o MERGE,je proveden CP #02 ;odskok na rutinu MERGE JP Z,#08B6 Rutina VERIFY CONTROL --------------------- Verifikace probiha tak,ze snimane bajty nejsou ukladany.Probiha pouze jejich postupne porovnavani.Tato rutina je take volana pri LOAD CODE a LOAD SCREEN$. 07CB PUSH HL ;Uschovani ukazatele LD L,(IX-6) ;Do HL je ukladan pocet bajtu "stareho" LD H,(IX-5) ;programu.Do DE je ukladan pocet bajtu LD E,(IX+11) ;bajtu "noveho" programu LD D,(IX+12) LD A,H ;Neni-li pocet udan,provede se odskok OR L JR Z,#07E9 ;Jen pro LOAD CODE SBC HL,DE ;Jde-li o LOAD delsiho bloku nez bylo JR C,#0806 ;pozadovano,provede se odskok na hlaseni R JR Z,#07E9 ;Jsou akceptovany shodne delky LD A,(IX+0) CP #03 JR NZ,#0806 07E9 POP HL ;Nasleduje posouzeni cisla 1.adresy,kam ma LD A,H ;byt program ulozen.Zjisteni ukazatele OR L ;1.adresy ktery,neni-li nulovy bude pouzit JR NZ,#07F4 LD L,(IX+13) ;Jinak budou uzity hodnoty nahrane v hlavicce LD H,(IX+14) 07F4 PUSH HL ;Nyni bude zjisteno zda se jedna o LOAD nebo POP IX ;VERIFY a bude proveden odskok na jednu LD A,(#5C74) ;z techto dvou rutin.Preneseni ukazatele do HL CP #02 SCF ;Signal pro LOAD a nejedna-li se o VERIFY, JR NZ,#0800 ;odskok na LOAD AND A ;Vynulovani CY,coz je signal VERIFY 0800 LD A,#FF ;Signal pro akceptovani bloku dat 0802 CALL #0556 ;LOAD nebo VERIFY dat RET C ;Navrat,je-li vse v poradku 0806 RST #08 ;Do rutiny chybovych hlaseni, DEFB #1A ;ohlas: Tape loading error Rutina LOAD CONTROL ------------------- Rizeni nacitani basickeho programu z pasky,vcetne promennych nebo poli. 0808 LD E,(IX+11) ;Do DE pocet bajtu tak,jak je uveden v nove LD D,(IX+12) ;hlavicce PUSH HL ;Uschovani adresy 1.bajtu programu,pokud je LD A,H ;tato adresa nulova,jedna se o LOAD drive OR L ;nedeklarovaneho pole JR NZ,#0819 INC DE ;Pricteni tri bajtu.Jeden bajt pro jmeno INC DE ;a dva bajty pro delku pole INC DE EX DE,HL ;Ulozeni ukazatele do HL JR #0825 ;Skok dopredu 0819 LD L,(IX-6) ;Test,zda je v pameti dost mista pro novy LD H,(IX-5) ;blok dat.Delka programu + promennych je EX DE,HL ;ulozena do HL a pozdeji do DE SCF SBC HL,DE ;Skok,neni-li treba vetsi prostor v pameti JR C,#082E 0825 LD DE,#0005 ;Test,zda je dost mista ve volne pameti ADD HL,DE ;Pricteni peti bajtu a ulozeni vysledku do BC LD B,H LD C,L CALL #1F05 ;Nasleduje test pameti MONITOR ROM - ZX Spectrum - 21 - Rutina MERGE CONTROL -------------------- Tato rutina se sklada z tri casti: a) LOAD bloku dat do oblasti WORKSPACE. b) MERGE radku noveho programu mezi radky stareho programu. c) MERGE novych promennych do starych promennych. Zacina se s LOADovanim bloku dat. 08B6 LD C,(IX+11) ;Nacti delku bloku do BC a uschovej ji LD B,(IX+12) PUSH BC INC BC ;Vytvor prostor o delce LEN+1 v pracovnim RST #30 ;prostoru a do bajtu "navic" vloz koncovy LD (HL),#80 ;znak EX DE,HL ;Presun ukazatele startu do HL POP DE ;Vyzvedni puvodni delku PUSH HL ;Uschovej kopii startu PUSH HL POP IX ;a preved start do IX SCF ;Signal: LOAD LD A,#FF ;Signal: blok dat CALL #0802 ;Proved LOAD bloku dat.Nyni dojde k splynuti POP HL ;radku noveho a stareho programu.Vyzvedni start LD DE,(#5C53) ;noveho programu a stareho programu 08D2 LD A,(HL) ;Vstup do smycky,ktera zpracovava radky noveho AND #C0 ;programu.Vyzvedni cislo rady a testuj je JR NZ,#08F0 ;Skoc,kdyz jsou radky skonceny 08D7 LD A,(DE) ;Vstup do smycky,ktera zpracovava radky stareho INC DE ;programu.Vyzvedni vyssi bajt cisla radku a po- CP (HL) ;rovnej jej s novym, INC HL ;inkrementuj ukazatel JR NZ,#08DF ;Skoc,neni-li shoda LD A,(DE) ;Opakuj porovnani pro CP (HL) ;nizsi bajty cisla radku 08DF DEC DE ;Obnov oba ukazatele DEC HL ;Skoc pri nalezeni spravneho mista pro radek JR NC,#08EB ;noveho programu,jinak najdi adresu zacatku PUSH HL ;dalsiho stareho radku EX DE,HL CALL #19B8 POP HL JR #08D7 ;Prochazej smyckou pro kazdy stary radek 08EB CALL #092C ;Vloz novy radek a skoc zpet do hlavni smycky JR #08D2 08F0 LD A,(HL) ;Obdobnym zpusobem splyvaji nove a stare pro- LD C,A ;menne.Vyzvedni postupne jmena vsech promen- CP #80 ;nych a testuj je.Test na konec a navrat,kdyz RET Z ;byly posouzeny vsechny promenne PUSH HL ;Uschovej ukazatel LD HL,(#5C4B) ;Vyzvedni VARS (pro stary program) 08F9 LD A,(HL) ;Nyni vstup do smycky,kde se naleznou vsechny CP #80 ;existujici promenne.Pri nalezeni koncoveho JR Z,#0923 ;bajtu skoc do predu (bude se pridavat) CP C ;Porovnej prvni bajty nazvu a skoc dopredu pro JR Z,#0909 ;dalsi posouzeni 0901 PUSH BC ;Uschovej nazev nove promenne a hledej dalsi CALL #19B8 ;starou promennou POP BC ;Obnov ukazatele a pokracuj ve smycce EX DE,HL JR #08F9 0909 AND #E0 ;Stara a nova promenna se shoduji podle prvnich CP #A0 ;bajtu nazvu,ale promenne s dlouhymi nazvy je JR NZ,#0921 ;treba porovnat cele.V uvahu se vezmou pouze POP DE ;bity 7,6 a 5.Akceptuji se vsechny typy pro- PUSH DE ;mennenych kromne tech s dlouhym nazvem.DE bude PUSH HL ;ukazovat na prvni znak nazvu nove promenne v HL ;je ukazatel prvniho znaku nazvu stare promenne ;Vstup do smycky k porovnani vsech znaku 0912 INC HL ;Posun oba ukazatele INC DE LD A,(DE) CP (HL) ;Porovnej oba znaky a skoc pri neshode JR NZ,#091E RLA ;Dokud neni nalezen posledni znak,pokracuj JR NC,#0912 ;ve smycce.Vyzvedni ukazatel na 1.znak nazvu POP HL ;stare promenne a skoc s uspesnym nalezem JR #0921 ;dopredu 091E POP HL ;Vyzvedni ukazatel na 1.znak nazvu stare JR #0901 ;promenne a skoc s neuspesnym nalezem zpet 0921 LD A,#FF ;Zde je vstup pro shodu.Signal: nahrada prom. 0923 POP DE ;Zde je vstup pro neshodu.A obsahuje #80,coz je EX DE,HL ;signal,ze ma byt promenna pridana.Vyzvednuti INC A ;ukazatele na 1.znak nazvu nove promenne a za- SCF ;mena registru.Z=1,jde-li o nahradu,Z=0,jde-li CALL #092C ;o pridani.Signal: promenna.Nyni proved vlozeni JR #08F0 ;Pokracuj ve smycce a posuzuj dalsi promennou MONITOR ROM - ZX Spectrum - 23 - RUTINY OBSLUHUJICI TISK NA OBRAZOVKU A TISKARNU *********************************************** Rutina PRINT OUT ---------------- Veskery tisk na hlavni cast obrazovky,dolni cast obrazovky a na tiskarnu obstaravaji nasledujici rutiny.Do rutiny PRINT OUT vstupuje kod znaku, kontrolniho znaku,nebo tokenu v registru A. 09F4 CALL #0B03 ;Aktualni tiskova pozice CP #20 ;Jestlize se jedna o znak ktery lze tisknout, JP NC,#0AD9 ;skoc CP #06 ;Tiskni otaznik pro hodnoty #00 az #05 JR C,#0A69 CP #18 ;a pro hodnoty #18 az #1F JR NC,#0A69 LD HL,#0A0B ;Baze "ridici" tabulky LD E,A ;Preved kod do registroveho paru DE LD D,#08 ADD HL,DE ;Indexuj v tabulce a vyzvedni doplnek LD E,(HL) ADD HL,DE ;Pricti doplnek a provedne primy skok do pris- PUSH HL ;lusne rutiny JP #0B03 TABULKA RIDICICH ZNAKU ---------------------- adresa doplnek znak adresa doplnek znak 0A11 4E PRINT carka 0A1A 4F nevyuzito 0A12 57 EDIT 0A1B 5F INK 0A13 10 kurzor vlevo 0A1C 5E PAPER 0A14 29 kurzor vpravo 0A1D 5D FLASH 0A15 54 kurzor dolu 0A1E 5C BRIGHT 0A16 53 kurzor nahoru 0A1F 5B INVERSE 0A17 52 DELETE 0A20 5A OVER 0A18 37 ENTER 0A21 54 AT 0A19 50 nevyuzito 0A22 53 TAB Podprogram KURZOR VLEVO ----------------------- Na vstupu obsahuje registr B cislo aktualniho radku a registr C cislo aktualniho sloupce. 0A23 INC C ;Pohyb doleva o jeden sloupec LD A,#22 ;Akceptuj tuto pokud neprevysi max. hodnotu CP C ;pro levou stranu JR NZ,#0A3A BIT 1,(IY+1) ;(FLAGS) Pri obsluze tiskarny skok dopredu JR NZ,#0A38 INC B ;Jeden radek nahoru LD C,#02 ;Nastav sloupcovou hodnotu LD A,#18 ;Testuj na nejvyssi radek.Spravne melo byt #19 CP B JR NZ,#0A3A ;Akceptuj zmenu,pokud neni vrchol obrazovky DEC B ;Neprijatelne-takze o radek dolu 0A38 LD C,#21 ;Nastav na levou krajni pozici 0A3A JP #0DD9 ;Proved neprimy navrat pres CL-SET @ PO-STORE Podprogram KURZOR VPRAVO ------------------------ Tento podprogram provede identickou operaci jako basicke PRINT OVER 1;CHR$ 32; 0A3D LD A,(#5C91) ;Vyzvedni P-FLAG a uschovej na zasobniku PUSH AF LD (IY+87),#01 ;(P-FLAG) Nastav P-FLAG na OVER 1 LD A,#20 ;Tiskni mezeru CALL #0B65 POP AF ;Obnov puvodni hodnotu pro P-FLAG.Poznamka: LD (#5C91),A ;Programator zapomel na navrat pres PO-STORE RET Podprogram "NAVRATU VOZIKU" --------------------------- Jestlize se jedna o vystup na tiskarnu,provede se vyprazdneni bafru.Pri vy- stupu na obrazovku se bude testovat skrol pred snizenim cisla radku. 0A4F BIT 1,(IY+1) ;(FLAGS) Pri obsluze tiskarny skok dopredu JP NZ,#0ECD LD C,#21 ;Nastav levy krajni sloupec CALL #0C55 ;Je-li potreba - skroluj DEC B ;Nyni o radek dolu JP #0DD9 ;Neprimy navrat pres CL-SET & PO-STORE MONITOR ROM - ZX Spectrum - 25 - AND #1F RET Z ;a vrat se,je-li vysledek nula LD D,A ;Pouzij D jako citac SET 0,(FLAGS) ;Potlac "uvodni mezeru" 0AD0 LD A,#20 CALL #0C3B DEC D JR NZ,0AD0 ;Vytiskni D * mezeru RET Znaky ktere lze tisknout ------------------------ Pozadovany znak (nebo znaky) lze vytisknut volanim PO-ANY nasledovane rutinou PO-STORE. 0AD9 CALL #0B24 ;Vytiskni znak(y) a pokracuj pres PO-STORE Podprogram USCHOVA POZICE ------------------------- Nove hodnoty pro radek,sloupec,a adresa "pixlu" jsou uschovany v prislusnych systemovych promenych. 0ADC BIT 1,(IY+1) ;(FLAGS) Skok dopredu pri obsluze tiskarny JR NZ,#0AFC BIT 0,(IY+2) ;(TV-FLAG) Skok pri obsluze dolni casti JR NZ,#0AF0 ;obrazovky LD (#5C88),BC ;Uschovej hodnoty,ktere se vztahuji k hlavni LD (#5C84),HL ;casti obrazovky a vrat se RET 0AF0 LD (#5CBA),BC LD (#5C82),BC ;Uschovej hodnoty,ktere se vztahuji k bafru LD (#5C86),HL ;tiskarny a vrat se RET 0AFC LD (IY+69),C ;(P-POSN) Uschovej hodnoty,ktere se vztahuji LD (#5C80),HL ;k dolni casti obrazovky a vrat se RET Podprogram VYZVEDNUTI POZICE ---------------------------- Parametry aktualni tiskove pozice jsou vyzvednuty z prislusnych systemovych promennych. 0B03 BIT 1,(IY+1) ;(FLAGS) Skok dopredu pri obsluze tiskarny JR NZ,#0B1D LD BC,(#5C88) LD HL,(#5C84) ;Vyzvedni hodnoty,ktere se vztahuji k hlavni BIT 0,(IY+2) ;(TV-FLAG) casti obrazovky a vrat se,pokud to RET Z ;bylo umyslem LD BC,(#5C8A) ;Jinak vyzvedni hodnoty,ktere se vztahuji LD HL,(#5C86) ;dolni casti obrazovky vrat se RET 0B1D LD C,(IY+69) ;(P-POSN) Vyzvedni hodnoty,ktere se vztahuji LD HL,(#5C80) ;k bafru tiskarny a vrat se RET Podprogram tisku jakehokoliv znaku ---------------------------------- Obycejne znaky,tokens,graficke znaky a UDG znaky jsou projednany oddelene. 0B24 CP #80 JR C,#0B65 ;Pri obycejnem znaku skoc dopredu CP #90 JR NC,#0B52 ;Pri UDG znaku skoc dopredu LD B,A ;Presun grafickeho znaku.Vytvoreni graficke CALL #0B38 ;formy CALL #0B03 ;Obnoveni HL LD DE,#5C92 ;DE ukazuje na zacatek graficke formy JR #0B7F ;Skok dopredu a tisk grafickeho znaku Graficke znaky jsou konstruovany pouze pro tento pripad v oblasti pameti pro kalkulator tj. MEM-0 az MEM-1. 0B3B LD HL,#5C92 CALL #0B3E ;Ve skutecnosti volej nasledujici rutinu 2x 0B3E RR B ;Urceni bitu 0 (a pozdeji i bitu 2) grafickeho SBC A,A ;kodu.A bude obsahovat #00, AND #0F ;nebo #0F podle hodnoty bitu v kode LD C,A ;Uschovej vysledek v C RR B ;Urceni bitu 1 (a pozdeji i bitu 3) grafickeho SBC A,A ;kodu.A bude obsahovat #00 nebo #0F podle AND #0F ;hodnoty bitu v kode OR C ;Oba vysledky jsou kombinovany LD C,#04 ;A obsahuje polovinu znakove formy a bude 0B4C LD (HL),A ;pouzito 4x INC HL DEC C ;Po horni polovine znakove formy prijde dolni MONITOR ROM - ZX Spectrum - 27 - EX DE,HL ;adresu znakove oblasti DEC H BIT 1,(IY+1) ;(FLAGS) Pri obsluze obrazovky nastav CALL Z,#0BDB ;prislusny bajt atributu POP HL ;Obnov puvodni cilovou a pozicni adresu POP BC DEC C ;Snizeni cisla sloupce INC HL ;Zvyseni cilove adresy RET ;Navrat 0BD3 EX AF,AF' ;Pri obsluze tiskarny musi byt cilova adresa LD A,#20 ;inkrementovana po prirustcich #20.Uschovej CY ADD A,E ;flag.Pricteni do registru E LD E,A EX AF,AF' ;Vyzvedni CY flag JR #0BC1 ;Skok zpet do smycky Podprogram nastaveni atributu ----------------------------- Je nalezen prislusny bajt.Stary obsah je modifikovan podle ATTR-T,MASK-T a P-FLAG a tato nova hodnota je vlozena zpet. 0BDB LD A,H ;Vyssi bajt cilove adresy je delen osmi.Urci, RRCA ;ktera tretina obrazovky je adresovana RRCA RRCA AND #03 OR #58 ;Nyni je formovan vyssi bajt adresy atributu LD H,A LD DE,(#5C8F) ;D obsahuje ATTR-T a E obsahuje MASK-T LD A,(HL) ;Hodnota "stareho" atributu do A.Maskovani XOR E AND D XOR E BIT 6,(IY+87) ;(P-FLAG) Pokud neni PAPER 9,skoc dopredu JR Z,#0BFA ;Puvodni barva PAPER se ignoruje a podle AND #C7 ;odstinu INK bude nova barva PAPER bud cerna BIT 2,A ;(000),nebo bila (111) JR NZ,#0BFA XOR #38 0BFA BIT 4,(IY+87) ;(P-FLAG) Pokud neni INK 9,skoc dopredu JR Z,#0C08 ;Puvodni barva INK se ignoruje a podle odstinu AND #F8 ;PAPER bude nova barva INK bud cerna (000), BIT 5,A ;nebo bila (111).Vloz novou hodnotu atributu JR NZ,#0C08 XOR #07 0C08 LD (HL),A RET ;a vrat se Podprogram tisku hlaseni ------------------------ Tento podprogram se pouziva pro tisk hlaseni a tokens.Na vstupu obsahuje re- gistr A cislo hlaseni nebo token v tabulce a v DE je bazova adresa teto tabulky. 0C0A PUSH HL ;Vyssi bajt posledni ulozky na zasobniku je LD H,#00 ;vynulovan pro potlaceni koncovych mezer viz EX (SP),HL ;dale v programu.Skok dopredu JR #0C14 0C10 LD DE,#0095 ;Zde je vstupni bod pro rozvinuti tokens (#00 PUSH AF ;az #5A=RND az COPY).Bazova adresa pro tabulku 0C14 CALL #0C41 ;tokens.Uschovej kod na zasobniku.Tabulka je JR C,#0C22 ;prohledana a spravny vstup vytisknut.Nalezeni LD A,#20 ;polozky.Skok na tisk,neni-li pozadovana BIT 0,(IY+1) ;(FLAGS) uvodni mezera CALL Z,#0C3B ;Jednotlive znaky hlaseni nebo token jsou 0C22 LD A,(DE) ;postupne vytisknuty.Vyzvedni kod a zrus AND #7F ;"invertovany" bit.Tiskni znak CALL #0C3B LD A,(DE) ;Opet vyzvedni kod a posun ukazatel dopredu INC DE ;"Invertovany" bit jde do CY - signal posled- ADD A,A ;niho znaku.Skok,kdyz nejsi u konce hlaseni JR NC,#0C22 ;nebo token.Nyni se posoudi potreba zaverecne POP DE ;mezery.Pro hlaseni obsahuje D #00 a pro to- CP #48 ;kens #00-5A.Jestlize byl posledni znak "$", JR Z,#0C35 ;pak skok vpred.Jestlize posledni byl CP #82 ;kterykoli znak pred invertovanym "A",vrat se RET C 0C35 LD A,D ;Prozkoumej hodnotu v D a jestlize indikuje,ze CP #03 ;bylo tisknuto hlaseni RND,INKEY$ nebo PI, RET C ;vrat se.Vsechny ostatni pripady chteji LD A,#20 ;naslednou mezeru MONITOR ROM - ZX Spectrum - 29 - CP #20 ;Pri stisku BREAK skoc na chybove hlaseni JR Z,#0D00 CP #E2 ;Pri stisku STOP skoc na chybove hlaseni JR Z,#0D00 OR #20 ;Pri stisku n nebo N skoc na chybova hlaseni CP #6E JR Z,#0D00 LD A,#FE ;Ostatni znaky vyvolaji skroling.Otevreni CALL #1601 ;kanalu "S".Vyzvednuti a obnoveni P-FLAG POP AF LD (#5C91),A POP HL ;Vyzvednuti a obnoveni ATTR-T a MASK-T LD (#5C8F),HL 0CD2 CALL #0DFE ;Nyni je displej skrolovan.Cely displej je LD B,(IY+49) ;(DF-SZ) skrolovan.Jsou nalezena cisla radku INC B ;a sloupce nad dolni casti obrazovky a jsou LD C,#21 ;uschovana PUSH BC CALL #0E9B ;Je nalezena adresa odpovidajiciho atributu LD A,H ;a tato je ulozena.Radek,o ktery se jedna, RRCA RRCA RRCA ;obdrzi atributy z dolni casti obrazovky a no- AND #03 ;vy radek na nejspodnejsim okraji displeje bude OR #58 ;mit hodnoty z ATTR-P.Staci tedy hodnoty LD H,A ;z atributu zamenit LD DE,#5AE0 ;DE ukazuje na prvni atribut nejspodnejsiho LD A,(DE) ;radku.Hodnota bajtu do A LD C,(HL) ;Bajt z radku nad dolni casti obrazovky do C LD B,#20 ;32 bajtu je ve hre EX DE,HL ;Zamena ukazatelu 0CF0 LD (DE),A ;Proved prvni zamenu a pokracuj se stejnymi LD (HL),C ;hodnotami pro cely radek INC DE INC HL DJNZ #0CF0 POP BC ;Vyzvedni cislo nejspodnejsiho radku a sloupce RET ;horni casti obrazovky a vrat se 0CF8 DEFB #80 ;Sdeleni "scroll?" DEFB #73,#63,#72,#6F DEFB #6C,#6C,#BF 0D00 RST #08 ;Ohlas: BREAK - CONT repeats DEFB #0C 0D02 CP #02 ;Osetreni dolni casti obrazovky.Je-li prilis JR C,#0C86 ;velka,skok na chybove hlaseni.Jestlize neni ADD A,(IY+49) ;(DF-SZ) potreba skrolovat,provede se navrat SUB #19 RET NC NEG ;V A je pocet skrolu,ktere se maji vykonat PUSH BC ;Uschovani cisla radku a sloupce.Pocet skrolu, LD B,A ;ATTR-T,MASK-T a P-FLAG jsou uschovany.Budou LD HL,(#5C8F) ;pouzity "permanentni" barvy.Pocet skrolu do A PUSH HL LD HL,(#5C91) PUSH HL CALL #0D4D LD A,B 0D1C PUSH AF ;Nyni je dolni cast obrazovky skrolovana LD HL,#5C6B ;A krat.Uloz pocet.Hodnota v DF-SZ jde do B LD B,(HL) ;a do A,je inkrementovana a vracena do DF-SZ LD A,B INC A LD (HL),A LD HL,#5C89 ;Toto je S-POSN-hi CP (HL) ;Skok se provede,kdyz B=puvodni hodnota DF-SZ JR C,#0D2D ;tedy skrol pouze dolni casti.Inkrementace INC (HL) ;S-POSN-hi.Hodnota pro skrol celeho displeje LD B,#18 0D2D CALL #0E00 ;Skroluj B krat POP AF ;Vyzvednuti a dekrementace poctu skrolu DEC A JR NZ,#0D1C ;Skok zpet,neni-li konec POP HL ;Vyzvedni a obnov P-FLAG LD (IY+87),L ;(P-FLAG) POP HL ;Vyzvedni a obnov ATTR-T a MASK-T LD (#5C8F),HL LD BC,(#5C88) ;V pripade zmeny S-POSN volej CL-SET,aby se do RES 0,(IY+2) ;(TV-FLAG) DF-CC ulozila odpovidajici hodnota CALL #0DD9 SET 0,(IY+2) ;(TV-FLAG) Signal:obsluha dolni casti obrazovky POP BC ;Vyzvedni cislo radku a sloupce a vrat se RET MONITOR ROM - ZX Spectrum - 31 - Subrutina CL-SET ---------------- Na vstupu do tohoto podprogramu obsahuje registrovy par BC cislo radku a sloupce na obrazovce,nebo reg. C obsahuje cislo sloupce v bafru tiskarny a pak je nalezena prislusna adresa bitu prvniho znaku.Rutina se vraci pres PO-STORE tak,aby byly ulozeny vsechny potrebne hodnoty. 0DD9 LD HL,#5B00 ;Adresa 1.bajtu bafru tikarny.Obsluhujes-li BIT 1,(IY+1) ;(FLAGS) bafr tiskarny,skoc vpred JR NZ,#0DF4 LD A,B ;Okopiruj cislo radku.Obsluhujes-li hlavni cast BIT 0,(IY+2) ;(TV-FLAG) obrazovky,skoc vpred JR Z,#0DEE ADD A,(IY+49) ;(DF-SZ) Prvni radek dolni casti obrazovky se SUB #18 ;nazyva "radek #18" a to musi byt prevedeno 0DEE PUSH BC ;Cisla radku a sloupce jsou uschovana a cislo LD B,A ;radku prevedeno do A.V HL je nyni adresa CALL #0E9B ;zacatku radku a cisla radku a sloupcu jsou POP BC ;ulozena do BC.Cislo sloupce je nyni prevra- 0DF4 LD A,#21 ;ceno,prevedeno do reg. paru DE a na zaver je SUB C ;v HL vytvorena pozadovana adresa.Tyto hodnoty LD E,A ;jsou uschovany rutinou PO-STORE LD D,#00 ADD HL,DE JP #0ADC Skrolovaci subrutina -------------------- Pocet radku,ktery ma byt skrolovan,vstupuje do rutiny v reg. B. 0DFE LD B,#17 ;Vstupni bod po dotazu "scroll?".Hlavni vstup- 0E00 CALL #0E9B ;ni bod z predchazejiciho a nebo z prikazu LD C,#08 ;INPUT AT.Najdi pocatececni adresu radku. 0E05 PUSH BC ;8 "pixlovych" radku tvori kompletni znakovy PUSH HL ;radek.Nyni prichazi hlavni skrolovaci smycka LD A,B ;Registr B obsahuje pocet scrolovanych radku, AND #07 ;HL ukazuje na adresu 1.skrolovaneho bajtu LD A,B ;a registr C je vyuzit jako pocitadlo "pixlo- JR NZ,#0E19 ;vych" radku.Uschovej oba citace a adresu 0E0D EX DE,HL ;Nejedna-li se o prechod na dalsi tretinu LD HL,#F8E0 ;displeje,skoc dopredu."Pixlove" radky prvniho ADD HL,DE ;znakoveho radku kazde tretiny musi byt prene- EX DE,HL ;seny pres 2K hranici (kazda tretina ma 2KB) LD BC,#0020 ;Po skonceni techto operaci zustava v HL pu- DEC A ;vodni hodnota a DE ukazuje na novou cilovou LDIR ;adresu.Jedna se o 32 znaku.Dekrementuj poci- 0E19 EX DE,HL ;tadlo za kazdy preneseny radek a prenes poza- LD HL,#FFE0 ;dovanych 32 bajtu.Pixlove radky uvnitr tretin ADD HL,DE ;maji byt nyni skrolovany.Registr A obsahuje EX DE,HL ;pri prvnim prubehu hodnoty #01 az #07,#09 az LD B,A ;#0F nebo #11 az #17.Znovu je DE nastaven tak, AND #07 ;aby ukazoval na pozadovanou cilovou adresu, RRCA ;ale tentokrat pouze o 32 pozic dale.Uschovej RRCA ;cislo radku v reg.B.Nyni zjisti,kolik znaku RRCA ;zustava v teto tretine.Predej celkovy pocet LD C,A ;znaku do registru C.Vyzvedni cislo radku LD A,B ;A nyni jiz obsahuje celkovy pocet znaku i BC LD B,#00 ;a "pixlovy" radek kazdeho znaku je skrolovan LDIR ;Priprav pro inkrementaci adresu,na kterou se LD B,#07 ;bude ukladat pri tretinove hranici a inkre- ADD HL,BC ;mentuj HL o #0700.Nejsou-li zde jiz zadne AND #F8 ;dalsi zvazovane tretiny skoc zpet JR NZ,#0E0D ;Nyni zjisti,zda byla smycka pouzita 8krat pro POP HL ;8"pixlovych"radku.Vyzvedni adresu originalu INC H ;Adresuj dalsi"pixlovy"radek.Vyzvedni citace POP BC ;Dekrementuj citac"pixlovych"radku a dokud DEC C ;nebylo preneseno vsech 8"pixlovych"radku skoc JR NZ,#0E05 ;zpet Dale jsou skrolovany atributove bajty.Povsimnete si,ze registr B obsahuje stale pocet radku,ktere maji byt skrolovany a registr C obsahuje nulu. CALL #0E88 ;Je nalezena pozadovana adresa v oblasti LD HL,#FFE0 ;promennych a pocet znaku v "B" radcich ADD HL,DE ;Premistovaci konstanta pro vsechny atributove EX DE,HL ;bajty je 32 mist LDIR ;Skrolovani atributovych bajtu LD B,#01 ;Zbyva jeste vycistit spodni radky displeje MONITOR ROM - ZX Spectrum - 33 - Subrutina CL-ADDR ----------------- Pro zadane cislo radku v registru B vytvori v HL tato rutina odpovidajici adresu obrazove pameti. 0E9B LD A,#18 ;Cislo radku je prevraceno a vysledek je SUB B ;ulozen do registru D LD D,A RCCA ;Ve skutecnosti (A mod B)*32.V kazde tretine RCCA ;displeje ma nizsi bajt tyto hodnot: RCCA ;1.radek=#00,2.radek=#02,...atd.Nizsi bajt je AND #E0 ;je ulozen do L.Skutecne cislo radku je LD L,A ;vyzvednuto,ve skutecnosti se jedna LD A,D ;o 64+8*INT(A/8).Vyssi bajt horni tretiny AND #18 ;displeje ma hodnotu #40,bajt stredni tretiny OR #40 ;#48 a nizsi tretina je #50.Tyto hodnoty jsou LD H,A ;ulozeny do registru H a provede se navrat RET Rutina prikazu COPY ------------------- Tato rutina obslouzi 176 "pixlovych" radku displeje, a to jeden po druhem. 0EAC DI ;Po dobu provadeni teto rutiny je zakazano LD B,#B0 ;maskovane preruseni.Konstanta 176 radku LD HL,#4000 ;Bazova adresa displeje.Zde se vstupuje 0EB2 PUSH HL ;do smycky.Uschovej bazovou adresu a pocet PUSH BC ;radku.Tato rutina bude zavolana 176 krat CALL #0EF4 POP BC ;Vyzvedni cislo radku a bazovou adresu POP HL ;Bazova adresa je posunuta na dalsi "pixlovy" INC HL ;radek.Nebylo-li preneseno jeste vsech 8 LD A,H ;"pixlovych"radku,skoc dopredu AND #07 JR NZ,#0EC9 ;Pro kazdy novy znakovy radek musi byt bazova LD A,L ;adresa upravena.Vyzvedni nizsi bajt a zvys ho ADD A,#20 ;o #20 LD L,A ;CY flag bude nulovy,pohybujes-li se uprostred CCF ;tretiny displeje.Neguj CY flag. SBC A,A ;Registr A bude obsahovat #08,pokud jsi uvnitr AND #F8 ;tretiny a #00 pokud jdes do nove tretiny ADD A,H ;Vyssi bajt adresy je zvysen LD H,A 0EC9 DJNZ #0EB2 ;Skoc zpet,pokud jsi nevytiskl 176"pixlovych" JR #0EDA ;radku.Skoc na konec rutiny COPY Subrutina COPY-BUFF ------------------- Tento podprogram je volan kdykoliv je zapotrebi vyslat obsah bafru na tiskarnu. 0ECD DI ;Maskovane preruseni je zakazano LD HL,#5B00 ;Adresa prvniho bajtu bafru LD B,#08 ;Je zde 8 "pixlovych" radku 0ED3 PUSH BC ;Uschovej cislo radku CALL #0EF4 ;Tato rutina je volana 8x POP BC ;Vyzvedni cislo radku DJNZ #0ED3 ;Opakuj do vytisteni 8 "pixlovych" radku 0EDA LD A,#04 ;Zastav motor tiskarny OUT (#FB),A EI ;Povol preruseni a pokracuj pres CLEAR-PRB Subrutina "VYCISTI BAFR TISKARNY" --------------------------------- Pri zavolani CLEAR-PRB je vycisten bafr tiskarny. 0EDF LD HL,#5B00 ;Adresa prvniho bajtu bafru tiskarny LD (IY+70),L ;(PR-CC) Nastav tiskovy sloupec na nulu XOR A ;Vynuluj registr A a registr B (ve skutecnosti LD B,A ;obsahuje dekadicky 256) 0EE7 LD (HL),A ;Nyni je vycisteno 256 bajtu bafru tiskarny, INC HL ;jeden po druhem DJNZ #0EE7 RES 1,(IY+48) ;(FLAGS2) Signal:bafr je prazdny LD C,#21 ;Nastav tiskovou pozici JP #0DD9 ;a vrat se pres CL-SET a PO-STORE Subrutina COPY-LINE ------------------- Na vstupu tohoto podprogramu obsahuje registrovy par HL adresu 32 bajtu,ktere predstavuji "pixlovou" radku a B obsahuje cislo "pixlove" radky. 0EF4 LD A,B ;Okopiruj cislo radky CP #03 ;Registr A bude obsahovat #00 dokud se nebudou SBC A,A ;obsluhovat posledni dva radky AND #02 ;Zpomal motor,ale pouze pro posledni dva OUT (#FB),A ;"pixlove" radky LD D,A ;Registr D bude obsahovat bud #00 nebo #02 MONITOR ROM - ZX Spectrum - 35 - Rutina ADD-CHAR --------------- Tato subrutina ve skutecnosti pricita kod znaku do soucasneho EDIT nebo INPUT radku. 0F81 RES 0,(IY+7) ;(MODE) Signal "K" mode LD HL,(#5C5B) ;Vyzvedni pozici kurzoru CALL #1652 ;Udelej jednu mezeru 0F8B LD (DE),A ;Vloz kod do teto mezery a signalizuj, INC DE ;ze kurzor se musi postavit na dalsi misto LD (#5C5B),DE ;Pak se vrat do ED-LOOP RET Editacni tlacitka jsou zpracovana takto: 0F92 LD E,A ;Kod je prevedeno do registroveho paru DE LD D,#00 LD HL,#0F99 ;Bazova adresa tabulky editacnich klaves do HL ADD HL,DE ;Vstupni bod je adresovan a vyzvednut do E LD E,(HL) ADD HL,DE PUSH HL ;Adresa obsluzne rutiny na zasobnik a do HL LD HL,(#5C5B) ;je ulozena pozice kurzoru.Je proveden RET ;neprimy skok do zadane rutiny TABULKA EDITACNICH KLAVES ------------------------- adresa doplnek znak adresa doplnek znak 0FA0 09 EDIT 0FA5 70 DELETE 0FA1 66 kurzor vlevo 0FA6 7E ENTER 0FA2 6A kurzor vpravo 0FA7 CF SYMBOL SHIFT 0FA3 50 kurzor dolu 0FA8 D4 GRAPHICS 0FA4 B5 kurzor nahoru Subrutina tlacitka edit ----------------------- Je-li system v editacnim modu,zpusobi stisteni editacni klavesy EDIT sneseni aktualniho basickeho radku (tj. radku,na ktery ukazuje programovy kurzor). Je-li system v modu INPUT,je po stisteni klavesy EDIT vymazan text vlozeny uzivatelem. 0FA9 LD HL,(#5C49) ;Vyzvedni cis. soucasneho,ale skoc dopredu, BIT 5,(IY+55) ;(FLAGX) jestli-ze jsi v modu INPUT JP NZ,#1097 CALL #196E ;Nalezni adr.zacatku radku a s ni i jeho cislo CALL #1695 LD A,D ;Je-li obdrzene cislo radku nula,vycisti jen OR E ;editacni oblast JP Z,#1097 PUSH HL ;Uschovej adresu tohoto radku.Uloz si do BC INC HL ;jeho delku. Pak k teto delce pricti 10 LD C,(HL) ;a vysledek opet uloz do BC INC HL LD B,(HL) LD HL,#000A ADD HL,BC LD B,H LD C,L CALL #1F05 ;Testuj,je-li zde dost mista pro tento radek CALL #1097 ;Nyni vycisti editacni oblast.Vyzvedni soucas- LD HL,(#5C51) ;nou adr. kanalu a zamen ji s adresou tohoto EX (SP),HL ;radku.Prechodne si ji uloz PUSH HL LD A,#FF ;Aby mohl byt radek okopirovan do edit.oblasti CALL #1601 ;otevri kanal "A" POP HL ;Vyzvedni adr.radku a postup 1 bajt pred radek DEC HL ;Dekrementuj cis.soucasneho radku,aby se za- DEC (IY+15) ;(E-PPC-LO) branilo vytisku kurzoru a vytiskni CALL #1855 ;basicky radek INC (IY+15) ;(E-PPC-LO) Inkrementuj cislo radku Poznamka: Tyto upravy nekdy nesplni svou funkci a kurzor je vytisknut. LD HL,(5C59) ;(E-LINE) Vyzvedni adresu radky v editacni INC HL ;oblasti a prekroc cislo radku a delku radku INC HL ;tak,abys nalezl pozici kurzoru INC HL INC HL LD (#5C5B),HL POP HL ;Vyzvedni drivejsi kanalovou adresu a nastav CALL #1615 ;prislusne vlajky RET ;Vystup do ED-LOOP MONITOR ROM - ZX Spectrum - 37 - Subrutina EDITACNI KURZOR NAHORU -------------------------------- 1059 BIT 5,(IY+55) ;(FLAGX) Jsi-li v modu INPUT,vrat se RET NZ LD HL,(#5C49) ;Zjisti cislo soucasneho radku a jeho pocatecni CALL #196E ;adresu.HL nyni ukazuje na predchozi radek EX DE,HL CALL #1695 ;Cislo radku je vyzvednuto LD HL,#5C4A CALL #191C ;Cislo radku je ulozeno 106E CALL #1795 ;Automaticky listing je znovu zavolan a potom LD A,#00 ;je otevren kanal "K" pred navratem do ED-LOOP JP #1601 Subrutina ED-SYMBOL ------------------- Jestlize byly pouzity kody SYMBOL & GRAPHICS,budou osetreny nasledovne. 1076 BIT 7,(IY+55) ;(FLAGX) Skoc zpet,pokud nejsi v INPUT LINE JR Z,#1024 107C JP #0F81 ;Skoc zpet Subrutina ED-ERROR ------------------ Toto je vstupni bod,doslo-li k nejake chybe. 107F BIT 4,(IY+48) ;(FLAGS-2) Skoc zpet,pouzivas-li jiny kanal JR Z,#1026 ;nez "K" LD (IY+0),#FF LD D,#00 ;Zrus cislo chyby a proved zavrceni,nez se LD E,(IY-2) ;(RASP) vratis zpet do editoru LD HL,#1A90 CALL #03B5 JP #0F30 Subrutina CLEAR-SP ------------------ Editacni oblast nebo WORKSPACE jsou vycisteny. 1097 PUSH HL ;Uschovej ukazatel prostoru DE bude ukazovat CALL #1190 ;na prvni bajt a HL na posledni DEC HL CALL #19E5 ;Nyni se zrusi potrebny pocet bajtu.Systemove LD (#5C5B),HL ;promenne K-CUR a MODE("K" mode)jsou nastaveny LD (IY+7),#00 ;pred vyzvednutim ukazatele a provedenim POP HL ;navratu RET Subrutina pro klavesovy vstup ----------------------------- Tato dulezita subrutina vraci kod posledni stistene klavesy,ale povsimnete si, ze klavesa CAPS LOCK,zmeny modu a zmeny barevnych parametru jsou v teto rutine zpracovany take. 10AB BIT 3,(IY+2) ;(TV-FLAG) Okopiruj editacni nebo inputovy CALL NZ,#111D ;radek na obrazovku,byl-li zmenen mod AND A ;Vrat se s CY flag=0 a Z flag=0,jestlize nebyla BIT 5,(IY+1) ;(FLAGS) stisknuta zadna nova klavesa RET Z LD A,(#5C08) ;Byla-li,vyzvedni kod a dej signal,ze jsi tak RES 5,(IY+1) ;(FLAGS) ucinil PUSH AF ;Prechodne si uschovej tento kod a vycisti BIT 5,(IY+2) ;(TV-FLAG) dolni cast obrazovky CALL NZ,#0D6E POP AF ;Vyzvedni kod a akceptuj vsechny znaky a kody CP #20 ;pro tokens.Skoc dopredu pri temer vsech kodech JR NC,#111B ;pro ridici znaky.Skoc dopredu s kodem pro CP #10 ;CAPS LOCK nebo pro zmenu "modu" JR NC,#10FA CP #06 JR NC,#10DB ;Nyni se vyporadej s FLASH,BRIGHT a INVERSE LD B,A ;Uloz si kod AND #01 ;Ponech si pouze bit 0 LD C,A ;C obsahuje #00 (=off) nebo #01 (=on) LD A,B ;Vyzvedni kod RRA ;Jednou ho rotuj,cimz prijdes o bit 0 ADD A,#12 ;Pricti #12 kvuli BRIGHT,FLASH a INVERSE JR #1105 ;Kod pro CAPS LOCK a kod modu jsou osetreny 10DB JR NZ,#10E6 ;mistne.Skoc s kody modu LD HL,#5C6A LD A,#08 ;Flipuj bit 3 FLAGS2 XOR (HL) LD (HL),A ;Jde o vlajku CAPS LOCK JR 10F4 ;Skok dopredu MONITOR ROM - ZX Spectrum - 39 - 1167 LD D,#00 ;Nyni osetreni jakekoliv chyby LD E,(IY-2) ;(RASP) LD HL,#1A90 CALL #03B5 ;Zavrc LD (IY+0),#FF ;(ER-NR) Zrus cislo chyby LD DE,(#5C8A) ;Vyzvedni soucasnou hodnotu S-POSNL a skoc JR #117E ;Normalni vystup po dokonceni kopirovani 117C POP DE ;editacniho radku.Hodnota nove pozice a adresa POP HL ;chyby 117E POP HL ;Sem se skace pri chybe.Stara hodnota ERR-SP LD (#5C3D),HL ;je obnovena POP BC ;Vyzvedni starou hodnotu S-POSNL a uschovej PUSH DE ;hodnoty nove pozice CALL #0DD9 ;Nastav systemove promenne a starou hodnotu POP HL ;S-POSNL dej do ECHO-E LD (#5C82),HL LD (IY+38),#00 ;X-PRT-hi je vynulovana a je proveden navrat RET Rutina na nastaveni "HL" A "DE" ------------------------------- Tato subrutina vraci registry HL a DE tak,ze HL ukazuje na prvni a DE na posledni lokaci editacniho prostoru nebo WORKSPACE. 1190 LD HL,(#5C61) ;Ukazuj na posledni lokaci editacni oblasti DEC HL AND A ;Nuluj CY flag 1195 LD DE,(#5C59) ;Ukazuj na zacatek editacni oblasti a jsi-li BIT 5,(IY+55) ;(FLAGX) v editacnim modu,vrat se RET Z LD DE,(5C61) RET C LD HL,(#5C63) ;Vyzvedni STKBOT a vrat se RET Subrutina odstraneni FP ----------------------- Tento podprogram odstranuje skryte floating point formy z basickeho radku. 11A7 LD A,(HL) ;Vyzvedni znak CP #0E ;Je to znacka cisla? LD BC,#0006 ;Cislo zabira sest mist CALL Z,#19E8 ;Zruseni FP cisla LD A,(HL) ;Vyzvedni opet tento kod INC HL ;Posun ukazatel CP #0D ;ENTER? JR NZ,#11A7 ;Opakuj kdyz ne,jinak proved navrat RET PROVADECI RUTINY **************** Inicializacni rutina -------------------- Hlavni vstupni bod do teto rutiny je na START/NEW (#11CB).Pri vstupu ze startu (#0000),napriklad je-li do systemu pri zapojeni poprve privedeno napeti, registr A obsahuje #00 a registr DE obsahuje #FFFF. Nicmene vstupni bod muze byt tez dosazen pri vykonani prikazu NEW. Rutina prikazu NEW ------------------ 11B7 DI ;Zakazano mask.preruseni LD A,#FF ;Signal: NEW LD DE,(#5CB2) ;Existujici hodnota systemove promenne RAMTOP EXX ;je vyzvednuta.Zrcadlove registry jsou LD BC,(#5CB4) ;naplneny temito systemovymi promennymi, LD DE,(#5C38) ;ktere maji byt rovnez uschovany LD HL,(#5C7B) EXX 11CB LD B,A ;Hlavni vstupni bod.Uschovej signal pro LD A,#07 ;pozdejsi pouziti OUT (#FE),A ;Barva pro BORDER: bila LD A,#3F LD I,A ;Nastav registr I na #3F.Cekej 24 T stavu DEFB #00,#00,#00 DEFB #00,#00,#00 11DA LD H,D ;Nyni se provede kontrola pameti.Prenes hod- LD L,E ;notu v registrovem paru DE do HL (START=#FFFF 11DC LD (HL),#02 ;NEW=RAMTOP) Uloz hodnotu #02 do vsech pameto- DEC HL ;vych mist nad #3FFF CP H JR NZ,#11DC MONITOR ROM - ZX Spectrum - 41 - SET 1,(IY+1) ;(FLAGS) Signal:pouziva se tiskarna Nuluj bafr CALL #0EDF ;tiskarny LD (IY+49),#02 ;(DF-SZ) Nastav velikost dolni casti obrazovky CALL #0D6B ;a smaz cely displej. Nyni vytiskni sdeleni: XOR A ;1982 Sinclair Research Ltd. na spodni radek LD DE,#1538 ;obrazovky CALL #0C0A SET 5,(IY+2) ;(TV-FLAG) Signal: spodni cast obrazovky JR #12A9 ;Skok do hlavni provadeci smycky Hlavni provadeci smycka ----------------------- Tato smycka se v pameti rozklada od adresy #12A2 az do adresy #15AE a ridi editacni mod,provadeni primych prikazu a vypisy sdeleni. 12A2 LD (IY+49),#02 ;(DF-SZ) Dolni cast obrazovky bude velka dva CALL #1795 ;radky.Je proveden automaticky LISTing 12A9 CALL #16B0 ;Vsechny oblasti od E-LINE dopredu budou mit 12AC LD A,#00 ;minimalni velikosti.Kanal "K" je otevren CALL #1601 CALL #0F2C ;Je zavolan editor,aby uzivatel mohl vytvorit CALL #1B17 ;novy radek,ve kterem je nasled osetrena BIT 7,(IY+0) ;(ERR-NR) syntaxe.Je-li syntaxe v poradku,skoc JR NZ,#12CF BIT 4,(IY+48) ;(FLAGS-2) Pri pouziti jineho kanalu nez "K" JR Z,#1303 ;se provede skok LD HL,(#5C59) ;Ukazuj na zacatek radku kde je chyba CALL #11A7 ;Odstran FP formy z tohoto radku,nastav ERR-NR LD (IY+0),#FF ;na "OK" a skoc na MAIN-2 aniz by se JR #12AC ;v LISTingu cokoliv zmenilo Editovany radek prosel syntaxi a nyni je treba rozlisit tri ruzne typy radku. 12CF LD HL,(#5C59) ;Ukazuj na zacatek radku,tam take nastav CH-ADD LD (#5C5D),HL CALL #19FB LD A,B OR C ;Vyzvedni jakekoliv cislo radku do BC a je-li JP NZ,#155D ;to platne cislo radku,skoc dopredu a zarad RST #18 ;radek do programu.Vyzvedni 1.znak tohoto CP #0D ;radku a podivej se,jestli jde o radek nebo JR Z,#12A2 ;o pouhy CR.Skoc zpet,bylo-li tomu tak Editovany radek musi zacinat primym basickym prikazem,tak ze tento radek se stava prvnim,ktery bude interpretovan. BIT 0,(IY+48) ;(FLAGS2) Cela obrazovka bude smazana v pripade CALL NZ,#0DAF ;potreby,jinak jen spodni cast CALL #0D8E LD A,#19 SUB (IY+79) ;(S-POSN-hi) Nastav prislusne hodnoty LD (#5C8C),A ;pro skrolovaci citac SET 7,(IY+1) ;(FLAGS) Signal: vykonani radku LD (IY+0),#FF ;(EAR-NR) Zajisteni hodnoty "OK" na ERR-NR LD (IY+10),#01 ;(NSPPC) a osetreni prvniho prikazu v radku CALL #1B8A ;Nyni proved tento radek Poznamka: Na zasobnik bude ulozena hodnota #1303 a bude adersovana systemovou promennou ERR-SP.Po interpretaci radku a po vykonani vsech z toho vyplyvaji- cich akci se program vraci do MAIN-4,aby mohlo byt vytisknuto hlaseni. 1303 HALT ;Musi byt obnoveno maskovane preruseni RES 5(IY+1) ;(FLAGS) Signal:mozno dalsi klavesu.Byl-li BIT 1,(IY+48) ;(FLAGS2) pouzit bafr tiskarny,bude vycisten CALL NZ,#0ECD LD A,(#5C3A) ;Vyzvedni cislo chyby a inkrementuj ho INC A 1313 PUSH AF ;Uschovej si tuto novou hodnotu.Nastav na nu- LD HL,#0000 ;love hodnoty systemove promenne FLAGX, LD (IY+55),H ;X-PITR-HI a DEFADD LD (IY+38),H LD (#5D0B),HL LD HL,#0001 ;Zajisti, aby proud #00 ukazoval na kanal "K" LD (#5C16),HL ;Vycisti vsechny pracovni oblasti a kalkulato- CALL #16B0 ;rovy zasobnik RES 5,(IY+55) ;(FLAGSX) Signal:editacni mod CALL #0D6E ;Vycisti dolni cast obrazovky SET 5,(IY+2) ;(TV-FLAG) Dolni cast obrazovky bude potreba POP AF ;vycistit.Vyzvedni hodnotu hlaseni a okopiruj LD B,A ;ji do B a s cisly hlaseni 0-9 skoc dopredu CP #0A JR C,#133C ADD A,#07 ;Pricti doplnkovou hodnotu ASCII znaku MONITOR ROM - ZX Spectrum - 43 - Subrutina MAIN-ADD ------------------ Tato subrutina umoznuje basickenu radku,aby mohl byt pridan do existujiciho basickeho programu v programove oblasti.Existuje-li jak nova,tak i stara verze radku se stejnym cislem,pak bude stary radek znicen.Pokud novy radek obsahuje pouze svoje cislo,nebude do programu zarazen. 155D LD (#5C49),BC ;Necht je cislo noveho radku aktualnim cislem LD HL,(#5C5D) ;Vyzvedni CH-ADD a uschovej jeji adresu v DE EX DE,HL LD HL,#1555 ;Uschovej adr.hlaseni "G" na zasobnik,kam PUSH HL ;ukazuje i ERR-SP.Vyzvedni WORKSP LD HL,(#5C61) SCF ;Najdi delku radku od mista za cislem radku az SBC HL,DE ;po znak CR a uschovej tuto delku PUSH HL LD H,B ;Prenes cislo radku do registroveho paru HL LD L,C CALL #196E JR NZ,#157D ;Existuje jiz cislo takoveho radku? Ne-li,skoc CALL #19B8 ;Najdi delku stareho radku a znic ho CALL #19E8 157D POP BC ;Vyzvedni delku noveho radku,ale jednalo-li se LD A,C ;jen o cislo radku + CR,skoc dopredu DEC A OR B JR Z,#15AB PUSH BC ;Uschovej delku INC BC ;Jsou zapotrebi 4 mista navic.Dve pro cislo INC BC ;a dve pro delku INC BC INC BC DEC HL ;Nastav HL tak,aby ukazovalo pred misto urceni LD DE,(#5C53) ;Uschovej soucasnou hodnotu PROG,aby se zabra- PUSH DE ;nilo zhrouceni po pridani jednoho radku CALL #1655 ;Misto pro pridani jednoho radku je vytvoreno POP HL ;Stara hodnota PROG je vyzvednuta a obnovena LD (#5C53),HL POP BC ;Kopie delky radku(bez parametru)je vyzvednuta PUSH BC INC DE ;DE ukazuje na posledni misto nove oblasti LD HL,(#5C61) ;a HL na znak CR v novem radku,ktery je DEC HL ;v editacni oblasti.Nyni prekopiruj cely radek DEC HL LDDR LD HL,(#5C49) ;Vyzvedni cislo noveho radku EX DE,HL ;Adresa urceni jde do HL a cislo do DE POP BC ;Vyzvedni delku noveho radku a uloz jeji vyssi LD (HL),B ;a nizsi bajt.Povsimnete si,ze dvoubajtova DEC HL ;hodnota udavajici cislo radku je zde LD (HL),C ;na rozdil od systemu procesoru Z80 ukladana DEC HL ;v opacnem poradi LD (HL),E ;Nizsi bajt radku (!) DEC HL LD (HL),D ;Vyssi bajt radku (!) 15AB POP AF ;Odhod adresu hlaseni "G" a po odskoku zpet JP #12A2 ;proved i automaticky listing Pocatecni kanalove informace ---------------------------- Na pocatku existuji ctyri kanaly "K","S","R" a "P" pro komunikaci s klavesnici, obrazovkou,pracovnim prostorem a tiskarnou.Data jsou ulozena v tomto poradi: adresa vstupni rutiny a kod kanalu. 15AF DEFB #F4,#09 ;PRINT-OUT DEFB #A8,#10 ;KEY-INPUT DEFB #4B ;"K" 15B4 DEFB #F4,#09 ;PRINT-OUT DEFB #C4,#15 ;REPORT-J DEFB #53 ;"S" 15B9 DEFB #81,#0F ;ADD-CHAR DEFB #C4,#15 ;REPORT-J DEFB #52 ;"R" 15BE DEFB #F4,#09 ;PRINT-OUT DEFB #C4,#15 ;REPORT-J DEFB #50 ;"P" 15C3 DEFB #80 ;koncovy znak 15C4 RST #08 ;Ohlas: J - Invalid I/O device DEFB #12 MONITOR ROM - ZX Spectrum - 45 - Subrutina CHAN-FLAG ------------------- Tato rutina nastavuje prislusne vlajky pro ruzne kanaly. 1615 LD (#5C51),HL ;V HL je bazova adresa daneho kanalu RES 4,(IY+48) ;(FLAGS2) Signal:pouziva se jiny kanal nez "K" INC HL INC HL INC HL INC HL ;Prekroc vystupni a vstupni adresy LD C,(HL) ;Vyzvedni kod kanalu LD HL,#162D ;Toto je bazova adresa tabulky kanalovych kodu CALL #16DC ;Hledej v teto tabulce a urci vhodny doplnek, RET NC ;ale vrat se v pripade,ze jsi nenasel vhodny LD D,#00 ;kanalovy kod.Predej doplnek do DE a skoc LD E,(HL) ;na prislusnou rutinu nastavujici flag ADD HL,DE 162C JP (HL) TABULKA KANALOVYCH KODU ----------------------- 162D DEFB #4B,#06 ;kanal "K" offset #06 adresa #1634 162F DEFB #53,#12 ;kanal "S" offset #12 adresa #1642 1631 DEFB #50,#1B ;kanal "P" offset #1B adresa #164D 1633 DEFB #00 ;ukoncovac Subrutina FLAG KANALU "K" ------------------------- 1634 SET 0,(IY+2) ;(TV-FLAG) Signal:uzita dolni cast obrazovky RES 5,(IY+1) ;(FLAGS) Signal:pripraven prijmout dalsi SET 4,(IY+48) ;(FLAGS2) klavesu.Signal:pouzit kanal "K" JR #1646 ;Skok dopredu Subrutina FLAG KANALU "S" ------------------------- 1642 RES 0,(IY+2) ;(TV-FLAG) Signal:uzita hlavni cast obrazovky 1646 RES 1,(IY+1) ;(FLAGS) Signal:tiskarna neni prave pouzivana JP #0D4D Vrat se pres TEMPS,aby byly nast.spravne barvy Subrutina FLAG KANALU "P" ------------------------- 164D SET 1,(IY+1) ;(FLAGS) Signal:nyni bude pouzita tiskarna RET Subrutina "VYTVOR PROSTOR" -------------------------- Tato velmi dulezita subrutina je volana pri mnoha prilezitostech,aby vytvorila nejaky prostor.Proto musi HL ukazovat na adresu za prvnim bajtem pozadovaneho prostoru a v BC musi byt delka pozadovaneho prostoru.Je-li vyzadovan prostor o velikosti jedineho bajtu,vstupuje se do tohoto podprogramu v bode ONE-SPACE. 1652 LD BC,#0001 ;Pouze jeden bajt 1655 PUSH HL ;Uschovej ukazatel CALL #1F05 ;Zjisti,zda je zde dost volne pameti pro poza- POP HL ;dovany prostor.Obnov ukazatel CALL #1664 ;Zmen vsechny ukazatele,nez vytvoris zadany LD HL,(#5C65) ;prostor.Uloz do HL hodnotu STKEND EX DE,HL ;Zamen "stare" a "nove" LDDR ;Nyni vytvor prostor a vrat se RET Poznamka: Po navratu z tohoto podprogramu ukazuje registr HL na misto pred novym prostorem a registr DE ukazuje na posledni bajt nove vytvoreneho prosto- ru.Novy prostor muze byt popsan takto: od (HL)+1 az do (DE) vcetne.Nicmene "nova mista" maji i sve "stare adresy" a tak je mozno popsat novy prostor take takto: od (HL)+2 az do (DE)+1. Ve skutecnosti se zda, ze programator daval prednost druhemu popisu a to muze byt matouci. Subrutina "UKAZATELE" --------------------- Kdykoliv je vytvaren nebo rusen nejaky prostor,musi byt vsechny ukazatele, ktere nejak souvisi s timto prostorem,nastaveny.Na vstupu obsahuje registrovy par BC pocet bajtu,o ktere se bude jednat a registrovy par HL adresu mista pred novym prostorem. 1664 PUSH AF ;Uschovej AF PUSH HL ;Kopiruj adresu "pozice" prvni ze ctrnacti LD HL,#5C4B ;systemovych ukazatelu (promennych) LD A,#0E Tato smycka sice obslouzi vsechny ukazatele,ale zmeneny budou jenom ty,ktere ukazuji za danou "pozici". MONITOR ROM - ZX Spectrum - 47 - Vstup zde zpusobi "vycisteni" pracovniho prostoru a zasobniku kalkulatoru. 16BF LD HL,(#5C61) ;Vyzvedni WORKSP LD (#5C63),HL ;Toto cisti pracovni prostor Vstup zde zpusobi "vycisteni" pouze zasobniku kalkulatoru. 16C5 LD HL,(#5C63) ;Vyzvedni STKBOT LD (#5C65),HL ;Toto "cisti" zasobnik Ve vsech pripadech nastav permanentni hodnotu MEM. PUSH HL ;Uschovej STKEND LD HL,#5C92 ;Na tuto adresu nastav MEM LD (#5C68),HL POP HL ;Obnov STKEND do HL RET Zniceni editacniho radku ------------------------ 16D4 LD DE,(#5C59) ;Vyzvedni E-LINE JP #19E5 ;Proved "zniceni" Podprogram INDEXER ------------------ Tento podprogram se pouziva ve vice pripadech a slouzi k prohledavani tabulek. Vstupni bod je INDEXER (16DC). 16DB INC HL ;Postup na posouzeni dalsiho paru 16DC LD A,(HL) ;Vyzvedni prvni par a je-li to koncovy znak AND A ;#00,vrat se RET Z CP C ;Porovnej s dodanym znakem.Ukazatel na dalsi INC HL ;polozku.Skoc zpet pri nenalezeni spravne JR NZ,#16DB ;polozky.Pri uspesnem nalezu je nastaven CY SCF RET Rutina prikazu CLOSE# --------------------- Tento prikaz dava uzivateli moznost zavirat proudy.Pro proudy #00 az #03 jsou jejich data neustale systemem obnovovana a proto je nelze zavrit. 16E5 CALL #171E ;Jsou vyzvednuta existujici data proudu.Over CALL #1701 ;kod kanalu tohoto proudu.Priprav si nuly pro LD BC,#0000 ;vynulovani proudu.Priprav si hodnoty pro LD DE,#A3E2 ;identifikaci pouziti proudu #00 az #03.Testuj EX DE,HL ADD HL,DE ;Pro proudy #04 az #0F se nastavi CY JR C,#16FC ;a provede skok LD BC,#15D4 ;Jinak nalezni spravne hodnoty v tabulce ADD HL,BC ;inicializacnich proudovych dat LD C,(HL) ;Vyzvedni inicializacni data pro proudy INC HL ;#00 az #03 LD B,(HL) 16FC EX DE,HL ;Nyni vloz data a to bud obe nuly,nebo LD (HL),C ;inicializacni hodnoty INC HL LD (HL),B RET Podprogram CLOSE-2 ------------------ Kode kanalu pripojeneho k zaviranemu proudu musi byt "K","S" nebo "P". 1701 PUSH HL ;Uschovej adersu proudovych dat LD HL,(#5C4F) ;Vyzvedni bazovou adresu oblasti kanalovych ADD HL,BC ;informaci a nalezni kanalova data pro proud, INC HL ;ktery je prave zaviran INC HL INC HL LD C,(HL) EX DE,HL ;Uschovej ukazatel LD HL,#1716 ;Baze tabulky uzavirani proudu CALL #16DC ;Nalezni spravny doplnek LD C,(HL) ;Preved doplnek do BC,pricti ho k bazi LD B,#00 ADD HL,BC JP (HL) ;a skoc do prislusne subrutiny TABULKA UZAVIRANI PROUDU ------------------------ 1716 DEFB #4B,#05 ;kanal "K" doplnek #05 adresa 171C 1718 DEFB #53,#03 ;kanal "S" doplnek #03 adresa 171C 171A DEFB #50,#01 ;kanal "P" doplnek #01 adresa 171C Poznamka: Tato tabulka nema koncovy bajt. MONITOR ROM - ZX Spectrum - 49 - TABULKA OTEVIRANI PROUDU ------------------------ 177A DEFB #48,#06 ;kanal "K" doplnek #06 adresa 1781 177C DEFB #53,#08 ;kanal "S" doplnek #08 adresa 1785 177E DEFB #50,#0A ;kanal "P" doplnek #0A adresa 1789 1780 DEFB #00 ;koncovy znak Podprogram OPEN-K ----------------- 1781 LD E,#01 ;Datove bajty budou #01 a #00 JR #178B Podprogram OPEN-S ----------------- 1785 LD E,#06 ;Datove bajty budou #06 a #00 JR #178B Podprogram OPEN-P ----------------- 1789 LD E,#10 ;Datove bajty budou #10 a #00 178B DEC BC ;Zkrat delku vyrazu a pokud se nejednalo LD A,B ;o jediny znak,skoc na chybove hlaseni OR C JR NZ,#1765 LD D,A ;Vynuluj D,vyzvedni HL POP HL RET Prikazy CAT,ERASE,FORMAT & MOVE ------------------------------- V systemu standartniho SPECTRA vede pouziti techto prikazu k vyvolani chybove- ho hlaseni.Podrobne informace lze najit v knize "Komentovany vypis strojoveho kodu stinove ROM v Interface 1". 1793 JR #1725 ;Skok na chybove hlaseni Prikazy LIST & LLIST -------------------- Rutiny v teto casti monitoru produkuji listing aktualniho programu.U kazdeho radku je posouzeno cislo,jsou expandovany tokens a umisten aktualni programovy kurzor.Vstupni bod AUTO-LIST je pouzivan jak rutinou hlavni exekuce,tak edito- rem k vytvoreni jedne stranky listingu.Ukazatel zasobniku je uschovan,coz u- moznuje opetne nastaveni zasobnikove pameti po vykonani listingu (viz. PO-SCR, #0C55). 1795 LD (#5C3F),SP ;Uschovej ukazatel zasobniku LD (IY+2),#10 ;(TV-FLAG) Signal:Automaticky listing na hlav- CALL #0DAF ;ni obrazovce.Vycisti tuto cast obrazovky SET 0,(IY+1) ;(FLAGS) Prepni na editacni oblast LD B,(IY+49) ;(DF-SZ) Vycisti take dolni cast obrazovky CALL #0E44 RES 0,(IY+1) ;(FLAGS) Prepni zpet z editacni oblasti SET 0,(IY+48) ;(FLAGS2) Signal:obrazovka je cista LD HL,(#5C49) ;Vyzvedni cislo aktualniho radku a cislo "au- LD DE,(#5C6C) ;tomatickeho" radku AND A ;Jestlize cislo aktualniho radku je mensi nez SBC HL,DE ;cislo "automatickeho" radku,skoc ADD HL,DE JR C,#17E1 Je treba upravit "automaticke" cislo tak,aby se aktualni radek objevil na spodni casti hlavni obrazovky. PUSH DE ;Uschovej "automaticke" cislo.Najdi adresu CALL #196E ;zacatku aktualniho radku a vytvor adresu LD DE,#02C0 ;zhruba jednu "obrazovku" pred nim a vysledek EX DE,HL ;uschovej na zasobniku a vyzvedni cislo "auto- SBC HL,DE ;matickeho" radku.Adresa tohoto radku do HL EX (SP),HL CALL #196E POP BC ;Vysledek jde do BC Vstup do smycky.Pri kazdem pruchodu je zvyseno cislo "automatickeho" radku, dokud se aktualni radek neobjevi v listingu. 17CE PUSH BC ;Uschovej vysledek.Najdi adresu zacatku radku CALL #19B8 ;nasledujiciho za "automatickym" radkem (v DE) POP BC ;Vyzvedni vysledek ADD HL,BC ;Proved vypocet a skoc,je-li hotovo JR C,#17E4 EX DE,HL ;Preved adresu dalsiho radku do HL a vyzvedni LD D,(HL) ;jeho cislo do DE INC HL LD E,(HL) DEC HL LD (#5C6C),DE ;Nastav S-TOP a pokracuj s timto dalsim radkem JR #17CE MONITOR ROM - ZX Spectrum - 51 - RES 0,(IY+1) ;(FLAGS) Signal:uvodni mezera povolena LD A,D ;Vyzvedni kod kurzoru a pokud jej neni treba AND A ;tisknout,skoc JR Z,#1881 RST #10 ;Tiskni kurzor 187D SET 0,(IY+1) ;(FLAGS) Signal: uz zadna mezera 1881 PUSH DE ;Uschovej DE EX DE,HL ;Ukazatel do DE RES 2,(IY+48) ;(FLAGS2) Signal: ne v uvozovkach LD HL,#5C3B RES 2,(HL) ;Signal: tisk v modu "K" BIT 5,(IY+55) ;(FLAGX) Pokud nejsi v inputu,skoc JR Z,#1894 SET 2,(HL) ;Signal: tisk v modu "L" Zde je vstup do smycky,ktera tiskne vsechny znaky az do konce basickeho radku a v pripade potreby preskoci cisla v FP forme. 1894 LD HL,(#5C5F) ;Vyzvedni ukazatel syntakticke chyby AND A ;a v pripade,ze neni potreba tisknout chybovy SBC HL,DE ;znak,skoc JR NZ,#18A1 LD A,#3F ;Nyni tiskni chybovy znak CALL #18C1 ;Je to blikajici otaznik 18A1 CALL #18E1 ;Pripadny tisk kurzoru EX DE,HL ;Ukazatel do HL LD A,(HL) ;Vyzvedni znak.Jedna-li se o FP CALL #18B6 ;identifikacni bajt,nebude cislo vypsano INC HL ;Posun ukazatel pro dalsi pruchod CP #0D ;Je-li aktualni znak "CR",skoc JR Z,#18B4 EX DE,HL ;Ukazatel do DE CALL #1937 ;Tiskni znak JR #1894 ;Zpet do smycky 18B4 POP DE ;Radek byl vytisknut.Obnov DE a vrat se RET Podprogram CISLO ---------------- V pripade,ze v A je identifikacni bajt FP cisla,je ukazatal v HL posunut za posledni bajt FP formy. 18B6 CP #0E ;Nejedna-li se o identifikacni bajt FP cisla, RET NZ ;vrat se INC HL ;Inkrementuj HL o 6 mist INC HL INC HL INC HL INC HL INC HL LD A,(HL) ;Vyzvedni aktualni znak a vrat se RET Tisk blikajiciho znaku ---------------------- Tento podprogram se pouziva pro tisk chybovych a ostatnich blikajicich kurzoru. 18C1 EXX ;Uschovej soucasne registry LD HL,(#5C8F) ;Uschovej a ATTR-T a MASK-T na zasobniku PUSH HL RES 7,H ;Zajisti FLASH SET 7,L LD (#5C8F),HL ;Pouzij tyto upravene hodnoty pro ATTR-T LD HL,#5C91 ;a MASK-T.Uschovej P-FLAG na zasobniku LD D,(HL) PUSH DE LD (HL),#00 ;Zajisti INVERSE 0,OVER 0 a ne PAPER 9 CALL #09F4 ;a ne INK 9.Vytiskni znak POP HL ;Obnov P-FLAG,ATTR-T a MASK-T LD (IY+87),H POP HL LD (#5C8F),HL EXX ;Obnov registry a vrat se RET Podprogram TISK KURZORU ----------------------- Pri nevhodnem miste pro tisk kurzoru se provede navrat.Jinak bude vytisknut prislusny kurzor "C","E","G","K" nebo "L". 18E1 LD HL,(#5C3B) ;Vyzvedni adresu kurzoru a neni-li pozice AND A ;vhodna,vrat se SBC HL,DE RET NZ LD A,(#5C41) ;Je vyzvednuta aktualni hodnota MODE a zdvojena RLC A MONITOR ROM - ZX Spectrum - 53 - 1968 SET 2,(IY+1) ;(FLAGS) Signal: dalsi znak bude vytisknut 196C RST #10 ;v modu "L".Vlastni tisk znaku RET Poznamka: Je to prave toto poradi testu,ktere urcuje,v jakem modu ma byt vytisten nasledujici znak.Take si povsimnete,ze program neobsluhuje dvojtecky v radcich REM. Adresa radku ------------ Pro dane cislo radku v HL vraci tento podprogram pocatecni adresu tohoto nebo nasledujiciho radku v HL a v DE adresu predchoziho radku.Pokud hledane cislo radku existuje bude Z flag=1,avsak pri substituci cislem nasledujiciho radku bude Z flag=0. 196E PUSH HL ;Uschovej cislo radku LD HL,(#5C53) ;Vyzvedni hodnotu PROG a preved ji do DE LD D,H LD E,L Nyni vstup do smycky,ktera testuje cisla vsech programovych radku,dokud nenalezne shodne nebo vyssi cislo. 1974 POP BC ;Dane cislo radku CALL #1980 ;Porovnej cislo daneho radku s cislem adreso- RET NC ;vaneho radku a vrat se kdyz CY=0 PUSH BC ;Jinak adresuj cislo dalsiho radku CALL #19B8 EX DE,HL ;Zamen ukazatele a skoc zpet na posouzeni dal- JR #1974 ;siho programoveho radku Podprogram porovnani radku -------------------------- Cislo radku v BC se porovna s cislem radku jehoz adresa je v HL. 1980 LD A,(HL) ;Vyzvedni vyssi bajt adresovaneho cisla radku RET NZ ;a porovnej.Vrat se pokud se neshoduji INC HL LD A,(HL) DEC HL CP C ;Porovnej nizsi bajt a vrat se s CY=1, RET ;jestlize nebylo dosazeno hledane cislo Nalezeni jednotlivych prikazu ----------------------------- Tento podprogram plni dve rozlicne funkce: a) Muze byt pouzit k nalezeni "D teho" prikazu v basickem radku,kdy v HL bude adresa pred zacatkem tohoto prikazu a Z=1. b) Vyhleda adresu prikazu,jehoz token je v registru E.(Pokud prikaz existuje) 1988 INC HL ;Nevyuzito INC HL INC HL 198B LD (#5C5D),HL ;Nastav CH-ADD na aktualni bajt LD C,#00 ;Nastav signal: Uvozovky pryc Vstup do smycky,ktera zkouma kazdy prikaz v radku. 1990 DEC D ;Dekrementuj D a vrat se,jestlize byl nalezen RET Z ;pozadovany prikaz RST #20 ;Vyzvedni kod dalsiho znaku a pokud neodpovida CP E ;danemu token,skoc dopredu.V pripade shody JR NZ,#199A ;nuluj CY a vrat se tez s nulovym Z flag AND A RET Tato smycka posuzuje jednotlive znaky v radku,aby nalezla kde prikaz konci. 1998 INC HL ;Posun ukazatel a vyzvedni dalsi kod LD A,(HL) 199A CALL #18B6 ;Prekracuj vsechna cisla a obnovuj CH-ADD LD (#5C5D),HL CP #22 ;Jestlize znak neni uvozovka,skoc.Nastav JR NZ,#19A5 ;signal:"uvozovky ano" DEC C 19A5 CP #3A ;Jestlize znak je dvojtecka,skoc.Jestlize JR Z,#19AD ;znak neni token pro THEN,skoc CP #CB JR NZ,#19B1 19AD BIT 0,C ;Precti signal "uvozovky" a skoc zpet na konci JR Z,#1990 ;kazdeho prikazu(i po THEN) 19B1 CP #0D ;Pokud se nenachazis na konci radku,skoc zpet JR NZ,1998 DEC D ;Dekrementuj citac prikazu a nastav CY=1 SCF RET MONITOR ROM - ZX Spectrum - 55 - Tisk cisla radku nebo sdeleni ----------------------------- Vstupni bod OUT-NUM-1 vytiskne cislo prichazejici v BC.Vstupni bod OUT-NUM-2 vytiskne cislo neprimo adresovane HL a v tomto miste se vytisknou take potrebne mezery.V obou pripadech je limit pro bezchybne vytisteni 9999. 1A1B PUSH DE ;Uschovej tyto registry po cely prubeh PUSH HL ;podprogramem XOR A BIT 7,B ;Jedna-li se o sdeleni,skoc dopredu na tisk JR NZ,#1A42 ;nuly.Preved cislo do HL LD H,B LD L,C LD E,#FF ;Signal: Zadne uvodni mezery JR #1A30 ;Skok na tisk cisla 1A28 PUSH DE ;Uschova DE LD D,(HL) ;Cislo do DE INC HL LD E,(HL) PUSH HL ;Uschova zvyseneho HL EX DE,HL ;Cislo do HL LD E,#20 ;Signal: Potreba uvodnich mezer 1A30 LD BC,+#FC18 ;Integer HL.Toto je "1000" CALL #192A ;Tisk prvni cislice LD BC,+#FF9C ;Toto je "100" CALL #192A ;Tisk druhe cislice LD BC,+#F6 ;Toto je "10" CALL #192A ;Tisk treti cislice LD A,L ;Zbytek do A 1A42 CALL #15EF ;Tisk cisla POP HL ;Obnoveni registru POP DE RET INTERPRETACE PRIKAZU V BASICKEM RADKU ************************************* SYNTAKTICKE TABULKY ------------------- A) Tabulka doplnku V teto tabulce je doplnkova hodnota pro kazdy z padesati basickych prikazu. Token prikaz adresa Token prikaz adresa 1A48 DEFB #B1 DEF FN 1AF9 1A61 DEFB #94 BORDER 1AF5 1A49 DEFB #CB CAT 1B14 1A62 DEFB #56 CONTINUE 1AB8 1A4A DEFB #BC FORMAT 1B06 1A63 DEFB #3F DIM 1AA2 1A4B DEFB #BF MOVE 1B0A 1A64 DEFB #41 REM 1AA5 1A4C DEFB #C4 ERASE 1B10 1A65 DEFB #2B FOR 1A90 1A4D DEFB #AF OPEN # 1AFC 1A66 DEFB #17 GO TO 1A7D 1A4E DEFB #B4 CLOSE # 1B02 1A67 DEFB #1F GO SUB 1A86 1A4F DEFB #93 MERGE 1AE2 1A68 DEFB #37 INPUT 1A9F 1A50 DEFB #91 VERIFY 1AE1 1A69 DEFB #77 LOAD 1AE0 1A51 DEFB #92 BEEP 1AE3 1A6A DEFB #44 LIST 1AAE 1A52 DEFB #95 CIRCLE 1AE7 1A6B DEFB #0F LET 1A7A 1A53 DEFB #98 INK 1AEB 1A6C DEFB #59 PAUSE 1AC5 1A54 DEFB #98 PAPER 1AEC 1A6D DEFB #2B NEXT 1A98 1A55 DEFB #98 FLASH 1AED 1A6E DEFB #43 POKE 1AB1 1A56 DEFB #98 BRIGHT 1AEE 1A6F DEFB #2D PRINT 1A9C 1A57 DEFB #98 INVERSE 1AEF 1A70 DEFB #51 PLOT 1AC1 1A58 DEFB #98 OVER 1AF0 1A71 DEFB #3A RUN 1AAB 1A59 DEFB #98 OUT 1AF1 1A72 DEFB #6D SAVE 1ADF 1A5A DEFB #7F LPRINT 1AD9 1A73 DEFB #42 RANDOMIZE 1AB5 1A5B DEFB #81 LLIST 1ADC 1A74 DEFB #0D IF 1A81 1A5C DEFB #2E STOP 1ABA 1A75 DEFB #49 CLS 1ABE 1A5D DEFB #6C READ 1AC9 1A76 DEFB #5C DRAW 1AD2 1A5E DEFB #6E DATA 1ACC 1A77 DEFB #44 CLEAR 1ABB 1A5F DEFB #70 RESTORE 1ACF 1A78 DEFB #15 RETURN 1A8D 1A60 DEFB #48 NEW 1AA8 1A79 DEFB #5D COPY 1AD6 MONITOR ROM - ZX Spectrum - 57 - 1AE7 DEFB #09 ;P-CIRCLE CLASS-09 DEFB #05 ;CLASS-05 DEFB #20,#23 ;CIRCLE,#2320 1AEB DEFB #07 ;P-INK CLASS-07 1AEC DEFB #07 ;P-PAPER CLASS-07 1AED DEFB #07 ;P-FLASH CLASS-07 1AEE DEFB #07 ;P-BRIGHT CLASS-07 1AEF DEFB #07 ;P-INVERSE CLASS-07 1AF0 DEFB #07 ;P-OVER CLASS-07 1AF1 DEFB #08 ;P-OUT CLASS-08 DEFB #00 ;CLASS-00 DEFB #7A,#1E ;OUT,#1E7A 1AF5 DEFB #06 ;P-BORDER CLASS-06 DEFB #00 ;CLASS-00 DEFB #94,#22 ;BORDER,#2294 1AF9 DEFB #05 ;P-DEF-FN CLASS-05 DEFB #60,#1F ;DEF FN,#1F60 1AFC DEFB #06 ;P-OPEN CLASS-06 DEFB #2C ;carka DEFB #0A ;CLASS-0A DEFB #00 ;CLASS-00 DEFB #36,#17 ;OPEN,#1736 1B02 DEFB #06 ;P-CLOSE CLASS-06 DEFB #00 ;CLAAS-00 DEFB #E5,#16 ;CLOSE,#16E5 1B06 DEFB #0A ;P-FORMAT CLASS-0A DEFB #00 ;CLASS-00 DEFB #93,#17 ;CAT atd..#1793 1B0A DEFB #0A ;P-MOVE CLASS-0A DEFB #2C ;carka DEFB #0A ;CLASS-0A DEFB #00 ;CLASS-00 DEFB #93,#17 ;CAT atd..#1793 1B10 DEFB #0A ;P-ERASE CLASS-0A DEFB #00 ;CLASS-00 DEFB #93,#17 ;CAT atd..#1793 1B14 DEFB #00 ;P-CAT CLASS-00 DEFB #93,#17 ;CAT atd..#1793 Poznamka: Pozadavky ruznych trid jsou tyto: CLASS-00 - Bez dalsich operandu CLASS-01 - Pouzito pro LET.Vyzaduje se promenna CLASS-02 - Pouzito pro LET.Musi nasledovat numericky nebo retezcovy vyraz CLASS-03 - Muze nasledovat numericky vyraz CLASS-04 - Musi nasledovat jednoznakova promenna CLASS-05 - Muze nasledovat soubor polozek CLASS-06 - Musi nasledovat numericky vyraz CLASS-07 - Pro obsluhu barevnych polozek CLASS-08 - Musi nasledovat dva numericke vyrazy,oddelene carkou CLASS-09 - Jako 08,ale mohou predchazet barevne polozky CLASS-0A - Musi nasledovat retezcovy vyraz CLASS-0B - Obsluha kazetoveho magnetofonu Hlavni 'VETNY ROZBOR' v basickem prekladaci ------------------------------------------- Do teto rutiny se vstupuje v bode LINE-SCAN pri kontrole syntaxe a v bode LINE-RUN (#1B8A),jestlize ma byt proveden basicky program,nebo jeden ci vice basickych prikazu.Kazdy prikaz je posuzovan postupne a systemova promenna CH-ADD je pouzita jako ukazatel na jednotlive kody prikazu,tak jak se vysky- tuji v programove,nebo editacni oblasti. 1B17 RES 7,(IY+1) ;(FLAGS) Signal:kontrola syntaxe CALL #19FB ;CH-ADD je nastavena na prvni znak za jakym- XOR A ;kolivcislem radku.Promenna SUBPPC je LD (#5C47),A ;nastavena na #00 DEC A LD (#5C3A),A ;a ERR-NR na #FF JR #1B29 ;Skoc dopredu na posouzeni 1.prikazu v radku Prikazova smycka ---------------- Jsou posouzeny vsechny prikazy,dokud neni dosazeno konce radku. 1B28 RST #20 ;Posun CH-ADD po radku 1B29 CALL #16BF ;Pracovni prostor je vycisten INC (IY+13) ;Pri kazdem pruchodu smyckou je inkrementovana JP M,#1C8A ;SUBPPC.Ale v jednom radku je povoleno pouze RST #18 ;127 prikazu.Vyzvedni znak a vycisti registr LD B,#00 ;pro pozdejsi pouziti CP #0D ;Je to CR? JR Z,#1BB3 ;Skoc,je-li tomu tak CP #3A ;Jestlize je to ":", JR Z,#1B28 ;Vrat se zpatky do smycky MONITOR ROM - ZX Spectrum - 59 - Podprogram LINE-NEW ------------------- V podprogramu byl proveden skok a pocatecni adresa noveho radku musi byt nalezena. 1B9E CALL #196E ;Je nalezena adresa nasledujiciho radku LD A,(#5C44) ;Vyzvedni cislo prikazu JR Z,#1BBF ;Skoc,byl-li zadany radek nalezen,jinak AND A ;zkontroluj platnost prikazoveho cisla JR NZ,#1BEC ;Musi to byt nula LD B,A ;Take zkontroluj,jestli "nasledujici radek uz LD A,(HL) ;neni za skutecnym "koncem" programu AND #C0 LD A,B JR Z,#1BBF ;Skoc s platnymi adresami,nebo ohlas: 1BB0 RST #08 ;0 - OK DEFB #FF Poznamka: toto neni chyba v normalnim smyslu chapani,ale pouze skok za konec programu. Rutina prikazu REM ------------------ Navratova adresa do STMT-RET je odhozena,cimz je program donucen ignorovat zbytek radku. 1BB2 POP BC ;Odhod adresu STMT-RET Rutina 'KONEC RADKU' -------------------- Pri kontrole syntaxe se provede jednoduchy navrat,ale pokud je program v behu, musi byt zkontrolovana adresa na NXTLIN,nez bude pouzita. 1BB3 CALL #2530 ;Pri kontrole syntaxe se vrat,jinak vyzvedni RET Z LD HL,(#5C55) ;adresu na NXTLIN a je-li tato adresa LD A,#C0 ;za koncem programu,vrat se take,cimz je AND (HL) ;prikaz RUN take vykonan RET NZ XOR A ;Signal: prikaz cislo 0,nez postoupis dale Rutina POUZITI RADKU -------------------- Tato kratka rutina ma tri funkce: a) zmeni prikaz "0" na "1" b) najde cislo noveho radku a vlozi ho do systemove promenne PPC c) vytvari adresu zacatku nasledujiciho radku 1BBF CP #01 ;Z prikazu "0" se stava prikaz "1" ADC A,#00 LD D,(HL) ;Cislo aktualniho radku je vyzvednuto INC HL LD E,(HL) LD (#5C45),DE ;a predano do PPC INC HL ;Nyni je nalezena delka radku LD E,(HL) INC HL LD D,(HL) EX DE,HL ;Zamena obou hodnot a vytvoreni adresy zacatku ADD HL,DE ;dalsiho radku v HL.Pozice pred prvnim znakem INC HL ;dalsiho radku je v DE Rutina DALSI RADEK ------------------ Na vstupu ukazuje HL za posledni misto "dalsiho" radku a DE ukazuje na misto pred prvnim bajtem tohoto radku.To se tyka radku,ktere jsou v programove oblasti a take radku v editacni oblasti,kdy "dalsi radek" je ten samy radek a zbyvaji zde jeste prikazy,ktere je nutno prelozit. 1BD1 LD (#5C55),HL ;Nastav NXTLIN pro pouziti,jakmile byl aktualni EX DE,HL ;radek dokoncen.CH-ADD ukazuje jako obvykle LD (#5C5D),HL ;na pozici pred znakem,ktery ma byt posouzen LD D,A ;Cislo prikazu je vyzvednuto,registr E LD E,#00 ;je vycisten v pripade,ze se pouziva EACH-STMT LD (IY+10),#FF ;(NSPPC) Signal: zadny skok DEC D ;Cislo prikazu minus jedna jde do SUBPPC LD (IY+13),D JP Z,#1B28 ;Nyni muze byt posouzen prvni prikaz.Nicmene INC D ;pro dalsi prikazy musi byt nalezena pocatecni CALL #198B ;adresa.V pripade,ze prikaz existuje,skoc, JR Z,#1BF4 ;jinak ohlas: N - Statement lost 1BEC RST #08 DEFB #16 MONITOR ROM - ZX Spectrum - 61 - Pokracuj, jestlize obsluhujes existujici promennou. 1C30 CALL Z,#2996 ;Parametry retezcu a poli jsou predany BIT 6,(IY+1) ;(FLAGS) na kalkulatorovy zasobnik.STK-VARS JR NZ,#1C46 ;odkroji konec retezce(je-li to treba).Skoc, XOR A ;obsluhujes-li ciselnou promennou.Vynuluj A CALL #2530 ;Parametry retezce nebo retezcoveho pole jsou CALL NZ,#2BF1 ;vyzvednuty v pripade ze se nekontroluje LD HL,#5C71 ;syntaxe.Bit 0 je nastaven pouze v pripade, OR (HL) ;kdy se jedna o uplny jednoduchy retezec,cimz LD (HL),A ;se signalizuje: Smazat starou kopii EX DE,HL ;HL nyni ukazuje na retezec nebo cast pole Takze cesty programu se zde opet setkavaji,aby STRLEN a DEST byly nastaveny na pozadovane hodnoty.Pro vsechny numericke promenne a retezce a retezcova pole obsahuje STRLEN-LO znak nazvu promenne.Ale pro stare retezce a retezcova pole,at uz jsou uriznuty nebo kompletni,obsahuje tato systemova promenna delku prideleni. 1C46 LD (#5C72),BC ;Nastav STRLEN na pozadovanou hodnotu DEST obsahuje "cilovou" adresu "stare" promenne,ale zaroven i "zdrojovou" adresu "nove" promenne. LD (#5C4D),HL ;Nastav DEST na pozadovanou hodnotu a vrat se RET Prikazy tridy 02 jsou doplneny aktualnim vypoctem hodnoty,ktera je pridelena v prikazu LET. 1C4E POP BC ;Adresa SCAN-LOOP je odhozena.Je provedeno CALL #1C56 ;prideleni.Presun na dalsi prikaz,bud pres CALL #1BEE ;CHECK-END pri kontrole syntaxe,nebo pres RET ;STMT-RET pri programovem behu Subrutina "VYZVEDNI HODNOTU" ---------------------------- Tento podprogram se vyuziva pro LET,READ a INPUT aby ohodnotil a pridelil hodnoty deklarovanym promennym.Vstupni bod VAL-FET-1 (#1C56) je pouzivan prikazy LET a READ a posuzuje FLAGS,zatimco vstupni bod VAL-FET-2 (1C59) je vyuzivan prikazem INPUT a posuzuje FLAGX. 1C56 LD A,(#5C3B) ;Pouzij FLAGS 1C59 PUSH AF ;Uschovej FLAGS nebo FLAGX CALL #24FB ;Proved hodnoceni dalsiho prikazu POP AF ;Vyzvedni starou hodnotu FLAGS nebo FLAGX LD D,(IY+1) ;Vyzvedni novou hodnotu FLAGS XOR D ;Typ promenne numericke nebo retezcove se musi ADD #40 ;shodovat s typem vyrazu JR NZ,#1C8A ;Neni-li tomu tak,vypis hlaseni C BIT 7,D ;Pokud nekontrolujes JP NZ,#2AFF ;syntaxi,skoc dopredu k provedeni vlastniho RET ;prideleni.Jinak se vrat Prikazy tridy 04 ---------------- Tento vstupni bod se pouziva pro prikazy FOR a NEXT. 1C6C CALL #28B2 ;Zjisti zda je tato promenna pouzivan PUSH AF ;Uschovej AF zatimco budes testovat LD A,C ;diskriminacni bajt OR #9F INC A JR NZ,#1C8A ;Over si take,ze se jedna o smycku FOR NEXT POP AF ;Obnov podminkovy registr a skoc zpet,abys JR #1C22 ;zajistil ze nalezena promenna bude pridelena Subrutina "OCEKAVEJ CISELNY NEBO RETEZCOVY VYRAZ" ------------------------------------------------- Toto jsou sledy kratkych subrutin,ktere jsou vyuzivany k vyzvednuti vysledku dalsiho ohodnoceneho vyrazu.Vysledek jednoducheho vyrazu je vracen jako posledni hodnota na zasobniku kalkulatoru.Vstupni bod NEXT-2NUM se pouziva, kdyz je potreba upravit CH-ADD tak,aby ukazovala na zacatek prvniho vyrazu. 1C79 RST #20 ;Posun CH-ADD Vstupni bod EXPT-2NUM (odpovida tride 8) umoznuje dvema ciselnym vyrazum oddelenym carkou,aby byly ohodnoceny. 1C7A CALL #1C82 ;Ohodnot oba vyrazy po sobe CP #2C ;Neni-li separator carka,ohlas chybu JR NZ,#1C8A RST #20 ;Posun CH-ADD Vstupni bod EXPT-1NUM (odpovida tride 06) umoznuje ohodnoceni jednoducheho ciselneho vyrazu. MONITOR ROM - ZX Spectrum - 63 - PRIKAZOVE RUTINY **************** Tato sekce 16K monitoroveho programu od adresy #1CEE az do #23FA obsahuje vetsinu prikazovych programu pro basicky prekladac. Prikaz "STOP" ------------- Rutina prikazu STOP obsahuje pouze rutinu chyboveho hlaseni. 1CEE RST #08 ;Ohlas: 9 - Stop statement DEFB #08 Prikaz "IF" ----------- Hodnota vyrazu mezi IF a THEN se stane "posledni hodnotou" na kalkulatorovem zasobniku.Je-li logicky pravdiva,bude se posuzovat dalsi vyraz a v ostatatnich pripadech je radek povazovan za skonceny. 1CF0 POP BC ;Odhod navratovou adresu STMT-RET CALL #2530 ;Pri kontrole syntaxe skoc JR Z,#1D00 Nyni pouzij kalkulator k vymazani posledni polozky na zasobniku kalkulatoru, ale nech DE,aby adresoval prvni bajt teto hodnoty. RST #28 ;Pouzij kalkulator DEFB #02 ;vymaz Posledni hodnota je vymazana DEFB #38 ;konec vypoctu EX DE,HL ;HL ukazuje na prvni bajt a je zavolan CALL #34E9 ;TEST-ZERO.Byla-li hodnota "nepravda",skoc JP C,#1BB3 ;na dalsi radek,ale byla-li pravda,skoc 1D00 JP 1B29 ;na dalsi prikaz po THEN Prikaz "FOR" ------------ Tato prikazova rutina vytvari hodnoty VALUE a LIMIT,ulozene jsou na zasobniku kalkulatoru. 1D03 CP #CD ;Pokud neni udan STEP,skoc JR NZ,#1D10 RST #20 ;Posun CH-ADD a vyzvedni hodnotu pro STEP CALL #1C82 CALL #1BEE ;Pri kontrole syntaxe se posun na dalsi JR #1D16 ;prikaz,jinak skoc dopredu Pokud neni zadana hodnota STEP,pouzij hodnotu "1". 1D10 CALL #1BEE ;Presun se na dalsi prikaz,jestlize kontrolujes RST #28 ;syntaxi,jinak pouzij kalkulator a uloz hodnotu DEFB #A1 ;STK-JEDNA "1" na jeho zasobnik DEFB #38 ;konec vypoctu Tri hodnoty na zasobniku kalkulatoru jsou to VALUE (v),LIMIT (l) a STEP (s). Tyto hodnoty budou nyni posouzeny. 1D16 RST #28 ;v,l,s DEFB #C0 ;ST-MEM-0 v,l,s (pamet c.0 = s) DEFB #02 ;vymaz v,l DEFB #01 ;zamena l,v DEFB #E0 ;GET-MEM-0 l,v,s DEFB #01 ;zamena l,s,v DEFB #38 ;konec vypoctu Promenna FOR je nyni vytvorena a povazovana za prechodnou oblast kalkulatorove pameti. CALL #2AFF ;Promenna je nalezena nebo vytvorena LD (#5C68),HL ;(ma hodnotu v ),udelej z ni pametovou oblast Zjistena promenna muze byt pouze jednoducha ciselna promenna pouzivajici pouze sest mist a nyni pro ni bude vytvoren prostor. DEC HL ;Vyzvedni jednopismenny nazev promenne LD A,(HL) SET 7,(HL) ;Zajisti,ze BIT 7 v nazvu je nastaven LD BC,#0006 ;Bude treba sest mist ADD HL,BC ;HL necht ukazuje za ne RLCA ;Rotuj nazev a skoc,byla-li to jiz promenna JR C,#1D34 ;FOR.V opacnem pripade vytvor dalsich 13 mist LD C,#0D CALL #1655 INC HL ;HL ukazuje opet za pozici LIMIT MONITOR ROM - ZX Spectrum - 65 - INC HL ;Pak je vyzvednuta jeho delka LD B,(HL) PUSH HL ;Ukazatel je uschovan,zatimco adresa konce ADD HL,BC ;radku je vytvorena v BC LD B,H LD C,L POP HL ;Ukazatel je obnoven LD D,#00 ;Nastav pocitadlo prikazu na nulu 1DA3 PUSH BC ;Ukazatel na konec radku je uschovan,zatimco CALL #198B ;jsou prozkoumany prikazy v radku POP BC RET NC ;Vrat se nebyl-li zde zadny vyskyt,jinak JR #1D8B ;posuzuj dalsi radek Prikaz "NEXT" ------------- Promenna "v prideleni" jiz byla stanovena (viz TRIDA 04,#1C6C) a zbyva zmenit jeji hodnotu,jak je pozadovano. 1DAB BIT 1,(IY+55) ;(FLAGX) Nebyla-li promenna nalezena,ohlas JP NZ,#1C2E ;chybu.Adresa promenne je vyzvednuta a jeji LD HL,(#5C4D) ;nazev je dale testovan BIT 7,(HL) JR Z,#1DD8 VALUE (hodnota) a STEP (krok) jsou upravovany pomoci kalkulatoru. INC HL ;Prekroc jmeno a vytvor z promenne prechodnou LD (#5C68),HL ;"pametovou oblast" RST #28 DEFB #E0 ;GET-MEM-0 v DEFB #E2 ;GET-MEM-2 v,s DEFB #0F ;scitani v+s DEFB #C0 ;ST-MEM-0 v+s DEFB #02 ;vymaz DEFB #38 ;konec vypoctu Vysledek secteni hodnot VALUE + STEP je nyni porovnavan s hodnotou LIMIT volanim podprogramu NEXT-LOOP CALL #1DDA ;Testuj novou hodnotu VALUE proti hodnote RET C ;LIMIT.Byla-li smycka FOR-NEXT jiz dokoncena, LD HL,(5C68) ;vrat se.Jinak vyzvedni "cislo smyckovaciho LD DE,#000F ;radku a prikazu".Nalezni adresu nizsiho bajtu ADD HL,DE ;cisla "smyckovaciho radku".Nyni toto cislo LD E,(HL) ;vyzvedni.Vyzvedni take cislo prikazu INC HL LD D,(HL) INC HL LD H,(HL) EX DE,HL ;Zamen cisla pred skokem dopredu,kde budou JP #1E73 ;zpracovana jako hodnoty pro GO TO 1DD8 RST #08 ;Ohlas: 1 - NEXT without FOR DEFB #00 Subrutina "NEXT-LOOP" --------------------- Tato subrutina testuje,byl-li prekrocen LIMIT hodnotou VALUE.Musi se prihlednout ke znamenku hodnoty STEP.Tato subrutina nastavi CY flag na hodnotu 1,byl-li LIMIT prekrocen. 1DDA RST #28 DEFB #E1 ;GET-MEM-1 l DEFB #E0 ;GET-MEM-0 l,v DEFB #E2 ;GET-MEM-2 l,v,s DEFB #36 ;<0 l,v,(1 nebo 0) DEFB #00 ;skok-pravda l,v,(1 nebo 0) DEFB #02 ;na NEXT-1 l,v,(1 nebo 0) DEFB #01 ;zamena v,l 1DE2 DEFB #03 ;odecitani v-l nebo l-v DEFB #37 ;>0 (1 nebo 0) DEFB #00 ;skok-pravda (1 nebo 0) DEFB #04 ;na NEXT-2 DEFB #38 ;konec vypoctu AND A ;Vycisti CY flag a vrat se-smycka je mozna RET Ovsem,neni-li mozne smycku provest,nastav CY flag. 1DE9 DEFB #38 ;konec vypoctu - SCF ;Nastav CY flag a vrat se RET MONITOR ROM - ZX Spectrum - 67 - Rutina prikazu CONTINUE ----------------------- Prislusna cisla radku a prikazu se stanou predmetem skoku. 1E5F LD HL,(#5C6E) ;Cislo radku LD D,(IY+54) ;(OSPCC) Cislo prikazu JR #1E73 Rutina prikazu GO TO -------------------- Operandem musi byt cislo radku v rozsahu 1 az 9999. Ale vzhledem k "obracene" logice cislovani se testuje na cislo 61439. 1E67 CALL #1E99 ;Vyzvedni operand a preved jej do HL LD H,B LD L,C LD D,#00 ;Nastav cislo prikazu na nulu.Jestlize hodnota LD A,H ;presahuje 61439,skoc na chybove hlaseni CP #F0 JR NC,#1E9F Vstupni bod GO-TO-2 se pouziva v cetnych pripadech pri urcovani cisla nasledujiciho radku. 1E73 LD (#5C42),HL ;Vloz cislo radku a cislo prikazu LD (IY+10),D ;(NSPPC) RET Rutina prikazu OUT ------------------ Oba parametry jsou vyzvednuty ze zasobniku kalkulatoru a vyslany. 1E7A CALL #1E85 ;Vyzvedni operandy OUT (C),A ;Skutecna instrukce OUT RET Rutina prikazu POKE ------------------- Poke se provede obdobne. 1E80 CALL #1E85 ;Vyzvedni operandy LD (BC),A ;Skutecna instrukce POKE RET Rutina TWO-PARAM ---------------- Prvni parametr na zasobniku kalkulatoru musi byt kompresovatelny do jednodu- cheho registru a je-li zaporny,bude komplementovan.Druhy parametr na zasobniku kalkulatoru musi byt kompresovatelny do registroveho paru. 1E85 CALL #2DD5 ;Vyzvedni parametr a skoc na chybu,je-li JR C,#1E9F ;prilis vysoky.Skoc dopredu s kladnymi cisly, JR Z,#1E8E ;ale komplementuj zaporna cisla NEG 1E8E PUSH AF ;Uschovej prvni parametr a vyzvedni druhy CALL #1E99 ;Vyzvedni prvni parametr POP AF RET Podprogramy nalezeni integru ---------------------------- "Posledni hodnota" na zasobniku kalkulatoru je vyzvednuta a kompresovana do jednoducheho registru nebo registroveho paru. 1E94 CALL #2DD5 ;Vyzvedni hodnotu do A a skoc JR #1E9C 1E99 CALL #2DA2 ;Vyzvedni hodnotu do BC a v obou pripadech skoc 1E9C JR C,#1E9F ;na chybu,je-li CY=1.Vrat se s pozitivnimi RET Z ;cisly ktera jsou v rozsahu 1E9F RST #08 ;Ohlas: Integer out of range DEFB #0A Rutina prikazu RUN ------------------ Parametry prikazu RUN jsou predany do NEWPPC volanim prikazove rutiny GO TO. Pred navratem se provede RESTORE 0 a CLEAR 0. 1EA1 CALL #1E67 ;Nastav NEWPPC na hodnotu operandu LD BC,#0000 CALL #1E45 ;Proved RESTORE 0 JR #1EAF ;Vystup pres prikaz CLEAR MONITOR ROM - ZX Spectrum - 69 - Zjisteni volne pameti --------------------- SPECTRUM sice nema basicky prikaz "FRE",ale protoze zde existuje tato rutina, lze velikost volne pameti zjistit pouzitim prikazu: PRINT 65536-USR 7962 1F1A LD BC,#0000 ;Nepovoluje se "nic navic".Vlastni test CALL #1F05 LD B,H ;Prevedeni do BC LD C,L RET Rutina prikazu RETURN --------------------- Ze zasobniku GO SUB se vyzvedne cislo radku a prikazu. 1F23 POP BC ;Vyzvedni adresu STMT-RET a "chybovou adresu" POP HL POP DE ;Vyzvedni posledni polozku ze zasobniku GO SUB LD A,D ;Testuj,jestli se jedna o koncovy znak CP #3E ;zasobniku GO SUB a v tom pripade skoc JR Z,#1F36 ;do rutiny chybovych hlaseni.Cely udaj DEC SP ;potrebuje tri bajty EX (SP),HL ;Zamen cislo prikazu za "chybovou adresu" EX DE,HL ;a preved do DE LD (#5C3D),SP ;Nastav chybovy ukazatel PUSH BC ;Vrat adresu STMT-RET na zasobnik JP #1E73 ;Skoc na zmenu NEWPPC a NSPPC 1F36 PUSH DE ;Vloz koncovy znak a chybovou adresu PUSH HL RST #08 ;Ohlas: RETURN without GO SUB DEFB #06 Rutina prikazu PAUSE -------------------- Trvani pauzy je dano citanim maskovanych preruseni,ke kterym dochazi kazdou 1/50 tinu sekundy.PAUSE je ukonceno bud po nacteni prislusneho poctu preruseni nebo pri stisku nektere klavesy. 1F3A CALL #1E99 ;Vyzvedni operand.Cekej na maskovane preruseni 1F3D HALT DEC BC ;Dekrementuj citac LD A,B ;Je-li nulovy,prikaz PAUSE konci OR C JR Z,#1F4F LD A,B ;Jestlize byl operand 0,BC bude obsahovat AND C ;#FFFF a tato je opet upravena na 0 INC A JR NZ,1F49 ;Skok se vsemi otatnimi hodnotami INC BC 1F49 BIT 5,(IY+1) ;(FLAGS) Nebyla-li stistena zadna klavesa,skoc JR Z,#1F3D 1F4F RES 5,(IY+1) ;(FLAGS) Signal: zadna klavesa RET ;Navrat do STMT-RET Podprogram BREAK ---------------- Podprogram zjisti stisteni klavesy BREAK,coz signalizuje CY=0. 1F54 LD A,#7F ;Vytvor adresu portu #7FFE a nacti bajt IN A,(#FE) RRA ;Testuj pouze bit 0,jeho rotaci do CY RET C ;Vrat se,pokud klavesa BREAK nebyla stistena LD A,#FE ;Vytvor adresu portu #FEFE a nacti bajt IN A,#(#FE) RRA ;Testuj pouze bit 0,jeho rotaci do CY.Vrat se RET ;s CY=0,pokud doslo k soucasnemu stisteni Rutina prikazu DEF FN --------------------- Pri kontrole syntaxe se testuje,zdali ma prikaz spravnou formu. Take se vytvori prostor pro vysledek ohodnoceni funkce.Ale pokud je program v behu, tento prikaz se vynecha. 1F60 CALL #2530 ;Pri kontrole syntaxe skok dopredu JR Z,#1F6A LD A,#CE ;Jinak vynechani prikazu JP #1E39 Nejdrive se posuzuje promenna teto funkce. 1F6A SET 6,(IY+1) ;(FLAGS) Signal:ciselna promenna CALL #2C8D ;Je aktualni znak v registru A pismeno? JR NC,#1F89 ;Skoc dopredu,jestlize ne RST #20 ;Vyzvedni dalsi znak CP #24 ;Nejedna-li se o $, JR NZ,#1F7D ;skoc RES 6,(IY+1) ;(FLAGS) Zmen bit 6,protoze se jedna o retez- RST #20 ;covou promennou.Vyzvedni dalsi znak MONITOR ROM - ZX Spectrum - 71 - Podprogram "CR - NAVRAT VOZIKU" ------------------------------- 1FF5 CALL #1FC3 ;Vrat se pri kontrole syntaxe LD A,#0D ;Proved CR RST #10 RET Podprogram tisku polozek ------------------------ Rutina je volana z programu PRINT,LPRINT & INPUT. 1FFC RST #18 ;Vyzvedni prvni znak CP #AC ;Pokud to neni token AT,skoc JR NZ,#200E CALL #1C79 ;Predej dva parametry na zasobnik kalkulatoru CALL #1FC3 ;Navrat pri kontrole syntaxe.Parametry do BC CALL #2307 LD A,#16 ;Ridici znak AD do registru A a skok JR #201E ;na provedeni 200E CP #AD ;Pokud to neni token AT,skoc JR NZ,#2024 RST #20 ;Vyzvedni dalsi znak CALL #1C82 ;Predej jeden parametr na zasobnik kalkulatoru CALL #1FC3 ;Navrat pri kontrole syntaxe.Parametr do BC CALL #1E99 LD A,#17 ;Ridici znak do registru A AT a TAB se provedou tremi volanimi PRINT OUT. 201E RST #10 ;Tiskni ridici znak LD A,C ;Nasleduje hodnota prvniho parametru RST #10 LD A,B ;A hodnota druheho parametru RST #10 RET Dale posuzuj "implantovane informace" o barvach. 2024 CALL #21F2 ;Pokud je takova informace obsazena RET NC ;Vrat se CY=0. CALL #2070 ;Posuzuj,ma-li byt zmenen proud RET NC ;Pokracuj,pokud ne Tiskova informace musi byt ciselny nebo retezcovy vyraz. CALL #24FB ;Proved hodnoceni vyrazu,ale vrat se pokud CALL #1FC3 ;provadis kontrolu syntaxe BIT 6,(YI+1) ;(FLAGS) Test typu vyrazu CALL Z,#2BF1 ;Je-li to retezec,vyzvedni potrebne parametry JP NZ,#2DE3 ;Je-li to cislo,vystup pres PRINT-FP Nasledujici smycka zpracuje postupne vsechny znaky retezce. 203C LD A,B ;Pokud jsou vsechny znaky vypsany,vrat se OR C DEC BC RET Z LD A,(DE) ;Vyzvedni kod a posun ukazatel INC DE RST #10 ;Tiskni znak JR #203C ;a skoc na dalsi posouzeni Podprogram "KONEC TISKU" ------------------------ Z flag=1,neni-li co tisknout 2045 CP #29 ;Je-li znak zavorka,vrat se RET Z 2048 CP #0D ;Je-li znak "CR",vrat se RET Z CP #3A ;Pred navratem testuj znak dvojtecky RET Podprogram "TISK POZICE" ------------------------ Podprogram zpracovava znaky a ridici tiskovou pozici. 204E RST #18 ;Vyzvedni aktualni znak CP #3B ;Je-li to strednik,skoc JR Z,#2067 CP #2C ;Je-li to carka,skoc JR NZ,#2061 CALL #2530 ;Ale pri kontrole syntaxe znak netiskni JR Z,#2067 LD A,#06 ;Dej do A znak carky vytiskni ji RST #10 JR #2067 ;skoc dopredu MONITOR ROM - ZX Spectrum - 73 - 20FA CALL #2530 ;Jestli-ze kontrolujes syntaxi,skoc JP Z,#21B2 CALL #16BF ;Pracovni prostor je nastaven na nulu LD HL,#5C71 ;Toto je adresa FLAGX RES 6,(HL) ;Signal:retezcovy vysledek.Signal:INPUT mode SET 5,(HL) LD BC,#0001 ;Naznak zabere jedno misto BIT 7,(HL) JR NZ,#211C ;Pri pouziti LINE skoc LD A,(#5C3B) ;Ocekavas-li ciselny vstup,skoc AND #40 JR NZ,#211A LD C,#03 ;Retezcovy naznak zabere tri mista 211A OR (HL) ;Pro ciselnou polozku bude nastaven bit 6 FLAGX LD (HL),A ;Je vytvoren pozadovany prostor 211C RST #30 ;Znak CR na posledni misto LD (HL),#0D LD A,C ;Testovanim bitu 6 registru C se zjisti, RRCA ;bylo-li vytvoreno pouze jedno misto RRCA ;a v tom pripade skok JR NC,#2129 LD A,#22 ;Znak uvozovek prijde na prvni a druhe misto LD (DE),A DEC HL LD (HL),A 2129 LD (#5C5B),H ;Uschovej pozici kurzoru V pripade INPUT LINE muze byt editor volan bez dalsi pripravy,ale pro ostatni typy INPUTu musi byt pozmenen chybovy zasobnik,aby zachytaval pripadne chyby. BIT 7,(IY+55) ;(FLAGX) Pokud jde o INPUT LINE,skoc JR NZ,#215E LD HL,(#5C5D) ;Uschovej aktualni hodnotu CH-ADD na zasobniku PUSH HL LD HL,(#5C3D) ;Uschovej aktualni hodnotu ERR-SP na zasobniku PUSH HL 213A LD HL,#213A ;Toto bude bod navratu v pripade vyskytu chyby PUSH HL BIT 4,(IY+48) ;(FLAGS2) Pokud pouzivas kanal K,skoc JR Z,#2148 LD (#5C3D),SP ;Nastav ukazatel chyby 2148 LD HL,(#5C61) ;Nastav HL na zacatek radku INPUT a odstran CALL #11A7 ;FP formy LD (IY+0),#FF ;(ERR-NR) Signal:zatim zadna chyba.Nyni vezmi CALL #0F2C ;INPUT a nastav signal (FLAGS):kontrola syntaxe RES 7,(IY+1) CALL #21B9 ;Testuj INPUT na chyby a skoc, JR #2161 ;je-li vse v poradku 215E CALL #0F2C ;Vem LINE Vsechny systemove promenne musi byt nastaveny,nez se provede skutecne prideleni hodnoty. 2161 LD (IY+34),#00 ;Adresa kurzoru je resetovana.Pokud se pouziva CALL #21D6 ;jiny kanal nez K,provede se skok JR NZ,#2174 CALL #111D ;Inputovy radek je vypsan na obrazovku LD BC,(#5C82) ;a pozice z ECHO-E se stane aktualni tiskovou CALL #0DD9 ;pozici v dolni casti obrazovky 2174 LD HL,#5C71 ;Toto je adresa FLAGX RES 5,(HL) ;Signal: edit mode BIT 7,(HL) ;Pokud se jedna o INPUT LINE,skoc RES 7,(HL) JR NZ,#219B POP HL ;Zahod adresu IN-VAR-1 ??? POP HL ;Vyzvedni a obnov puvodni adresu pro ERR-SP LD (#5C3D),HL POP HL ;Vyzvedni puvodni adresu CH-ADD a uschovej ji LD (#5C5F),HL ;v X-PTR SET 7,(IY+1) ;(FLAGS) Signal:beh programu CALL #21B9 ;Proved prideleni LD HL,(#5C5F) ;Puvodni adresa CH-ADD do HL LD (IY+38),#00 ;Vynulovani X-PTR-HI a obnoveni CH-ADD LD (#5C5D),HL JR #21B2 ;Skok na posouzeni pripadnych dalsich polozek 219B LD HL,(#5C63) ;Konec line do HL LD DE,(#5C61) ;Zacatek line do DE SCF SBC HL,DE ;Vypocet delky a prevod do BC LD B,H LD C,L CALL #2AB2 ;Tyto parametry jdou na zasobnik a provede se CALL #2AFF ;prideleni JR #21B2 ;Skok na posouzeni pripadnych dalsich polozek MONITOR ROM - ZX Spectrum - 75 - b) Barevne systemove promenne jsou upraveny na pozadovane hodnoty.Podprogram je volan z rutiny PRINT-OUT.Na vstupu je kod ridiciho znaku v registru A a jeho parametr v registr D.Vsechny zmeny jsou pouze "prechodne". 2211 SUB #11 ;Snizuj rozsah a skoc dopredu pri INK & PAPER ADC A,#00 JR Z,#2234 SUB #02 ;Jeste snizuj rozsah a skoc dopredu pri ADC A,#00 ;FLASH & BRIGHT JR Z,#2273 Kode ridiciho znaku je nyni #01 pro INVERSE a #02 pro OVER. Podle toho bude nastavena systemova promenna P-FLAG. CP #01 ;Priprava na skok pro OVER LD A,D ;Vyzvedni parametr LD B,#01 ;Priprav masku pro OVER JR NZ,#2228 ;Skoc jde-li o OVER RLCA ;Pro INVERSE 0 musi byt bit 2 registru A RLCA ;nastaven na nulu.Pro INVERSE 1 musi byt LD B,#04 ;bit 2 registru A nastaven na jednicku.Maska ;ma bit 2 nastaven na jednicku 2228 LD C,A ;Uschovej obsah A LD A,D ;Povoleny rozsah parametru je pouze #00 az #01 CP #02 JR NC#2244 ;Skok na chybu,je-li mimo rozsah LD A,C ;Vyzvedni zpet A LD HL,#5C91 ;Adresa promenne P-FLAG,ktera se bude menit JR #226C ;Vystup pres CO-CHANGE se zmenou P-FLAG maskou ;v registru B.V teto casti se zpracuje PAPER 2234 LD A,D ;a INK.Na vstupu je CY=1 pro INK.Vyzvedni LD B,#07 ;parametr.Priprav masku pro INK JR C,#223E ;Skoc dopredu s INK RLCA ;Vynasob parametr osmi RLCA RLCA LD B,#38 ;Priprav masku pro PAPER 223E LD C,A ;Uschovej parametr v C LD A,D ;Povoleny rozsah parametru CP #0A ;je pouze #00 az #09 JR C,#2246 ;Skoc,je-li rozsah dodrzen 2244 RST #08 ;Ohlas: Invalid colour DEFB #13 2246 LD HL,#5C8F ;Pokracuj zpracovanim PAPER & INK.Priprava CP #08 ;na zmenu ATTR-T,MASK-T a P-FLAG.Skoc dopredu JR C,#2258 ;s PAPER/INK 0 az 9 LD A,(HL) ;Vyzvedni i hodnotu ATTR-T a pokud je JR Z,#2257 ;PAPER/INK 8,skoc OR B ;Ale pro PAPER/INK 9 budou barvy cerna a bila CPL AND #24 JR Z,#2257 ;Skoc s cernymi INK/PAPER LD A,B ;Pokracuj s bilymi INK/PAPER.Preved hodnotu do C 2257 LD C,A Nyni jsou pouzity maska B a hodnota C ke zmene ATTR-T. 2258 LD A,C ;Hodnota zpet do A CALL #226C ;Zmena ATTR-T LD A,#07 ;Bity MASK-T se budou menit pouze CP D ;pro PAPER/INK 8 nebo 9 SBC A,A CALL #226C RLCA ;Pro P-FLAG je prislusna maska vytvorena v B RLCA AND #50 LD B,A LD A,#08 ;Bit 4 a 6 bude zmenen jedine v pripade, CP D ;ze PAPER/INK je 9 SBC A,A Podprogram "CO-CHANGE" ---------------------- Tento podprogram preda systemove promenne bity vstupujici v registru A. Maska v B ukazuje,ktere bity z A maji byt kopirovany. 226C XOR (HL) ;Bity specifikovane registrem B jsou zmeneny AND B ;a vysledek jde do systemove promenne XOR (HL) LD (HL),A INC HL ;Prejdi na adresu dalsi systemove promenne LD A,B ;Vrat se s maskou v registru A RET MONITOR ROM - ZX Spectrum - 77 - 22D4 RLCA ;Rotuj doleva a zaroven do CY DJNZ #22D4 AND #01 ;Bit=1 pro inkoust a 0 pro papir JP #2D28 ;Vysledek je ulozen na zasobnik Rutina prikazu PLOT ------------------- Je vyuzivana take programy CIRCLE a DRAW.Na vstupu jsou souradnice x,y ulozeny na zasobniku kalkulatoru.Po nalezeni adresy se bere v uvahu stav INVERSE a OVER a nakresli se prislusny bod. 22DC CALL #2307 ;Souradnice y do B a x do C CALL #22E5 ;Volani podprogramu JP #0D4D ;Vystup s nastavenim prechodovych barev 22E5 LD (#5C7D),BC ;Nastav systemovou promennou COORDS CALL #22AA ;Adresa "pixlu" do HL LD B,A ;B bude pocitat A+1 krat,aby se log. 0 dostala INC B ;na spravne misto v A LD A,#FE ;Vlozeni nuly a jeji nastaveni do bitu,ktery 22F0 RRCA ;odpovida pozici "pixlu" DJNZ #22F0 LD B,A ;Kopie do B LD A,(HL) ;Bajt obrazovky do A LD C,(IY+87) ;(P-FLAG) BIT 0,C ;Test na OVER 1 a preskok,jestlize ano JR NZ,#22FD AND B ;OVER 0 zpusobi,ze pixl bude mit hodnotu 0 22FD BIT 2,C ;Test na INVERSE 1 a preskok,jestlize ano JR NZ,#2303 ;INVERSE 0 preklopi logickou hodnotu pixlu XOR B CPL 2303 LD (HL),A ;Bajt je vlozen na obrazovku JP #0BDB ;Vystup s nastavenim atributu Subrutina STK-TO-BC ------------------- Tato subrutina ulozi dve FP cisla do BC a je pouzivana k vyzvednuti dvou parametru v rozsahu #00 az #FF.Zaroven vsak uklada do DE tzv. diagonalni hodnoty (+_1,+_1),ktere jsou pouzivany v podprogramu DRAW. 2307 CALL #2314 ;Prvni cislo do A potom do B LD B,A PUSH BC ;Chvilkova uschova CALL #2314 ;Druhe cislo do A LD E,C ;Jeho znamenko do E POP BC ;Obnov prvni cislo LD D,C ;Jeho znamenko do D LD C,A ;Druhe cislo do C RET ;BC a DE jsou nastaveny Subrutina STK-TO-A ------------------ Tato subrutina ulozi do registru A FP cislo z vrcholu zasobniku kalkulatoru. Cislo musi byt v rozsahu #00 az #FF. 2314 CALL #2DD5 ;Modul posledni zaokrouhlene hodnoty do A, JR C,#24F9 ;neni-li to mozne,chyba LD C,#01 ;Signal: pozit.hodnota RET Z ;Vrat se byla-li pozitivni LD C,#FF ;V ostat.pripadech zmen hodnotu v C na #FF RET ;(= -1) Prikaz CIRCLE ------------- Tato rutina narysuje pribliznou kruznici se stredem v bode X,Y o polomeru Z. Parametry jsou pred pouzitim prevedeny na tvar INTEGER.Proto Z musi byt mensi nez 87.5, i kdyz stred kruznice lezi ve stredu obrazovky.Pouzita metoda nakresli serii primek aproximujicich oblouk.Program CIRCLE ma ctyri casti: a) Test polomeru.Je-li polomer mensi nez jedna,je narysovan pouze bod o souradnicich X,Y. b) Je zavolana CD-PRMS1 na adrese #2470,ktera se pouziva k nastaveni pocatecnich parametru pro CIRCLE i DRAW. c) Jsou nastaveny zbyvajici parametrypro CIRCLE vcetne pocatecniho umisteni prvniho "oblouku". d) Skok do DRAW,kde je vyuzito programu pro narysovani oblouku (na adrese #2420). Nyni budou postupne popsany casti a) az c). Ad a) #2320 az #23AA.Polomer Z je vyzvednut z kalkulatoroveho zasobniku a jeho hodnota je prevedena na vhodny tvar.Je-li Z mensi nez jedna, je vymazano ze zasobniku a je proveden odskok pro narysovani bodu na souradnicich X,Y. MONITOR ROM - ZX Spectrum - 79 - INC (IY+28) ;(MEM-2-1ST) Exponent v MEM-2 je zmenen,cimz CALL #1E94 ;vznika tvar 2*Z*SIN(PI/A).Posledni hodnota LD L,A ;X+Z je predana ze zasobniku do registru A PUSH HL ;a je uschovana v HL CALL #1E94 ;Y-Z*SIN(PI/A) jde ze zasobniku do A POP HL ;a je kopirovano do H LD H,A LD (#5C7D),HL ;Nyni HL ukazuje na pocatecni bod a tato POP BC ;hodnota jde do COORDS.Je obnoveno pocitadlo JP #2420 ;oblouku a provede se skok na DRAW Nyni jsou na zasob.hodnoty X+Z,Y-Z*SIN(PI/A),Y-Z*SIN(PI/A),X+Z. Rutina prikazu DRAW ------------------- Do teto rutiny se vstupuje se souradnicemi bodu,rekneme X0,Y0 v systemove promenne COORDS.Jsou-li pro prikaz DRAW udany pouze dva parametry X,Y,potom rutina narysuje primku z bodu X0,Y0 do bodu X0+X,Y0+Y.Je-li udan treti parametr G,potom rutina rysuje aproximaci kruhoveho oblouku z bodu o sourad- nicich X0,Y0 do bodu X0+X,Y0+Y,jehoz stredovy uhel je G rad. a) jsou-li udany pouze dva parametry nebo parametr polomeru je mensi nez jedna,je narysovana prosta primka. b) vola CD-PRMS1 na #247D k nastaveni pocatecnich parametru. c) nastavuje zbyvajici parametry a to vcetne pocatecnich rozmisteni pro prvni oblouk. d) vstupuje do smycky pro rysovani oblouku na #24B7. Dva podprogramy CD-PRMS1 a DRAW-LINE nasleduji za touto hlavni rutinou.Nyni budou postupne popsany vsechny ctyri casti hlavni rutiny. ad a) Jsou-li udany pouze dva parametry,provede se skok na LINE-DRAW na adrese #2477.Primka se rysuje take v tom pripade,je-li hodnota Z mensi nez jedna. Z lezi jednim az jedenapultym nasobkem prumeru zamyslene kruznice.V teto casti je nastavena MEM-0 na SIN(G/2), MEM-1 na Y a MEM-5 na G. 2382 RST #18 ;Vyzvedni aktualni znak.Je-li to carka,skoc CP #2C JR Z,#238D CALL #1BEE ;Pri kontrole syntaxe se posun na dalsi prikaz JP #2477 ;Skoc na pouhe rysovani primky 238D RST #20 ;Vyzvedni dalsi znak(uhel),ktery je ulozen CALL #1C82 ;na zasobnik kalkulatoru CALL #1BEE ;Pri kontrole syntaxe se posun na dalsi prikaz RST #28 ;X,Y,G jsou na zasobniku DEFB #C5 ;ST-MEM-5 G jde do MEM-5 DEFB #A2 ;ST-POLOVINA X,Y,G,0.5 DEFB #04 ;nasobeni X,Y,G/2 DEFB #1F ;SIN X,Y,SIN(G/2) DEFB #31 ;zdvojeni X,Y,SIN(G/2),SIN(G/2) DEFB #30 ;not X,Y,SIN(G/2),(0 nebo 1) DEFB #30 ;not X,Y,SIN(G/2),(1 nebo 0) DEFB #00 ;skok-pravda X,Y,SIN (G/2) DEFB #06 ;na DR-SIN-NZ Jestlize SIN(G/2)=0 tj. G=2*N*PI DEFB #02 ;vymaz narysuj primku DEFB #38 ;konec vypoctu X,Y JP #2477 ;LINE-DRAW Primka z bodu X0,Y0 do X0+X,Y0+k 23A3 DEFB #C0 ;ST-MEM-0 SIN(G/2) jde do MEM-0 DEFB #02 ;vymaz X,Y jsou nyni na zasobniku DEFB #C1 ;ST-MEM-1 Y jde do MEM-1 DEFB #02 ;vymaz X DEFB #31 ;zdvojeni X,X DEFB #2A ;abs X,X' (X'=ABS X) DEFB #E1 ;GET-MEM-1 X,X',Y DEFB #01 ;zamena X,Y,X' DEFB #E1 ;GET-MEM-1 X,Y,X',Y DEFB #2A ;abs X,Y,X',Y' DEFB #0F ;scitani X,Y,X'+Y' DEFB #E0 ;GET-MEM-0 X,Y,X'+Y' SIN(G/2) DEFB #05 ;deleni X,Y,(X'+Y')/SIN(G/2)(dale pouze Z') DEFB #2A ;abs X,Y,Z (Z=ABS Z') DEFB #E0 ;GET-MEM-0 X,Y,Z,SIN(G/2) DEFB #01 ;zamena X,Y,SIN(G/2),Z DEFB #3D ;RE-STACK Z je v zasobniku prevedeno tak,aby DEFB #38 ;konec vypoctu byl k dispozici jeho exponent LD A,(HL) ;Vyzvedni exponent Z CP #81 ;Je-li Z vetsi nebo rovno jedne,skoc JR NC,#23C1 RST #28 ; X,Y,SIN(G/2),Z DEFB #02 ;vymaz X,Y,SIN(G/2) DEFB #02 ;vymaz X,Y DEFB #38,konec vypoctu JP #2477 ;Narysuj primku z bodu X0,Y0 do X0+X do Y0+Y MONITOR ROM - ZX Spectrum - 81 - RST #28 ; Y,X,X0 DEFB #C0 ;ST-MEM-0 X0 do MEM-0 DEFB #0F ;scitani Y,X0+X DEFB #01 ;zamena X0+X,Y DEFB #38 ;konec vypoctu LD A,(#5C7E) ;Dej Y0 do A a tim dale na zasobnik CALL #2D28 RST #28 ; X0+X,Y,Y0 DEFB #C5 ;st-mem-5 Y0 do MEM-5 DEFB #0F ;scitani X0+X,Y0+Y DEFB #E0 ;GET-MEM-0 X0+X,Y0+Y,X0 DEFB #E5 ;GET-MEM-5 X0+X,Y0+Y,X0,Y0 DEFB #38 ;konec vypoctu POP BC ;Obnov pocitadlo oblouku v B Ad d) Smycka pro narysovani oblouku.Do teto smycky se vstupuje na adrese #2439 se souradnicemi pocatecniho bodu na vrcholu zasobniku a s umistenim prvniho oblouku v MEM-1 a MEM-2.Je zajisteno pomoci jednoduche trigonometrie,ze vsech- ny nasledujici oblouky budou lezet na stejne kruznici a jsou tetivami stredove- ho uhlu N,ktery je tez puvodem techto souradnic,potom X2=X1*COS N-Y1*SIN N, Y2=X1*SIN N-Y1*COS N.Ale protoze puvod je zde ve spodnim levem rohu obrazovky, musi se pro dosazeni pozadovaneho efektu zahrnout tyto vztahy do prirustku, rekneme Un=Xn+1-Xn a Vn=Yn+1-Yn,ve smycce pro rysovani oblouku.V nasledujicim komentari jsou ukazany hodnoty zasobniku po n+1 prubehu smyckou,kdy Xn a Yn jsou uz zvetseny o hodnoty Un a Vn pote co byly obdrzeny z Un-1 a Vn-1.Ctyri hodnoty na vrcholu zasobniku na #2425 jsou u DRAW,cteno shora,X0+X,Y0+Y,Xn,Yn, ale pro usetreni mista nejsou tyto hodnoty ukazany az do bodu #2439.Zajimaji-li vas tyto hodnoty pro prikaz CIRCLE,jsou videt na konci rutiny CIRCLE. Pro CIRCLE plati G=2*PI. 2420 DEC B ;B pocita pruchody smyckou JR Z,#24F5 ;Skok,kdyz B dosahlo nuly JR #2439 ;Skok na zacatek smycky 2425 RST #28 ;Viz text o zasobniku DEFB #E1 ;GET-MEM-1 Un-1 DEFB #31 ;zdvojeni Un-1,Un-1 DEFB #E3 ;GET-MEM-3 Un-1,Un-1,COS(G/A) DEFB #04 ;nasobeni Un-1,Un-1*COS(G/A)=L DEFB #E2 ;GET-MEM-2 Un-1,L,Vn-1 DEFB #E4 ;GET-MEM-4 Un-1,L,Vn-1,SIN(G/A) DEFB #04 ;nasobeni Un-1,L,Vn-1*SIN(G/A) DEFB #03 ;odcitani Un-1,L-Vn-1*SIN(G/A)=Un DEFB #C1 ;ST-MEM-1 Un do MEM-1 DEFB #02 ;vymaz Un-1 DEFB #E4 ;GET-MEM-4 Un-1,SIN(G/A) DEFB #04 ;nasobeni Un-1*SIN(G/A)=K DEFB #E2 ;GET-MEM-2 K,Vn-1 DEFB #E3 ;GET-MEM-3 K,Vn-1,COS(G/A) DEFB #04 ;nasobeni K,Vn-1*COS (G/A) DEFB #0F ;scitani K+Vn-1*COS (G/A)=Vn DEFB #C2 ;st-mem-2 Vn do mem-2 DEFB #02 ;vymaz Jak bylo receno v textu,zasobnik DEFB #38 ;konec vypoctu ve skutecnosti obsahuje hodnoty ; X0+X,Y0+Y,Xn a Yn 2439 PUSH BC ;Uschovej citac oblouku RST #28 ; X0+X,Y0+Y,Xn,Yn DEFB #C0 ;ST-MEM-0 Yn do MEM-0 DEFB #02 ;vymaz X0+X,Y0+Y,Xn DEFB #E1 ;GET-MEM-1 X0+X,Y0+Y,Xn,Un DEFB #0F ;scitani X0+X,Y0+Y,Xn+Un=Xn+1 DEFB #31 ;zdvojeni X0+X,Y0+Y,Xn+1,Xn+1 DEFB #38 ;konec vypoctu Dale Xn',priblizna hodnota LD A,(#5C7D) ;Xn dosazena rutinou pro rysovani primek je CALL #2D28 ;ulozena do A a ulozena na zasobnik RST #28 ; X0+X,Y0+X,Xn+1,Xn' DEFB #03 ;odcitani X0+X,Y0+Y,Xn+1,Xn+1-Xn'=Un' DEFB #E0 ;GET-MEM-0 X0+X,Y0+Y,Xn+1,Un',Yn DEFB #E2 ;GET-MEM-2 X0+X,Y0+Y,Xn+1,Un',Yn,Vn DEFB #0F ;SCITANI X0+X,Y0+Y,Xn+1,Un',Yn+Vn=Yn+1 DEFB #C0 ;ST-MEM-0 Yn+1 do MEM-0 DEFB #01 ;zamena X0+X,Y0+Y,Xn+1,Yn+1,Un' DEFB #E0 ;GET-MEM-0 X0+X,Y0+Y,Xn+1,Yn+1,Un',Yn+1 DEFB #38 ;konec vypoctu Yn' aproximovano jako Xn' je LD A,(#5C7E) ;okopirovano do A a ulozeno na zasobnik CALL #2D28 ; X0+X, RST #28 ; Y0+Y,Xn+1,Yn+1,Un',Yn+1,Yn' DEFB #03 ;odcitani X0+X,Y0+Y,Xn+1,Yn+1,Un',Vn' DEFB #38 ;konec vypoctu CALL #24B7 ;Je narysovan dalsi oblouk POP BC ;Obnoveni pocitadla oblouku DJNZ #2425 ;Maji-li se rysovat jeste dalsi oblouky,provede se skok 245F RST #28 ; Souradnice konce oblouku, DEFB #02 ;vymaz ktery byl narysovan,jsou nyni vymazany DEFB #02 ;vymaz ze zasobniku DEFB #01 ;zamena Y0+Y,X0+X DEFB #38 ;konec vypoctu MONITOR ROM - ZX Spectrum - 83 - LD L,C ;Mensi do L a vetsi do H PUSH DE ;Uschovej diagonalni krok (+_1,+_1) XOR A ;Vloz vertikalni krok (+_1,0) LD E,A ;do DE a (DE=SGN A) skoc pro nastaveni H JR #24CB 24C4 OR C ;Jsou-li ABS X i ABS Y nulove,vrat se RET Z LD L,B ;Mensi (zde ABS Y) jde do L LD B,C ;ABS X jde do B pro H PUSH DE ;Uschovej diagonalni krok (+_1,+_1) LD D,#00 ;Vloz horizontalni krok (0,+_1) do DE 24CB LD H,B ;Vetsi z ABS X,ABS Y jde do H Zde zacina algoritmus.Vetsi z ABS X a ABS Y,rekneme H,je ulozeno do A a redukovano na INT (H/2).Nyni se provede H-L horizontalnich nebo vertikalnich kroku a L diagonalnich kroku,kdy L je mensi z ABS X a ABS Y,timto zpusobem: L se pricte do A;jestlize nyni je A>=H,je snizeno o H a provedou se diagonalni kroky,jinak se provedou horizontalni nebo vertikalni kroky.Toto se opakuje H-krat (B take obsahuje H).Povsimnete si,ze se tez vyuzivaji zrcadlove registry HL k uschovani hodnoty COORDS. LD A,B ;B jde do A stejne i do H RRA ;A zacina s hodnotou INT(H/2) 24CE ADD A,L ;L se pricte do A JR C,#24D4 ;Je-li to vic nez 255 provede se skok CP H ;na diagonalni krok.Jestlize A je mensi nez H JR C,#24DB ;provede se skok na horizontalni,nebo verti- 24D4 SUB H ;kalni krok.Sniz A o H a obnov jej do C LD C,A EXX ;Nyni pouzij zrcadlove registry.Diagonalni krok POP BC ;do B'C' a uschova PUSH BC JR #24DF ;Skok k provedeni kroku 24DB LD C,A ;Uschovej A (nesnizeno) v C PUSH DE ;Uschovej kratce na zasobniku.Zamen registro- EXX ;ve pary.Vyzvedni krok POP BC 24DF LD HL,(#5C7D) ;Nyni provadej krok,nejdrive jde COORDS do H'L' LD A,B ;jako pocatecni krok.Krok Y z B' do A ADD A,H ;Pricti H' LD B,A ;Vysledek uloz do B LD A,C ;Nyni bude testovan na rozsah X-ovy krok INC A ;(Y-ovy krok se otestuje v rutine PLOT) ADD A,L ;Pricti L do A a proved skok pri CY=1 na dalsi JR C,#24F7 ;test.Z=1 a CY=0 X-ova pozice -1 je mimo rozsah JR Z,#24F9 24EC DEC A ;Obnov pravdivou hodnotu v A. Hodnota do C' LD C,A ;pro rysovani.Narysuj tento krok CALL #22E5 EXX ;Obnov registry LD A,C ;C jde zpet do A pro pokracovani algortmu DJNZ #24CE ;Skok na start smycky po B-kroku (tedy po H POP DE ;kroku).Vycisti strojovy zasobnik.Konec RET 24F7 JR Z,#24EC ;Z=0 a CY=1 znamena X-ova souradnice 255, 24F9 RST #08 ;v rozsahu.Ohlas: B-Integer out of range DEFB #0A HODNOCENI VYRAZU **************** Subrutina SCANNING ------------------ Tato subrutina se pouziva,aby ohodnotila vysledky dalsiho vyrazu.Vysledek se vraci jako "posledni hodnota" na zasobniku kalkulatoru.Pro numericke vysledky bude "posledni hodnota" skutecne FP cislo,nicmene vysledkem hodnoceni retezcu je soubor parametru predstavujici posledni hodnotu.Prvni z peti bajtu neni specifikovan,druhy a treti bajt obsahuji adresu zacatku retezce a ctvrty a paty bajt jeho delku.Bit 6 systemove promenne FLAGS je nastaven pro ciselne vysledky a je nulovy pro retezce.Jestlize se vyraz sklada pouze z jedineho operandu napr. A...RND...A$(4,3 TO 7)...,potom "posledni hodnota" predstavuje hodnotu, ktera se ziska ohodnocenim operandu.V pripade,ze vyraz obsahuje jako operand funkci,napr.CHR$ A,...NOT A,...SIN 1,je operacni kod teto funkce ulozen na za- sobniku,dokud neni vypoctena posledni hodnota operandu.Potom se tato hodnta pouzije v prislusne operaci,aby se ziskala nova "posledni hodnota".V pripade, ze se maji vykonat aritmeticke nebo logicke operace,napr.A+B,...,A*B,...,A=B, potom se musi uschovat operacni kod a posledni hodnota prvniho argumentu,dokud neni nalezena posledni hodnota druheho argumentu.A vskutku vypocet posledni hodnoty druheho argumentu v sobe muze zahrnovat ulozeni poslednich hodnot a operacnich kodu na zasobnik po dobu prubehu vlastniho vypoctu.Proto lze zpracovat i slozitejsi hierarchii operaci.Napr.CHR$(T+A)-26*INT((T+A)/26)+65) se bude provadet tak dlouho,az se dosahne bodu,z ktereho jiz lze mezivysledky "demontovat" a takto muze byt teprve ziskana konecna "posledni" hodnota.Kazdy operacni kod ma pridelenou prioritu a operace s vyssi prioritou jsou vzdy uskutecneny pred operacemi s prioritou nizsi.Subrutina zacina s registrem A obsahujicim prvni znak souboru a pocatecni prioritou nula,ktera je ulozena na zasobniku. MONITOR ROM - ZX Spectrum - 85 - 255D INC D ;Posun DE na dalsi bitovy radek (pricti 256) INC HL ;Posun HL na dalsi radek (tedy na dalsi bajt) LD A,(DE) ;Vyzvedni radek z obrazovky XOR (HL) ;Porovnej ho s radkem v ROM XOR C ;Pridej inverzni status a skoc,nedochazi-li JR NZ,#2573 ;k totalni shode.Skoc zpet pokud nejsou DJNZ #255D ;porovnany vsechny bitove radky POP BC ;Zbav se ukazatele na soubor znakovych matic POP BC ;a ukazatele obrazovky POP BC ;Zaverecny pocet do BC kod posledniho znaku+1 LD A,#80 SUB B ;A nyni obsahuje pozadovane kod LD BC,#0001 ;Nyni bude potreba jedno misto v pracovnim RST #30 ;prostoru.Vytvor toto misto LD (DE),A ;Vloz do nej znak JR #257D ;Skoc na ulozeni znaku na zasobnik 2573 POP HL ;Obnov ukazatel na znakovy soubor LD DE,#0008 ADD HL,DE ;Posun jej o 8 bajtu,tedy na dalsi matici POP DE ;tohoto souboru.Obnov ukazatel obrazovky POP BC ;Obnov citac DJNZ #254F ;Skok zpet protze znaku je 96 LD C,B ;Signal: prazdny retezec delky 0.Nebyl-li znak 257D JP #2AB2 ;nalezen,skoc k ulozeni nuloveho retezce.Jinak ;uloz nalezeny znak Poznamka: Vystup pres STK-STO-$ je chybou,ktera zpusobi,ze nalezeny vysledek je ulozen dvakrat.Zde mela byt instrukce RET.Posledni z techto subrutin je subrutina prohledavajici atributy.Je volana programem S-ATTR aby vratila hodnotu ATTR(X,Y),udavajici hodnotu atributu pro znak nachazejici se na souradnicich X,Y obrazovky. 2580 CALL #2307 ;X do C, Y do B (opet 0<=X<=23 a 0<=Y<=31 de- LD A,C ;kadicky).X je okopirovano do A a cislo RRCA ;32*(X mod 8)+Y je formovano v A a okopirovano RRCA ;do L RRCA LD C,A ;Hodnota 32*(X mod 8)+INT (X/8) je take okopi- AND #E0 ;rovano do C XOR B LD L,H ;L obsahuje nizsi bajt atributove adresy LD A,C ;Hodnota 32*(X mod 8)+INT (X/8) je zpet okopi- AND #03 ;rovano do A.Hodnota INT (X/8)+#58 je formovana XOR #58 ;v A a okopirovana do H, ktere pak obsahuje LD H,A ;vyssi bajt adresy atributu LD A,(HL) ;Atributovy bajt je okopirovan do A a je JP #2D28 ;proveden odskok a ulozeni pozadovaneho bajtu ;na zasobnik TABULKA TESTOVACICH FUNKCI -------------------------- Tato tabulka obsahuje 8 funkci a 4 operatory.Zahrnuje v sobe tedy pet novych funkci SPECTRA a umoznuje elegantnim zpusobem dosahovat nekterych funkci a operatoru ktere jiz existovaly v pocitaci ZX-81. adresa kod doplnek jmeno adresa provadeci rutiny 2596 22 1C S-QUOTE 25B3 2598 28 4F S-BRACKET 25E8 259A 2E F2 S-DECIMAL 268D 259C 2B 12 S-U-PLUS 25AF 259E A8 56 S-FN 25F5 25A0 A5 57 S-RND 25F8 25A2 A7 84 S-PI 2627 25A4 A6 8F S-INKEY$ 2634 25A6 C4 E6 S-BIN(EQU.S-DECIMAL) 268D 25A8 AA BF S-SCREEN$ 2668 25AA AB C7 S-ATTR 2672 25AC A9 CE S-POINT 267B 25AE 00 Koncovy znak Rutiny pro vyhodnoceni funkci ----------------------------- 25AF RST #20 ;Pro obycejne plus se pouze presun na dalsi JP #24FF ;znak a skoc zpet na hlavni bod opetovnych ;vstupu programu SCANNING Rutina na prohledavani uvozovek: Tato rutina zpracovava retezce s uvozovkami, napr.obycejne jako "jmeno",nebo slozitejsi jako "temer" "nevinna" "lez" nebo nadbytecne jako VAL$ """a""". 25B3 RST #18 ;Vyzvedni aktualni znak INC HL ;Ukazuj na zacat.retezce. PUSH HL ;Uschovej pocatecni adresu LD BC,#0000 ;Nastav delku na nulu CALL #250F ;Volej porovnavaci podprogram JR NZ,#25D9 ;Skoc,jestlize je Z = 0,coz znamena:dalsi uvo- MONITOR ROM - ZX Spectrum - 87 - 2634 LD BC,#105A ;Priorita #10 operacni kod #5A pro rutinu RST #20 ;READ-IN CP #23 ;Je-li dalsi znak krizek,skoc,nebot bude JP Z,#270D ;nasledovat ciselny argument LD HL,#5C3B ;Adresa FLAGS RES 6,(HL) ;Resetuj bit 6 pro retezcovy vysledek a testuj BIT 7,(HL) ;bit 7 na kontrolu syntaxe JR Z,#2665 ;Skoc,je-li to potreba CALL #028E ;Vyzvedni klicovou hodnotu do DE.Priprav LD C,#00 ;prazdny retezec a vloz jej na zasobnik, JR NZ,#2660 ;bylo-li stisknuto vice klaves CALL #031E ;Testuj hodnotu klavesy a uloz hodnoty JR NC,#2660 ;prazdneho retezce,jestlize hodnoty klaves DEC D ;nevyhovuji.#FF do D pro L mod (set bit 3) LD E,A ;Hodnota klavesy do registru E pro dekodovani CALL #0333 ;Dekoduj hodnotu klavesy PUSH AF ;Uschovej hodnotu ASCII LD BC,#0001 ;Je potreba jedno misto v pracovnim prostoru RST #30 ;Vytvor toto misto POP AF ;Obnov hodnotu ASCII LD (DE),A ;Priprav jeho uschovani na zasobnik jakozto LD C,#01 ;retezce.Jeho delka je jedna 2660 LD B,#00 ;Dokonci parametr delky a uloz pozadovany CALL #2AB2 ;retezec 2665 JP #2712 ;Skoc dopredu 2668 CALL #2522 ;Testuj,zda byly udany dve souradnice CALL NZ,#2535 ;Pokud nekontrolujes syntaxi,volej podprogram RST #20 ;Vyzvedni dalsi znak a skoc zpet JP #25DB 2672 CALL #2522 ;Testuj,zda byly udany dve souradnice CALL NZ,#2580 ;Pokud nekontrolujes syntaxi,volej podprogram RST #20 ;Vyzvedni dalsi znak a skoc dopredu JR #26C3 267B CALL #2522 ;Testuj,zda byli udany dve souradnice CALL NZ,#22CB ;Pokud nekontrolujes syntaxi,volej podprogram RST #20 ;Vyzvedni dalsi znak a skoc dopredu JR #26C3 2684 CALL #2C88 ;Je znak alfanumericky?Skoc,jestlize neni JR NC,#26DF CP #41 ;Nyni skoc,je-li to pismeno,jinak pokracuj JR NC,#26C9 ;do S-DECIMAL S-DECIMAL (EQU.S-BIN) --------------------- Tato rutina zpracovava ciselne vyrazy zacinajici desetinnou carkou nebo cis- lici.Take se stara o prikaz BIN,ktery je zpracovavan rutinou "decimal na FP". 268D CALL #2530 ;Skoc dopredu,jestlize se provadi radek JR NZ,#26B5 Akce,ktera se nyni zahaji,se znacne lisi pro kontrolu syntaxe a pro beh pro- gramu.Kontroluje-li se syntaxe,je vypoctena FP forma a okopirovana do aktual- niho basickeho radku.Provadi-li se program,bude FP vzdy k dispozci,takze je okopirovana na zasobnik kalkulatoru,aby vytvorila "posledni hodnotu". Behem kontroly syntaxe: CALL #2C9B ;Je nalezena FP forma RST #18 ;HL ukazuje za posledni cislici LD BC,#0006 ;Je potreba 6 mist CALL #1655 ;Vytvori se prostor v basickem radku INC HL ;HL ukazuje na prvni volne misto LD (HL),#0E ;Vlozi se znacka FP cisla a postoupi se EX DE,HL ;na dalsi cislo.Nyni bude ukazatel v DE LD HL,(#5C65) ;Vyzvedni STKEND LD C,#05 ;Jedna se o pet bajtu,ktere budou preneseny AND A ;Vycisti CY flag SBC HL,BC ;Novy STKEND=stary STKEND-5 LD (#5C65),HL ;Prenes FP cislo ze zasobniku kalkulatoru LDIR ;do basickeho radku EX DE,HL ;Obnov ukazatel v HL a ukazuj na posledni bajt DEC HL CALL #0077 ;Tato rutina nastavi CH-ADD JR #26C3 ;Skoc Za chodu programu: 26B5 RST #18 ;Vyzvedni aktualni znak 26B6 INC HL ;Nyni se presun na dalsi znak,dokud neni LD A,(HL) ;nalezena znacka pro FP cislo CP #0E JR NZ,#26B6 INC HL ;Ukazuj na prvni bajt cisla a prenes ho CALL #33B4 ;na zasobnik LD (#5C5D),HL ;Nastav CH-ADD MONITOR ROM - ZX Spectrum - 89 - BIT 6,(IY+1) ;(FLAGS) Skoc dopredu,jestlize obsluhujes ci- JR NZ,#2734 ;selny vyraz v zavorkach CALL #2A52 ;Modifikuj parametry "posledni" hodnoty" RST #20 ;Presun se k posouzeni dalsiho znaku JR #2713 Jestlize aktualni znak je skutecne binarni operator,bude mit operacni kod v rozsahu #C3 az #CF a prislusny kod priority. 2723 LD B,#00 ;Puvodni kod do BC pro hledani v tabulce LD C,A ;operatoru.Ukazatel na tabulku LD HL,#2795 CALL #16DC ;Hledej v tabulce JR NC,#2734 ;Skoc,nebyla-li operace nalezena LD C,(HL) ;Vyzvedni prislusny kod z tabulky.Ukazatel LD HL,#26ED ;na tabulku priorit: #26ED+#C3=#27B0 je prvni ADD HL,BC ;adresa.Hledej v tabulce LD B,(HL) ;Vyzvedni prislusnou prioritu Nyni se vstupuje do hlavni smycky tohoto podprogramu.Jiz je: a) Posledni hodnota na zasobniku kalkulatoru. b) Pocatecni prioritni znak pod "hromadou" neznamych znaku.Ovsem tato "hromada" muze byt tez nulova. c) BC obsahuje aktualni operaci a prioritu,ktera pri dosazeni konce bude mit hodnotu nula. Konecne jsou ze zasobniku sejmuty posledni hodnoty a porovnany oproti aktualni operaci a priorite.Jestlize aktualni priorita je vyssi nez posledni priorita, potom se provede vystup ze smycky,protoze aktualni priorita predbehla posledni prioritu.Jestlize je vsak aktualni priorita nizsi nez posledni priorita,je provedena tato posledni operace.Aktualni operace a priorita jde zpatky na za- sobnik,aby mohla byt dale zpracovana smyckou.Timto zpusobem se hiearchie funkci a binarnich operaci,ktere cekaji v jakesi fronte,zpracovava ve spravnem poradi. 2734 POP DE ;Vyzvedni posledni operaci a jeji prioritu LD A,D ;Priorita jde do A CP B ;Porovnej posledni proti aktualnimu JR C,#2773 ;Vystup na cekani na argument AND A ;Jsou obe priority 0? JP Z,#0018 ;Jestlize ano,vystup pres GET-CHAR,cimz se ;"posledni hodnota" stane vyslednou Nez je provedena posledni operace,je funkce USR rozdelena na "USR cislo" nebo "USR retezec" podle log. hodnoty bitu 6 FLAGS,nastaveneho jiz drive pri ukla- dani argumentu funkce USR jako "posledni hodnoty". PUSH BC ;Uloz aktualni hodnotu na zasobnik LD HL,#5C3B ;Adresa FLAGS LD A,E ;Posledni operace se testuje na kod pro USR, CP #ED ;ktere da USR cislo,nebylo-li modifikovano JR NZ,#274C ;Skoc,nebylo-li to USR BIT 6,(HL) ;Testuj bit 6 FLAGS JR NZ,#274C ;Skoc,byl-li nastaven (USR cislo) LD E,#99 ;Modifikuj posledni oper.kod:doplnek #19+#80 274C PUSH DE ;pro retezec a numer.vysledek.Uloz prechodne CALL #2530 ;posledni hodnoty a nedelej nic,kontrolujes-li JR Z,#275B ;syntaxi LD A,E ;Posledni operacni kod AND #3F ;Vymaz bity 6 a 7,aby se prevedl operacni kod LD B,A ;na kalkulatorovy doplnek RST #28 ;Uzij kalkulator DEFB #3B ;FP-CALC-2 Proved aktualni operaci DEFB #38 ;konec vypoctu JR #2764 ;Skoc dopredu Dulezitou casti kontroly syntaxe je tez testovani operace aby se zajistilo, ze povaha posledni hodnoty je spravneho typu pro posuzovanou operaci. 275B LD A,E ;Vyzvedni posledni operacni kod.Testuj typ XOR (IY+1) ;(FLAGS) posledni hodnoty oproti pozadavkum AND #40 ;na funkci.Aby byla syntaxe spravna,musi se 2761 JP NZ,#1C8A ;shodovat.Skoc,jestlize syntaxe selhala Pred navratem projdi smyckou,aby se povaha posledni hodnoty zaznamenala do systemove promenne FLAGS. 2764 POP DE ;Vyzvedni posledni operacni kod LD HL,#5C3B ;Adresa FLAGS SET 6,(HL) ;Predpokladej ze vysledek je ciselny BIT 7,E JR NZ,#2770 ;Je-li povaha posledni hodnoty ciselna,skoc RES 6,(HL) ;Je to retezec 2770 POP BC ;Vyzvedni aktualni hodnnoty do BC a skoc zpet JR #2734 MONITOR ROM - ZX Spectrum - 91 - 27E9 RST #20 ;Ukazuj na dalsi znak v basickem radku LD HL,#5C3B ;Adresa je FLAGS RES 6,(HL) ;Predpoklada se retezcova funkce POP AF ;Obnov Z flag a skoc,je-li vysledek funkce JR Z,#27F4 ;retezcoveho typu SET 6,(HL) ;Jinak nastav bit 6 ve FLAGS 27F4 JP #2712 ;Skoc zpet pri vyhodnocovani radku ad b) Pri behu programu se musi najit prislusny prikaz DEF-FN. 27F7 RST #20 ;Vyzvedni prvni znak jmena AND #DF ;Resetuj bit 5 pro velka pismena LD B,A ;Okopiruj jmeno do B RST #20 ;Vyzvedni dalsi znak SUB #24 ;Odecti #24,coz je kod pro znak "$" LD C,A ;Vysledek uloz do C (nula pro retezce,jinak JR NZ,#2802 ;ciselna funkce).Skoc,jedna-li se o ciselnou RST #20 ;funkci.Vyzvedni dalsi znak.Je to zavorka "(" 2802 RST #20 ;Vezmi prvni znak prvniho argumentu PUSH HL ;Uschovej ukazatel na zasobnik a ukazuj na za- LD HL,(#5C53) ;catek programu DEC HL ;Zpet o jedno misto 2808 LD DE,#00CE ;Hledat se bude DEF FN PUSH BC ;Uschovej nazev a retezcovy statut CALL #1D86 ;Nyni prohledavej program POP BC ;Obnov nazev a retezcovy statut JR NC,#2814 ;Skoc,byl-li prikaz DEF FN nalezen 2812 RST #08 ;Jinak ohlas: P - FN without DEF DEFB #18 Po nalezeni prikazu DEF FN je testovano jmeno a status obou funkci. Neshoduji-li se,pokracuje se v hledani. 2814 PUSH HL ;Ma-li se pokracovat v hledani,uschovej ukaza- CALL #28AB ;tel na znak DEF FN.Vyzvedni nazev funkce AND #DF ;DEF FN.Resetuj bit 5 pro velka pismena CP B ;Shoduje se nazev pro hledanou FN ? JR NZ,#2825 ;Skoc,jestlize ne CALL #28AB ;Vyzvedni znak v prikazu DEF FN SUB #24 ;Odecti #24 coz je znak "$" CP C ;Porovnej status funkce JR Z,#2831 ;Pri kompletni shode skoc 2825 POP HL ;Obnov ukazatel na DEF FN DEC HL ;Krok zpet LD DE,#0200 PUSH BC ;Priprav se na dalsi prohledavani a k nalezeni CALL #198B ;konce prikazu pouzij porovnavaci rutinu POP BC ;Mezitim bylo ulozeno jmeno a status JR #2808 ;Skoc zpet na dalsi hledani ad c) Nyni byl nalezen spravny prikaz DEF FN.Argumenty prikazu FN budou ohod- noceny opakovanym volanim SCANNINGu a jejich hodnoty po 5. bajtu (nebo para- metry pro retezce) budou ulozeny do prikazu DEF FN do mist vytvorenych pri kontrole syntaxe.HL bude pouzit jako ukazatel na prikaz DEF FN (v pripade vo- lani rutiny FN-SKPOVR),zatimco CH-ADD ukazuje na prikaz FN (a vola si RST #20 v pripade potreby). 2831 AND A ;Ukazuje-li HL na znak $,presun se na znak ( CALL Z,#28AB POP DE ;Obnov ukazatel na DEF FN POP DE ;Vyzvedni ukazatel na prvni argument FN LD (#5C5D),DE ;a okopiruj ho do CH-ADD CALL #28AB ;Prekroc "(" PUSH HL ;Uschovej tento ukazatel na zasobnik CP #29 ;Ukazuje na zavorku? Jestlize ano,skoc, JR Z,#2885 ;protoze funkce nema argumenty 2843 INC HL ;Ukazuj na dalsi kod a uloz ho do A LD A,(HL) CP #0E ;Je to znacka pro FP cislo? LD D,#40 ;Nastav bit 6 v reg. D pro numericky argument JR Z,#2852 ;Skoc,jednalo-li se o numericky argument DEC HL ;Zajisti,ze HL bude ukazovat na znak "$" CALL #28AB ;a ne na ridici kod INC HL ;HL nyni ukazuje na znacku FP cisla LD D,#00 ;Bit 6 je vynulovan,signal: retezec 2852 INC HL ;Ukazuj na prvni z peti bajtu v DEF FN PUSH HL ;Uschovej tento ukazatel a "retezcovy status" PUSH DE ;argumentu CALL #24FB ;Odhod argument POP AF ;Vyzvedni vlajku "cislo/retezec" XOR (IY+1) ;(FLAGS) Testuj bit 6 oproti vysledku ze AND #40 ;SCANNINGu a vypis hlaseni,jestlize se JR NZ,#288B ;neshoduji.Vyzvedni ukazatel na prvni z peti POP HL ;bajtu v DEF FN a dej ho do DE EX DE,HL ;HL necht ukazuje na STKEND LD HL,(#5C65) ;BC je pouzito pro pocitadlo 5ti bajtu,ktere LD BC,#0005 ;budou preneseny MONITOR ROM - ZX Spectrum - 93 - Nyni bude nalezen koncovy znak nazvu majici vice nez jeden znak. 28D4 CALL #2C88 ;Je znak alfanumericky? JR NC,#28EF ;Vyskoc ze smycky,kdyz byl nalezen konec nazvu RES 6,C ;Oznac rozlisovaci bajt RST #20 ;Vyzvedni dalsi znak JR #28D4 ;Jdi zpet a testuj jej Obycejne retezce a retezcova pole vyzaduji,aby bit 6 systemove promenne FLAGS byl vynulovan. 28DE RST #20 ;Posun CH-ADD za znacku "$" RES 6,(IY+1) ;(FLAGS) Nuluj bit 6 jako signal: retezec Neni-li DEFADD-HI 0,znamena to,ze se bude zpracovavat FN,je-li vsak program v behu,budou se hledat argumenty prikazu DEF FN. 28E3 LD A,(#5C0C) ;Je DEFADD-HI nula? AND A ;Jestlize ano,skoc JR Z,#28EF ;Je program v behu? CALL #2530 ;Kdyz ano,skoc k prohledani DEF FN JP NZ,#2951 Jinak (nebo kdyz promenna nebyla nalezena v prikazu DEF FN) se provede hledani v oblasti promennych,pokud se ovsem nekontroluje syntaxe. 28EF LD B,C ;Kopiruj rozlisovaci bajt do registru B CALL #2530 JR NZ,#28FD ;Je-li program v behu,skoc LD A,C ;Preved rozlisovaci bajt do A AND #E0 ;Vymaz cast znakoveho kodu SET 7,A ;Indikuj syntaxi nastavenim bitu 7 LD C,A ;Obnov znackovy bajt a pokracuj JR #2934 Provadi se basicky radek a proto se provede prohledani oblasti promennych. 28FD LD HL,(#5C4B) ;Vyzvedni ukazatel VARS Nyni vstup do smycky,ktera posoudi nazvy existujicich promennych. 2900 LD A,(HL) ;Prvni pismeno kazde existujici promenne AND #7F ;Porovnavej na bitech 0-6 JR Z,#2932 ;Skoc pri dosazeni bajtu #80 (koncovy znak CP C ;oblasti promennych) JR NZ,#292A ;Jestlize se prvni znaky neshoduji,skoc RLA ;Rotuj A doleva a pak je zdvoj,aby otestoval ADD A,A ;bity 5 a 6 JP P,#293F ;Retezcove promenne a pole JR C,#293F ;Jednoduche ciselne a "FOR NEXT" promenne Dlouhe nazvy vyzaduji aby byly porovnany cele. POP DE ;Porid kopii ukazatele na druhy znak PUSH DE PUSH HL ;Uschovej ukazatel na prvni znak 2912 INC HL ;Posuzuj dalsi znak 2913 LD A,(DE) ;Vyzvedni postupne vsech ny znaky a ukazuj INC DE ;na da lsi znak CP #20 ;Je to mezera ? JR Z,#2913 ;Ignoruj mezery OR #20 ;Nastav bit 5 tak,abys testoval mala i velka CP (HL) ;pismena JR Z,#2912 ;Jestlize se shoduji,skoc zpet pro dalsi znak OR #80 ;Budou se shodovat pri nastavenem bitu 7 ? CP (HL) ;Zkus to.Jestlize se posledni znaky neshoduji, JR NZ,2929 ;skoc LD A,(DE) ;Kontrola konce nazvu pred odskokem dopredu CALL #2C88 JR NC,#293E Ve vsech pripadech neshody nazvu se musi HL upravit tak,aby ukazoval na dalsi promennou v oblasti promennych. 2929 POP HL ;Vyzvedni ukazatel 292A PUSH BC ;Kratce uschovej B & C CALL #19B8 ;Nyni DE ukazuje na dalsi promennou EX DE,HL ;Zamen oba ukazatele POP BC ;vyzvedni zpet B & C JR #2900 ;skoc znovu do smycky Nebyla-li nalezena zadna polozka se spravnym nazvem,skocis sem. 2932 SET 7,B ;Signal: promenna nenalezena MONITOR ROM - ZX Spectrum - 95 - CALL #28AB ;Posun se na dalsi znak CP #29 ;Je to zavorka ")"? Jestli ano,skoc JP Z,#28EF ;na prohledani oblasti promennych CALL #28AB ;Ukazuj na dalsi argument a skoc JR #295A ;zpet na jeho posouzeni Byla nalezena shoda.Parametry retezcove promenne jdou nyni na zasobnik,cimz se predejde potrebe volani programu STK-VAR. 2981 BIT 5,C ;Jedna-li se o ciselnou promennou skoc JR NZ,#2991 INC HL ;Ukazuj na prvni z peti ukladanych bajtu LD DE,(#5C65) ;DE ukazuje na STKEND CALL #33C0 ;Uloz techto pet bajtu EX DE,HL ;HL ukazuje na novou pozici STKEND,jejiz LD (#5C65),HL ;hodnota je ulozena do STKEND 2991 POP DE ;Odhod ukazatele pro LOOK-VARS (1.a 2.znakovy POP DE ;ukazatel).Vrat se s CY i Z flag nulovymi,coz XOR A ;je signal: nevolat STK-VAR INC A RET Podprogram STK-VAR ------------------ Tato subrutina se obycejne pouziva k nalezeni parametru,ktere definuji existu- jici retezec v oblasti promennych nebo vraci v HL bazovou adresu urciteho ele- mentu nebo pole.Je-li volana z DIM,slouzi pouze ke kontrole syntaxe basickeho prikazu.Parametry definujici retezec mohou byt pozmeneny volanim programu SLICING,je-li to potreba. 2996 XOR A ;Nastav vlajku:pole LD B,A ;Vynuluj B BIT 7,C ;Skoc dopredu pri kontrole syntaxe JR NZ,#29E7 ;Dale oddel jednoduche retezce od poli BIT 7,(HL) ;Jedna-li se o pole,skoc JR NZ,#29AE INC A ;Signal:jednoduchy retezec 29A1 INC HL ;Posun ukazatel LD C,(HL) ;Vyzvedni delku retezce INC HL LD B,(HL) INC HL ;Posun ukazatel EX DE,HL ;Preved ukazatel na aktualni retezec CALL #2AB2 ;Predej parametry na zasobnik kalkulatoru RST #18 ;Vyzvedni aktualni znak a skoc na test JP #2A49 ;"kraceni" 29AE INC HL ;Posun ukazatel za delku pole INC HL INC HL LD B,(HL) ;Vyzvedni pocet dimenzi BIT 6,C ;Jde-li o ciselne pole,skoc dopredu JR Z,#29C0 Jestlize retezcove pole ma pocet dimenzi 1,lze jej povazovat za obycejny retezec. DEC B ;Dekrementuj pocet dimenzi a skoc, JR Z,#29A1 ;byl-li pocet 1 EX DE,HL ;Dale se provede kontrola indexu.Uschovej RST #18 ;ukazatel v DE.Vyzvedni aktualni znak CP #28 ;Je to zavorka "(" ? JR NZ,#2A20 ;Skoc podat chybove hlaseni,jestlize ne EX DE,HL ;Obnov ukazatel v HL Pro oba typy poli se nyni ohodnoti index. 29C0 EX DE,HL ;Predej ukazatel do DE JR #29E7 ;Skoc Nasledujici smycka ma za ukol nalezt parametry daneho elementu pole.Do smycky se vstupuje v bode SV-COUNT.Smycka se vykona B krat,coz u ciselnych poli odpo- vida poctu pouzitych dimenzi.Pro retezcova pole se smycka vykona B-1 krat,pro- toze posledni index se pouzije ke stanoveni "vyrezu" z retezce. 29C3 PUSH HL ;Uschovej citac RST #18 ;Vyzvedni aktualni znak POP HL ;Obnov citac CP #2C ;Je aktualni znak carka "," ? JR Z,#29EA ;Skoc dopredu na posouzeni dalsiho indexu BIT 7,C ;Pri behu programu skoc ohlasit chybu JR Z,#2A20 BIT 6,C ;Jde-li o retezcove pole,skoc JR NZ,#29D8 CP #29 ;Je aktualni znak zavorka ")" ? JR NZ,#2A12 ;Ne-li,skoc ohlasit chybu RST #20 ;Vyzvedni dalsi znak RET ;Syntaxe je v poradku - vrat se MONITOR ROM - ZX Spectrum - 97 - 2A45 CALL #2A52 ;Pouzij SLICING pro upravu souboru parametru 2A48 RST #20 ;Vyzvedni dalsi znak 2A49 CP #28 ;Je to zavorka "(" ? JR Z,#2A45 ;Skoc zpet,je-li treba posoudit "rez" Po posouzeni posledniho indexu se provede navrat,pricemz parametry pozadovane- ho retezce jsou ulozeny na zasobniku kalkulatoru RES 6,(IY+1) ;(FLAGS) Signal:retezcovy vysledek RET Podprogram "SLICING" -------------------- Tento podprogram provede "rez" z aktualniho retezce.Na vstupu jsou parametry retezce ulozeny na zasobniku kalkulatoru a v registrech A B C D E.Parametry jsou vyzvednuty pouze pri exekuci radku. 2A52 CALL #2530 ;Testuj vlajku CALL NZ,#2BF1 ;Pri behu programu vyzvedni parametry RST #20 ;Vyzvedni dalsi znak CP #29 ;Je to zavorka ")" ? JR Z,#2AAD ;Skoc dopredu,jestlize ano PUSH DE ;Zacatek jde na zasobnik XOR A ;Nuluj a uschovej A PUSH AF PUSH BC ;Uschovej delku LD DE,#0001 ;Predpoklad,ze "rez" zacne prvnim znakem RST #18 ;Vyzvedni prvni znak POP HL ;Delka do HL Nyni se ohodnoti prvni parametr pro rez. CP #CC ;Je aktualni znak TO ? JR Z,#2A81 ;Prvni parametr je tedy povazovan za 1 a skoc POP AF ;testovat druhy.Obnov A,ktere je #00 CALL #2ACD ;1.parametr do BC.A bude obsahovat #FF,byla-li PUSH AF ;chyba v rozsahu.Uschovej tuto hodnotu LD D,B ;Preved 1.parametr do DE LD E,C PUSH HL ;Uschovej delku RST #18 ;Vyzvedni aktualni znak POP HL ;Obnov delku CP #CC ;Je aktualni znak TO ? JR Z,#2A81 ;Skoc na test druheho parametru CP #29 ;Je to zavorka ")" ?Neni-li,skoc ohlasit chybu 2A7A JP NZ,#1C8A V tomto bode jiz byl identifikovan rez o delce jednoho znaku.Napriklad A$(4). LD H,D ;Posledni znak rezu je tedy take prvnim znakem LD L,E JR #2A94 Zde se ohodnoti druhy parametr. 2A81 PUSH HL ;Uschovej delku RST #20 ;Vyzvedni dalsi znak POP HL ;Obnov delku CP #29 ;Je to zavorka ")" ? Skoc,jestlize neni druhy JR Z,#2A94 ;parametr.Jestlize byl 1.parametr v rozsahu POP AF ;A obsahuje #00,jinak #FF CALL #2ACD ;BC obsahuje druhy parametr PUSH AF ;Uschovej "chybovy registr" RST #18 ;Vyzvedni aktualni znak LD H,B ;Predej vysledek z INT-EXP2 do HL LD L,C CP #29 ;Je to zavorka ")" ? JR NZ,#2A7A ;Jestlize ne,skoc ohlasit chybu Budou definovany "nove" parametry. 2A94 POP AF ;Vyzvedni "chybovy" registr EX (SP),HL ;Druhy parametr jde na zasobnik a soucasne ADD HL,DE ;start jde do HL.Pricti prvni parametr DEC HL ;ke startu.Jdi zpet o 1 misto,aby hodnota v HL EX (SP),HL ;byla spravna.Novy start jde na zasobnik a 2. AND A ;parametr zpet do HL.Odecti prvni parametry od SBC HL,DE ;druhuch k nalezeni delky rezu LD BC,#0000 ;Inicializuj novou delku JR C,#2AA8 ;Negativni rez nezpusobi chybu,ale nulovy INC HL ;retezec.Umozni jedno misto pro uzavirajici AND A ;bajt.Nyni testuj"chybovy"registr JP M,2A20 ;Byl-li nektery parametr mimo rozsah,skoc LD B,H ;Preved novou delku do BC LD C,L 2AA8 POP DE ;Vyzvedni novy start a zajisti,ze se stale RES 6,(IY+1) ;(FLAGS) signalizuje retezec 2AAD CALL #2530 ;Vtomto miste se vrat,kontrolujes-li syntaxi. RET Z ;Jinak pokracuj do rutiny STK-STORE MONITOR ROM - ZX Spectrum - 99 - Subrutina HL*DE --------------- Tento podprogram vraci konstrukci HL=HL*DE,pokud se nekontroluje syntaxe,cimz se dosahuje pozadovane funkce.Preteceni ze 16. bitu dava hlaseni "out of memo- ry".Neni to sice uplne pravda,ale predpoklada se,ze neni dost pameti pro ukol, ktery je uvazovan. 2AF4 CALL #2530 ;Pri kontrole syntaxe se vrat okamzite RET Z CALL #30A9 ;Proved nasobeni JP C,#1F15 ;Hlaseni "out of memory" RET Rutina prikazu LET ------------------ Toto je skutecna rutina pridelovani,pouzivana prikazy LET,READ a INPUT.Jestli- ze cilova promenna je nove deklarovana promenna,potom systemova promenna DEST bude ukazovat na prvni pismeno nazvu promenne,tak jak se vyskytuje v basickem radku.Bit 1 systemove promenne FLAGX bude nastaven na jednicku.Jestlize vsak cilova promenna jiz existuje,potom bit 1 ve FLAGX bude nulovy a systemova pro- menna DEST bude ukazovat na misto pred peti bajty stareho cisla;a pro retezec na prvni misto stareho retezce.Pouziti systemove promenne DEST timto zpusobem se vztahuje na jednoduche promenne a casti poli.Bit 0 systemove promenne FLAGX je roven jedne,jestlize cilova promenna je kompletni jednoducha retezcova pro- menna (coz je signal: smaz starou kopii).Na zacatku se vyzvedne aktualni hod- nota v systemove promenne DEST a testuje se bit 1 promenne FLAGS. 2AFF LD HL,(#5C4D) ;Vyzvedni aktualni adresu v DEST BIT 1,(IY+55) ;(FLAGX) Obsluhujes-li promennou,ktera jiz JR Z,#2B66 ;existuje,skoc Jde o nove deklarovanou promennou. Proto musi byt nejdrive nalezena delka jejiho nazvu. LD BC,#0005 ;Predpokladej,ze se jedna o ciselnou promennou Zde je vstup do smycky,ktera obslouzi znaky dlouheho nazvu.Jakekoliv mezery nebo barevne kody v nazvu jsou ignorovany. 2B0B INC BC ;Pricti jednicku do citace za znak nazvu 2B0C INC HL ;Pohybuj se po nazvu promenne LD A,(HL) ;Vyzvedni aktualni kod CP #20 ;Je-li to mezera,skoc zpet JR Z,#2B0C ;Takto jsou rovany mezery. Je-li kod v rozsahu JR NC,#2B1F ;#21 az #FF,skoc CP #10 JR C,#2B29 ;Akceptuj jako vysledne kody.ktere jsou v roz- CP #16 ;sahu #00 az #FF.Take akceptuj rozsah JR NC,#2B29 ;#16 az #1F.Prekroc ridici kod za jakymkoliv INC HL ;znakem pro INK az OVER.Skoc zpet,protoze tyto JR #2B0C ;kody jsou povazovany za mezery Oddel "ciselne" a "retezcove nazvy. 2B1F CALL #2C88 ;Je znak alfanumericky ? JR C,#2B0B ;Je-li tomu tak,akceptuj ho jako kod dlouheho CP #24 ;nazvu.Je to znak "$" ?Obsluhujes-li nove JP Z,#2BC0 ;deklarovany obycejny retezec,skoc dopredu Nove deklarovana ciselna promenna,ktera byla vyse zpracovana,potrebuje nyni prostor o velikosti BC v oblasti promennych pro ulozeni sveho nazvu a sve hodnoty.Tento prostor se vytvori,potom se do nej okopiruje nazev promenne, pricemz znaky tohoto nazvu jsou uz oznaceny tak,jak je potreba. 2B29 LD A,C ;Okopiruj delku do A LD HL,(#5C59) ;Nastav HL tak,aby ukazoval na #80-kovy bajt DEC HL ;na konci oblasti promennych CALL #1655 ;Nyni otevri oblast promennych Je vytvoren prostor o velikosti "BC" pred #80-kovym bajtem. INC HL ;Ukazuj na 1.novy bajt INC HL EX DE,HL ;DE bude ukazovat na druhy novy bajt PUSH DE ;Uschovej tento ukazatel LD HL,(#5C4D) ;Vyzvedni ukazatel na zacatek jmena DEC DE ;DE ukazuje na 1.novy bajt SUB #06 ;B bude obsahovat pocet znaku,ktere byly LD B,A ;nalezeny v dlouhem nazvu navic.Obsluhujes-li JR Z,#2B4F ;promennou s kratkym nazvem,skoc dopredu MONITOR ROM - ZX Spectrum - 101 - Nyni jsou ze zasobniku kalkulatoru vyzvednuty parametry prave zpracovavaneho retezce. PUSH HL ;Kratce uschovej ukazatel CALL #2BF1 ;Vyzvedni nove parametry a obnov ukazatel POP HL Poznamka:V tomto bode jiz bylo v pracovnim prostoru vytvoreno misto pro prave "pridelovanou promennou",napriklad pri prikazu LET A$(4 TO 8)="abcdefg" bylo vytvoreno pet mist.Parametry vyzvednute jako posledni hodnota reprezentuji retezec,ktery ma byt kopirovan do novych mist s pouzitim Prokrustova pravidla kraceni nebo prodluzovani podle potreby.Delka noveho retezce je porovnavana s delkou mozneho prostoru. EX (SP),HL ;Delka nove oblasti do HL a ukazatel nove AND A ;oblasti na zasobnik.Porovnej dve delky SBC HL,BC ;a pasuje-li novy retezec do prostoru a tedy ADD HL,BC ;neni-li potreba zadneho kraceni),skoc dopredu JR NC,#2B9B LD B,H ;Jinak uprav novou delku,nebot je prilis dlou- LD C,L ;ha.Delka nove oblasti na zasobnik a ukazatel 2B9B EX (SP),HL ;nove oblasti do HL Pokud nema novy retezec nulovou delku je kopirovan do pracovniho prostoru. Prokrustovo pravidlo se provadi automaticky,jestlize je novy retezec kratsi, nez pro nej vytvorene misto a je ho treba "natahnout". EX DE,HL ;Start noveho retezce do HL a ukazatel nove LD A,B ;oblasti do DE OR C JR Z,#2BA3 ;Je-li novy retezec nulovy,skoc dopredu.Jinak LDIR ;presun novy retezec do pracovniho prostoru Hodnoty,ktere byly uschovany na zasobniku,jsou nyni obnoveny. 2BA3 POP BC ;Delka nove oblasti POP DE ;Ukazatel nove oblasti POP HL ;Start,ukazatel na promennou(puvodne v DEST), ;je nyni v L-ENTER pouzit k predani "noveho" ;retezce do oblasti promennych Subrutina "L-ENTER" ------------------- Tento kratky podprogram se pouziva bud k predani ciselne hodnoty ze zasobniku kalkulatoru,nebo retezce z pracovniho prostoru,na sve nove misto v oblasti promennych.Podprogram je tedy pouzivan pro vsechny retezce krome nove deklaro- vanych a existujicich kompletnich retezcu. 2BA6 EX DE,HL ;Zamen ukazatele LD A,B ;Opet kontroluj nulovou delku OR C RET Z ;Pri nulovem vysledku se vrat PUSH DE ;Uschovej cilovy ukazatel LDIR ;Prenes ciselnou hodnotu nebo retezec POP HL ;HL ukazuje na prvni bajt ciselne hodnoty nebo RET ;retezce.Vrat se Subrutina " 'LET' POKRACUJE ZDE " --------------------------------- Pri zpracovani kompletnich a existujicich retezcu vstupuje novy retezec "pod maskou" nove deklarovaneho pred tim,nez je znicena jeho puvodni verze. 2BAF DEC HL ;HL ukazuje na znak nazvu promenne.Tzn. DEST-3 DEC HL DEC HL LD A,(HL) ;Vyzvedni znak PUSH HL ;Uschovej ukazatel na existujici verzi PUSH BC ;Uschovej delku existujiciho retezce CALL #2BC6 ;Pomoci L-STRING pricti novy retezec POP BC ;do oblasti promennych.Obnov delku a ukazatel POP HL INC BC INC BC ;Pridej jeden bajt pro pismeno a dva bajty INC BC ;pro delku.Odejdi pres "zniceni" cele puvodne JP #19E8 ;existujici verze Nove deklarovane jednodche retezce jsou zpracovany nasledovne: 2BC0 LD A,#DF ;Priprav se na oznaceni nazvu promenne LD HL,(#5C4D) ;Vyzvedni ukazatel na pismeno a patricne jej AND (HL) ;poznac.Pak pouzij L-STRING MONITOR ROM - ZX Spectrum - 103 - ;Existujici pole je zniceno 2C15 JR C,#2C1F ;Neexistuje-li zadne pole skoc dopredu PUSH BC ;Uschovej rozlisovaci bajt CALL #19B8 ;Nalezni zacatek dalsi promenne a znic CALL #19E8 ;existujici pole POP BC ;Obnov rozlisovaci bajt Jsou nalezeny pocatecni parametry noveho pole. 2C1F SET 7,C ;Nastav bit 7 rozlisovaciho bajtu LD B,#00 ;Citac rozmeru na nulu PUSH BC ;Uschovej citac a rozlisovaci bajt LD HL,#0001 ;Registr HL bude obsahovat delku elementu BIT 6,C ;v poli ( 1 pro retezec a 5 pro cislo ) JR NZ,#2C2D LD L,#05 2C2D EX DE,HL ;Delka elementu do DE Do nasledujici smycky se vstoupi pro kazdy rozmer,ktery je specifikovan v zavorkach po prikazu DIM.Celkovy pocet elementu pole bude vytvoren v registrovem paru DE. 2C2E RST #20 ;Posun CH-ADD pri kazdem pruchodu LD H,#FF ;Nastav limitni hodnotu CALL #2ACC ;Ohodnot parametr JP C,#2A20 ;Ohlas chybu,je-li parametr mimo rozsah POP HL ;Vyzvedni citac dimenzi a rozlisovaci bajt PUSH BC ;Uschovej parametr pri kazdem pruchodu smyckou INC H ;Inkrementuj citac rozmeru pri kazdem prubehu PUSH HL ;Obnov citac dimenzi a rozlisovaci bajt LD H,B ;Parametry jsou preneseny do HL LD L,C CALL #2AF4 ;Celkovy pocet bajtu se vytvari v HL EX DE,HL ;Potom je preveden do DE RST #18 CP #2C ;Vyzvedni aktualni znak JR Z,#2C2E ;a skoc do smycky,je-li to dalsi rozmer Poznamka:V tomto bode obsahuje registrovy par DE pocet bajtu pozadovanych pro elementy noveho pole.Velikost kazdeho rozmeru je uschovana na zasobnik.Nyni zkontroluj,ze skutecne existuje zavorka ")" za danymi vyrazy. CP #29 ;Je to ")" ? JR NZ,#2C05 ;Jestlize ne,skoc zpet RST #20 ;Posun CH-ADD za ni Nyni budou prideleny rozmerum velikosti. POP BC ;Vyzvedni citac rozmeru a rozlisovaci bajt LD A,C ;Pro pozdejsi pouziti predej rozlisovaci bajt LD L,B ;do registru A.Prenes citac do L LD H,#00 ;Vycisti registr H INC HL INC HL ;Zvets citac rozmeru o dve a vynasob ho dvema ADD HL,HL ;Vytvor spravnou delku pro promennou prictenim ADD HL,DE ;celkoveho poctu bajtu JP C,#1F15 ;Ohlas "out of memory",je-li to treba PUSH DE ;Uschovej celkovy pocet bajtu pole,citac PUSH BC ;dimenzi a rozlisovaci bajt PUSH HL ;Uschovej take pocet vsech bajtu nutnych LD B,H ;k vytvoreni pole a zaroven ho prenes do BC LD C,L Pozadovany prostor pro nove pole je vytvoren na konci oblasti promennych. LD HL,(#5C59) ;HL ukazuje na #80-kovy bajt DEC HL CALL #1655 ;Je vytvoren prostor.HL ukazuje na prvni misto INC HL ;Nyni jsou ulozeny parametry LD (HL),A ;Radne oznacene pismeno je vlozeno prvni POP BC ;Je vyzvednuta celkova delka a je snizena o 3 DEC BC DEC BC DEC BC INC HL ;Posun HL LD (HL),C ;Vloz nizsi a vyssi bajt delky INC HL LD (HL),B POP BC ;Vyzvedni citac rozmeru.Preved jej do A LD A,B INC HL ;Posun HL LD (HL),A ;Vloz pocet rozmeru LD H,D ;Elementy noveho pole jsou nyni vycisteny LD L,E ;HL ukazuje na posledni misto pole a DE DEC DE ;o jedno misto pred nim LD (HL),#00 ;Vloz nulu na posledni misto.Ale pokud se BIT 6,C ;jedna o retezcove pole budou misto nul JR Z,#2C7C ;vlozeny "mezery" MONITOR ROM - ZX Spectrum - 105 - 2CDA RST #18 ;Vyzvedni aktualni znak CALL #2D22 ;Je-li to cislice uloz ji na zasobnik JR C,#2CEB ;Jinak skoc dopredu RST #28 ;Kalkulator DEFB #E0 ;GET-MEM-0 Pri kazdem pruchodu smyckou je cislo DEFB #A4 ;STK-deset vyzvednuto z pameti,vydeleno deseti DEFB #05 ;deleni a obnoveno v pameti(asi takto 0.1, DEFB #C0 ;ST-MEM-0 0.001,0.001 atd.).Aktualni cislice je DEFB #04 ;nasobeni nasobena aktualnim cislem a prictena DEFB #0F ;scitani k posledni hodnote DEFB #38 ;konec vypoctu RST #20 ;Vyzvedni dalsi znak.Skoc zpet (o jeden bajt JR #2CDA ;vice nez je treba k posouzeni) Dale posuzuj jakoukoliv notaci E,napr. formatu x E m nebo x e m,kde m je kladne nebo zaporne cele cislo. 2CEB CP #45 ;Je aktualnim znakem "E"? JR Z,#2CF2 ;Jestlize ano,pak skoc dopredu CP #65 ;Jeto "e" ? RET NZ ;Konec,jestlize ne 2CF2 LD B,#FF ;Pouzij B jako vlajku pro znamenko (#FF odpo- RST #20 ;vida plus "+"). Vyzvedni dalsi znak CP #2B ;Je-li to plus,skoc dopredu JR Z,#2CFE CP #2D ;Neni-li to ani minus,skoc dopredu JR NZ,#2CFF INC B ;Zamen znamenko 2CFE RST #20 ;Ukazuj na prvni cislici 2CFF CALL #2D1B ;Neni-li to cislice,ohlas chybu JR C,#2CCF PUSH BC ;Uschovej vlajku v registru B CALL #2D3B ;Uloz na zasobnik hodnotu ABS m,kde m je expo- CALL #2DD5 ;nent.Preved ABS do A POP BC ;Obnov znamenkovou vlajku do B JP C,#31AD ;Ohlas preteceni,je-li ABS m>255 nebo skutecne AND A ;vetsi nez 127 (hodnoty vetsi nez 39 budou vy- JP M,#31AD ;louceny pozdeji).Testuj znamenkovou vlajku INC B ;v registru B.Plus (tedy #FF) nastavi Z flag JR Z,#2D18 ;a pak se odskoci.Neguj m,je-li znamenko minus NEG 2D18 JP #2D4F ;Skoc k prideleni hodnoty,vysledek x*10^m Subrutina "NUMERIC" ------------------- Predstavuje-li aktualni hodnota v registru A znak platne cislice,vraci tento podprogram CY flag nastaven na jednicku. 2D1B CP #30 ;Testuj oproti #30,coz je kod nuly.Vrat se, RET C ;jestlize se nejedna o platny znakovy kod CP #3A ;Testuj oproti hornimu limitu CCF ;Komplementuj CY RET Subrutina "STK-DIGIT" --------------------- Nepredstavuje-li hodnota v registru A platnou cislici,podprogram se proste vrati,jinak je znaku prirazena jeho hodnota a ulozena na zasobnik kalkulatoru. 2D22 CALL #2D1B ;Neni-li znak cislo,vrat se RET C SUB #30 ;Nahrad kod aktualni cislici Subrutina "STACK-A" ------------------- Tento podprogram vytvari z absolutni hodnoty binarni hodnoty v registru A hodnotu ve tvaru floating point a uklada ji na zasobnik. 2D28 LD C,A ;Preved hodnotu do registru A a vynuluj B LD B,#00 Subrutina "STACK-BC" -------------------- Tento podprogram vytvari z absolutni binarni hodnoty v registru BC hodnotu ve tvaru floating point a uklada ji na zasobnik.Forma pouzivana v tomto a tim padem i v predchozich dvou podprogramech,je forma malych celociselnych hodnot, kde -65535<=n<=65535.Prvni a paty bajt jsou nulove,treti a ctvrty bajt je niz- si a vyssi bajt cisla v komplementovanem tvaru (tedy -n=65536+n) a druhy bajt je znamenkovy tedy #00 pro plus a #FF pro minus. 2D2B LD IY,#5C3A ;Nastav IY na ERR-NR XOR A ;Vynuluj registr A a E,aby indikoval + LD E,A LD D,C ;Kopiruj mene vyznamny bajt do D a vyznamnejsi LD C,B ;bajt do C.Vycisti registr B LD B,A MONITOR ROM - ZX Spectrum - 107 - 2D7B RST #28 ;Pouzij kalkulator k vymazani vysled.mocniny deseti DEFB #02 ;vymaz DEFB #38 ;konec vypoctu RET ;Posledni hodnota je tedy x*10^m Subrutina "VYZVEDNUTI CELEHO CISLA" ----------------------------------- Tato rutina nacte do DE hodnotu "maleho" celeho cisla z mista adresovaneho registrovym parem HL.Tedy n je bezne prvnim (nebo druhym) cislem na zasobniku kalkulatoru,ale HL muze (po zamene s DE) dosahnout i cisla,ktere uz bylo ze zasobniku kalkulatoru "vymazano".Program sam o sobe nevymaze cislo ze zasobniku a vraci HL tak,ze ukazuje na ctvrty bajt cisla v jeho puvodni pozici.Poznamka: "male cele cislo" je kazde cislo n,pro ktere plati -65535<=n<=65535. 2D7F INC HL ;Ukazuj na znamenkovy bajt cisla LD C,(HL) ;a vyzvedni ho do C Nasledujici mechanismus provede dvojkovy doplnek cisla jestlize je zaporne (C obsahuje #FF).Jinak ho necha byt (C obsahuje #00). INC HL ;Ukazuj na mene vyznamny bajt a vyzvedni ho LD A,(HL) ;do A.Je-li cislo zaporne,proved jednickovy XOR C ;doplnek.Pricti 1 pro zaporna cisla SUB C ;a nastav CY,pokud bajt neni nulovy LD E,A ;Mene vyznamny bajt do E INC HL ;Ukazuj na vyznamnejsi bajt a vyzvedni jej do A LD A,(HL) ADC A,C ;Dokonci dvojkovou komplementaci v pripade XOR C ;negativniho cisla.CY je vzdy=0 LD D,A ;Vyznamnejsi bajt do D RET Subrutina "ULOZENI CELEHO CISLA" -------------------------------- Tato subrutina uklada hodnotu "maleho" celeho cisla na misto adresovane HL a ctyri dalsi mista.Tedy n nahradi prvni (nebo druhe) cislo na zasobniku kalkulatoru.HL se vraci s hodnotou adresy prvniho bajtu cisla n na zasobniku kalkulatoru. 2D8C LD C,#00 ;Tento vstupni bod je pouzit pro ukladani ce- 2D8E PUSH HL ;lych kladnych cisel.Ukazatel na prvni misto LD (HL),#00 ;je uschovan.Prvni bajt je nastaven na nulu INC HL ;Ukazuj na druhe misto a vloz znamenkovy bajt LD (HL),C Nyni je pouzit stejny zpusob vytvareni dvojkovych komplementu pro negativni cisla jako v rutine VYZVEDNUTI CELEHO CISLA.Toto je zapotrebi napriklad pred nebo po nasobeni malych celych cisel.Scitani se provadi bez jakychkoli komple- mentacnich uprav. INC HL ;Ukazuj na treti misto LD A,E ;Vyzvedni nizsi bajt XOR C ;Proved jeho pripadnou dvojkovou komplementaci SUB C LD (HL),A ;Uloz tento bajt INC HL ;Ukazuj na ctvrte misto LD A,D ;Vyzvedni vyssi bajt,opet proved odpovidajici ADC A,C ;upravy XOR C LD (HL),A ;Uloz i tento bajt INC HL ;Ukazuj na pate misto a vloz tam nulu LD (HL),#00 POP HL ;Vrat se s adresou prvniho bajtu cisla v HL RET Subrutina "FLOATING POINT TO BC" -------------------------------- Tento podprogram se vola ze ctyr ruznych mist pro ruzne ucely a je pouzivan ke kompresi FP hodnoty na zasobniku kalkulatoru do reg. paru BC.Je-li vysledek vetsi nez 65536,potom program nastavi CY na hodnotu jedna.Je-li posledni hod- nota negativni,potom Z roven nule.Nizsi bajt je take okopirovan do reg. A. 2DA2 RST #28 ;Pouzij kalkulator,aby HL ukazoval na STKEND-5 DEFB #38 ;konec vypoctu LD A,(HL) ;Vyzvedni exponentovy bajt.Je-li nulovy,skoc AND A ;nebot se jedna o male cele cislo JR Z,#2DAD RST #28 ;Pouzij kalkulator k zaokrouhleni posledni hodnoty DEFB #A2 ;STK-polovina na nejblizsi cele cislo,coz ho take DEFB #0F ;scitani prevede na tvar maleho celeho cisla, DEFB #27 ;int je-li to mozne DEFB #38 ;konec vypoctu 2DAD RST #28 ;Pouzij kalkulator k vymazani cisla.DE ukazuje DEFB #02 ;vymaz na cislo v pameti (na STKEND) DEFB #38 ;konec vypoctu PUSH HL ;Uschovej oba zasobnikove ukazatele PUSH DE MONITOR ROM - ZX Spectrum - 109 - 2DE3 RST #28 ;Kalkulator DEFB #31 ;zdvojeni x,x DEFB #36 ;<0 x,(1/0)(logic.hodnota x) DEFB #00 ;skok-pravda x DEFB #0B ;na PF-NEGTVE x DEFB #31 ;zdvojeni x,x DEFB #37 ;>0 x,(1/0)(logic.hodnota x) DEFB #00 ;skok-pravda x DEFB #0D ;na PF-POSTVE x kde jiz x' bude ABS x DEFB #02 ;vymaz DEFB #38 ;konec vypoctu LD A,#30 ;Vloz znak nula a vytiskni ho RST #10 ;Konec a posledni hodnota je nula RET 2DF2 DEFB #2A ;abs x' (x'=ABS x) DEFB #38 ;konec vypoctu x' LD A,#2D ;Vloz znak "-" a vytiskni ho RST #10 RST #28 ;Kalkulator 2DF8 DEFB #A0 ;STK-nula 15 bajtu pameti MEM-3,4 a 5 je nasta- DEFB #C3 ;ST-MEM-3 veno na nuly potrebne pro tiskovy DEFB #C4 ;ST-MEM-4 bafr a dve pocitadla.Zasobnik je vy- DEFB #C5 ;ST-MEM-5 vycisten az na x',HL',ktery bude DEFB #02 ;vymaz obsahovat kalkulatorove doplnky(napr. DEFB #38 ;konec vypoctu pro STR$),je ulozen na stroj.zasobnik EXX PUSH HL EXX b) Toto je start smycky,ktera zpracovava vetsi cisla.Nicmene kazde cislo x je rozdeleno na svou celou cast (i) a zlomkovou cast (f).Jedna-li se o male cele cislo,tedy -65535=0) CALL #2D7F LD B,#10 ;B,je nastaveno jako pocitadlo 16-ti bitu LD A,D ;D je okopirovano do A AND A ;Neni-li D nulove,skoc JR NZ,#2E1E OR E ;Nyni testuj E a jestlize JR Z,#2E24 ;DE je nula,skoc,nebot x je cisty zlomek LD DE ;Prenes E do D LD B,#08 ;Nastav B na osm bitu 2E1E PUSH DE ;Prenes za pomoci zasobniku DE do DE',aby jeho EXX ;hodnoty mohli byt preneseny do tiskoveho POP DE ;bafru v bode PF-BITS EXX JR #2E7B ;Skoc dopredu c) Ciste zlomky jsou nasobeny hodnotou 10^n,kde je priblizny pocet uvodnich nul za desetinnou carkou. -n je pricteno k druhemu bajtu MEM-5,ktery obsahuje pocet cislic pred desetinnou carkou.Zaporna cisla indikuji pocet nul za dese- tinnou carkou. 2E24 RST #28 ; i (i je zde nula) DEFB #E2 ;get-mem-2 i,f DEFB #38 ;konec vypoctu i,f !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Poznamka: Povsimnete si,ze zasobnik je nyni nevyvazen.K tomu by byl potreba dalsi bajt DEFB #02,vymaz na adrese #2E25 hned za instrukci RST #28.Proto nyni vyraz jako napr. "2+STR$ 0.5" je nespravne ohodnocen jako 0.5: nula ponechana na zasobniku nahradi dvojku a vse je povazovano za nulovy retezec.Tim padem i retezcova porovnani mohou vest k nespravnym hodnotam,kdyz druhy retezec ma formu STR$ x a x<1,tedy napr.vyraz "50"=A>=111 ADD A,#91 ;Rozsah je 15>=A>=0 INC HL ;HL nyni ukazuje na druhy bajt a ten je prene- LD D,(HL) ;sen do D INC HL LD E,(HL) ;Treti bajt do E DEC HL ;HL opet ukazuje na prvni bajt DEC HL ;Predpokladej kladne cislo LD C,#00 BIT 7,D ;Testuj zaporne cislo (bit 7 reg. D je 1) JR Z,#3252 ;Pri kladnem cisle skoc DEC C ;Zmen znamenko 3252 SET 7,D ;Vloz skutecny numericky bit do registru D LD B,#08 ;Testuj,zda A>=8 (jen jeden bajt),nebo je-li SUB B ;treba dvou bajtu ADD A,B ;Ponech A nezmenene JR C,#325E ;Skoc,jsou-li potreba dva bajty LD E,D ;Dej jeden bajt do E LD D,#00 ;Nastav D na nulu SUB B ;Nyni 1<=A<=7 pocita potrebne posuny 325E JR Z,#3267 ;Neni-li nutny posun,skoc LD B,A ;B bude pocitat posuvy 3261 SRL D ;Posunuj B-krat doprava D a E,aby vzniklo RR E ;spravne cislo DJNZ #3261 ;Opakuj no vynulovani B 3267 CALL #2D8E ;Uschovej vysledek na zasobniku POP DE ;Obnov STKEND v DE RET Zbyva posoudit velke hodnoty cisla x. 326C LD A,(HL) ;Vyzvedni exponentovy bajt cisla x do reg. A 326D SUB #A0 ;Odecti 160=#A0 od exponentu.Pri plus se vrat, RET P ;x ma nevyznamnou celociselnou cast.Jinak ne- NEG ;guj zbytek,tim ziskas pocet nulovanych bajtu Zde budou vynulovany bity mantisy. 3272 PUSH DE ;Uschovej aktualni hodnotu DE (STKEND) EX DE,HL ;HL ukazuje jedno misto za paty bajt a nasle- DEC HL ;dovne primo na paty bajt cisla x.Vezmi do B LD B,A ;pocet bitu,ktere maji byt nulovany a vydel SRL B ;jej osmi,abys ziskal pocet bajtu bajtu SRL B ;kterych se to tyka SRL B JR Z,#3283 ;Pri nulovem vysledku skoc 327E LD (HL),#00 ;Nastav B bajtu na nulu DEC HL DJNZ #327E 3283 AND #07 ;Vyzvedni (A mod 8),coz je pocet bitu,ktere JR Z,#3290 ;maji byt nulovany LD B,A LD A,#FF ;Priprav masku 328A SLA A ;Pri kazdem pruchodu smyckou je zprava do A DJNZ #328A ;vsunuta dalsi nula,cimz se vytvari spravna AND (HL) ;maska.Nepotrebne bity jsou pomoci masky LD (HL),A ;vynulovany 3290 EX DE,HL ;Vrat ukazatel do HL POP DE ;Vrat STKEND do DE RET Podprogram "RE-STACK-TWO" ------------------------- Tento podprogram vytvari ze dvou "malych" celych cisel plnohodnotna cisla v FP forme.Toto je dosazeno volanim nasledujiciho podprogramu dvakrat. 3293 CALL #3296 ;Volej podprogram a pokracuj do nej jako druhe 3296 EX DE,HL ;zavolani.Pri kazdem volani zamen ukazatele Podprogram "RE-STACK" --------------------- Doplnek: #3D "RE-STACK" Tento podprogram vyzvedne a opet ulozi jedno cislo,ktere se ovsem zmeni z "maleho" celeho cisla na cislo v plnohodnotnem petibajtovem FP vyjadreni. Pro jedno cislo je pouzivan podprogramem ARCTAN a pres kalkulatorovy doplnek funkcemi EXP,LN a "GET-ARGT" 3297 LD A,(HL) ;Neni-li prvni bajt nulovy vrat se,nebot cislo AND A ;urcite neni "male" cele cislo RET NZ MONITOR ROM - ZX Spectrum - 123 - TABULKA ADRES ------------- Druha tabulka slouzi k vyhledavani adres 66ti operacnich podprogramu kalkula- toru.Doplnky,ktere umoznuji indexovani v teto tabulce jsou odvozeny bud z ri- dicich kodu,pouzitych v rutine SCANNING viz. #2734,nebo z literalu,ktere na- sleduji po instrukci RST #28. doplnek nazev adresa doplnek nazev adresa 32D7 00 skok-pravda 368F | 3319 21 TAN 37DA 32D9 01 zamena 343C | 331B 22 ASN 3833 32DB 02 vymaz 33A1 | 331D 23 ACS 3843 32DD 03 odecteni 300F | 331F 24 ATN 37E2 32DF 04 nasobeni 30CA | 3321 25 LN 3713 32E1 05 deleni 31AF | 3323 26 EXP 36C4 32E3 06 umocneni 3851 | 3325 27 INT 36AF 32E5 07 cislo OR cislo 351B | 3327 28 SQR 384A 32E7 08 cislo AND cislo 3524 | 3329 29 SGN 3492 32E9 09 cislo <= cislo 353B | 332B 2A ABS 346A 32EB 0A cislo >= cislo 353B | 332D 2B PEEK 34AC 32ED 0B cislo <> cislo 353B | 332F 2C IN 34A5 32EF 0C cislo > cislo 353B | 3331 2D USR-NO 34B3 32F1 0D cislo < cislo 353B | 3333 2E STR$ 361F 32F3 0E cislo = cislo 353B | 3335 2F CHR$ 35C9 32F5 0F scitani 3014 | 3337 30 NOT 3501 32F7 10 retezec AND cislo 352D | 3339 31 zdvojeni 33C0 32F9 11 retezec <= retezec 353B | 333B 32 N-mod-M 36A0 32fB 12 retezec >= retezec 353B | 333D 33 relativni skok 3686 32fD 13 retezec <> retezec 353B | 333F 34 STK-data 33C6 32FF 14 retezec > retezec 353B | 3341 35 DEC-JR-NZ 367A 3301 15 retezec < retezec 353B | 3343 36 cislo < 0 3506 3303 16 retezec = retezec 353B | 3345 37 cislo > 0 34F9 3305 17 retezec + retezec 359C | 3347 38 konec vypoctu 369B 3307 18 VAL$ 35DE | 3349 39 GET-argument 3783 3309 19 USR$ 34BC | 334B 3A int se zaokrouhlenim 3214 330B 1A nacteni do A 3645 | 334D 3B FP-CALC-2 33A2 330D 1B negace 346E | 334F 3C E-na-FP 2D4F 330F 1C CODE 3669 | 3351 3D RE-STACK 3297 3311 1D VAL 35DE | 3353 3E serie 06 atd. 3449 3313 1E LEN 3674 | 3355 3F STK-nula atd. 341B 3315 1F SIN 37B5 | 3357 40 STK-MEM0 atd. 2D34 3317 20 COS 37AA | 3359 41 GET-MEM0 atd. 340F Poznamka: Posledni ctyri podprogramy jsou viceucelove a vstupuje se do nich s parametrem,ktery je kopii bitu 0 az 4 puvodniho literalu: Doplnek #3E: serie #06,serie #08 a serie #0C odpovida literalum: #86,#88 a #8C Doplnek #3F: STK-nula,STK-jedna,STK-polovina,STK-PI/2,STK-deset odpovida lite- ralum #A0 az #A4 Doplnek #40: ST-MEM-0 az ST-MEM-5 odovida literalum #C0 az #C5 Doplnek #41: GET-MEM-0 az GET-MEM-5 odpovida literalum #E0 az #E5 Podprogram "CALCULATE" ---------------------- Tento podprogram provadi vypocty s cisly ve forme s pohyblivou radovou teckou. (Dale jen FP).Vypocty lze rozdelit do tri skupin: a) Binarni operace napriklad scitani,kdy dve FP cisla jsou sectena a vysledek pak tvori "posledni hodnotu" b) Unarni operace napriklad sin,kdy "posledni hodnota" je zmenena tak,ze je vysledkem dane operace c) Manipulacni operace napriklad ST-MEM-0,kde "posledni hodnota" je okopirova- na do prvnich peti bajtu pameti kalkulatoru Operace,ktere se maji provest jsou specifikovany sledem datovych bajtu takzva- nych literalu,ktere nasleduji po instrukci RST #28 a tento sled musi byt za- koncen literalem #38 - konec vypoctu.V pripade potreby vykonani jedine pocetni operace je mozne vlozit doplnek do registru B a vyvolat operaci jedineho vy- poctu pomoci literalu #3B.Take je mozne volat tuto rutinu rekursivne,tedy ze sama sebe a v takovem pripade lze pouzit systemovou promennou BREG jako citac, ktery ridi pocet operaci pred navratem.Prvni cast teto subrutiny nastavuje registry na pozadovane hodnoty,vypocitava doplnky a pripadne parametry z lite- ralu,ktere jsou testovany.Doplnek slouzi k vyhledani adresy prislusne subrutiny v tabulce konstant.Parametry jsou pouzity pri volani viceucelovych subrutin. Poznamka: FP cislo muze byt ve skutecnosti take soubor retezcovych parametru. 335B CALL #35BF ;Predpokladej unarni operaci a proto nastav HL 335E LD A,B ;tak,aby ukazovalo na 1.bajt"posledni hodnoty" LD (#5C67),A ;a DE na STKEND.Jinak predej doplnek jednoduche 3362 EXX ;operace do BREG pri rekurzivnim volani se ne- EX (SP),HL ;jedna o doplnek,ale o parametr (=citac) EXX ;Navratova adresa podprogramu je ulozena v zr- 3365 LD (#5C65),DE ;cadlovem HL.Toto cislo je take ukazatelem EXX ;na prvni literal.Vstup v tomto miste se pou- LD A,(HL) ;ziva,kdyz BREG je pozit jako citac a nema se INC HL ;znicit.Zde zacina smycka obsluhujici vsechny MONITOR ROM - ZX Spectrum - 125 - Podprogram "MOVE A FLOATING-POINT NUMBER" ----------------------------------------- Doplnek: #31 "DUPLICATE" Tento podprogram prenese FP cislo na vrchol zasobniku (ve trech pripadech), nebo z vrcholu kalkulatoru do pameti kalkulatoru (v jednom pripade).Je take pouzivan kalkulatorem pro obycejne zdvojeni cisla na vrcholu kalkulatoru,cimz se zasobnik kalkulatoru rozsiri o pet bajtu. 33C0 CALL #33A9 ;Testuje se misto LDIR ;Prenes pet aktualnich bajtu RET Podprogram "STACK LITERALS" --------------------------- Doplnek: #34 "STK-data" Tento podprogram vytvori z dodaneho cisla 2,3,4 nebo 5 literalu a umisti je jako posledni hodnotu na zasobnik kalkulatoru.Je-li tento podprogram vyvolan litaralem #34,jsou uvazovane literaly ulozeny za touto konstantou,je-li volan podprogramem SERIES GENERATOR,jsou litaraly dodany podprogramem vytvarejicim posloupnosti cisel a je-li volan podprogramy SKIP CONSTANTS nebo STACK A CONS- TANT,jsou litaraly ziskany z tabulky konstant na adrese #32C5-#32D6.V kazdem pripade je prvni literal vydelen hodnotou #40 a celociselna hodnota podilu plus jedna urci,zda bude pouzito 1,2,3 nebo 4 nasledujicich literalu jako cisla mantisy.Kazdy nevyplneny bajt z peti bajtu pro FP cislo je nastaven na nulu. Prvni literal se take pouziva k urceni exponentu po snizeni modulo #40,pokud ovsem zbytek neni nulovy.V tom pripade se pouzije druhy literal tak jak je,bez snizovani modulo #40.V kazdem pripade se k literalu pricte #50,cimz se vytvori zvetseny exponentovy bajt e (skutecny exponent e' plus #80).Zbyvajicich pet bajtu je ulozeno na zasobnik vcetne potrebnych nul a podprogram pokracuje. 33C6 LD H,D ;Tento podprogram provadi manipulacni operaci LD L,E ;pricteni posledni hodnoty na zasobnik kalku- 33C8 CALL #33A9 ;latoru,HL ukazuje za posledni hodnotu,tedy EXX ;na vysledek.Testuj potrebny prostor.Prepni PUSH HL ;na zrcadlove registry.Uschovej ukazatel EXX ;na dalsi literal.Prepni zpet EX (SP),HL ;Zamen vysledny ukazatel a ukazatel na dalsi PUSH BC ;literal.Uschovej kratce BC LD A,(HL) ;Vyzvedni prvni literal do A AND #C0 ;Vydel ho #40 pro dosazeni hodnot 0,1,2 nebo 3 RLCA RLCA ;Celociselna cast e je predana do C LD C,A ;a inkrementovana pro dosazeni hodnoty 1,2,3,4 INC C ;(=pocet literalu mantisy) LD A,(HL) ;Opet je vyzvednut literal,snizen o hodnotu AND #3F ;modulo #40 a bude pouzit pri nenulovem zbytku JR NZ,#33DE INC HL ;Jinak bude pouzit dalsi neredukovany literal LD A,(HL) 33DE ADD A,#50 ;Exponent e je formovan prictenim hodnoty #50 LD (DE),A ;a predan na zasobnik jako 1.z peti bajtu vy- LD A,#05 ;sledku SUB C ;C literalu je vyzvednuto ze zdroje INC HL INC DE LD B,#00 ;a ulozeno do bajtu vysledku LDIR POP BC ;Obnov BC EX (SP),HL ;Zamen zpet ukazatel vysledku a ukazatel EXX ;dalsiho literalu na zasobniku a v H'L' POP HL EXX LD B,A ;Pocet nulovych bajtu je udan hodnotou 5-C-1 XOR A 33F1 DEC B RET Z LD (DE),A ;a tento pocet nul je pridan k vysledku, INC DE ;aby byl doplnen pozadovany pocet bajtu JR #33F1 Podprogram "SKIP KONSTANTS" --------------------------- Do tohoto podprogramu se vstupuje s reg. parem HL obsahujicim bazovou adresu tabulky konstant a reg. A obsahujicim parametr urcujici jednu z peti konstant. Podprogram provadi nulove operace prenasenim peti bajtu kazde nepotrebne kon- stanty na adresy #0000,#0001,#0002,#0003 a #0004 v pameti ROM az do nalezeni pozadovane konstanty.Na vystupu obsahuje HL bazovou adresu pozadovane konstanty v tabulce konstant. 33F7 AND A ;Je-li parametr nula,nebo byla-li nalezena 33F8 RET Z ;potrebna konstanta,vrat se PUSH AF ;Uschovej parametr a ukazatel vysledku PUSH DE MONITOR ROM - ZX Spectrum - 127 - Podprogram "EXCHANGE" (zamena) ------------------------------ Doplnek: #01 "EXCHANGE" Tato binarni operace zameni prvni a druhe cislo na vrcholu zasobniku kalkulatoru 343C LD B,#05 ;Jedna se o pet bajtu 343E LD A,(DE) ;Kazdy bajt druheho a prvniho cisla LD C,(HL) EX DE,HL ;Prepni zdroj a cil LD (DE),A ;Na prvni a na druhe cislo LD (HL),C INC HL ;Presun se na posouzeni dalsiho paru bajtu INC DE DJNZ #343E ;Zamen pet bajtu.Zamen ukazatele, EX DE,HL ;nebot cislo 5 je liche RET Podprogram "SERIES GENERATOR" (generator rad) --------------------------------------------- Doplnky: #86,#88 a #8C "SERIES-06","SERIES-08","SERIES-0C" Tento dulezity podprogram generuje rady rozvojem Cebysevovych polynomu a jejich hodnoty jsou pak pouzity k vypoctu hodnot funkci SIN,ATN,LN a EXP a tim padem i dalsich matematickych funkci,ktere jsou s predchozimi v najakem matematickem vztahu (COS,TAN,ASN,ACS,...,SQR).Rady jsou generovany pro n=1,2,....,rekurent- nim vztahem: T n+1 (z)=2*z*T n(z)-T n-1(z),kde T n(z) je prvek Cebysevova po- lynomu argumentu z.Rada ve skutecnosti vypada 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 techto polynomech naleznete v knize Handbook of Mathematical Functions od M.Abramowitze a I.A.Steguna (Dover 1965),strana 795.Jednoduse receno,pod- program je volan s posledni hodnotou na zasobniku kalkulatoru,rekneme Z,coz je cislo,majici nejaky jednoduchy vztah k argumentu,rekneme X,napriklad pro funkci SIN X.Volajici podprogram take dodava seznam pozadovanych konstant (napr.pro SIN).SERIES GENERATOR pak pracuje s temito daty a vraci volajicimu podprogramu "posledni hodnotu",ktera obsahuje jednoduchy vysledek pro kazdou funkci,napr. SIN X.Podprogram muze byt rozdelen na ctyri hlavni casti: 1) Nastaveni citace pruchodu smyckou: Volajici podprogram preda sve parametry v reg. A pro pouziti jako citac.Do kalkulatoru se vstoupi v bode GEN-ENT-1, takze citac muze byt nastaven. 3449 LD B,A ;Predej parametr do B CALL #335E ;Toto je RST #28,ale s nastavenim citace 2) Prace s posledni hodnotou Z: Smycka generatoru vyzaduje, aby hodnota 2*Z byla ulozena v MEM-0,v MEM-2 ma byt ulozena nula,ktera ma byt zaroven posledni hodnotou. DEFB #31 ;zdvojeni Z,Z DEFB #0F ;soucet 2*Z DEFB #C0 ;ST-MEM-0 2*Z do MEM-0 DEFB #02 ;vymaz DEFB #A0 ;STK-nula 0 DEFB #C2 ;ST-MEM-2 0 do MEM-2 3) Hlavni smycka: Rada je generovana ve smycce s pouzitim BREG jako citace. Konstanty z volajiciho podprogramu jsou postupne ukladany na zasobnik rutinou STK-DATA.Je proveden opetovny vstup do kalkulatoru v bode GEN-ENT-2,tak,aby se neznicila hodnota v BREG a rada se vytvari v teto forme: 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 kon- stanty dodane volajicim podprogramem (SIN,ATN,LN a EXP) a B(0)=0=B(-1). R+prvni smycka zacina s B(R) na zasobniku a s 2*Z,B(R-2) a B(R-1) v MEM-0, MEM-1 a MEM-2. 3453 DEFB #31 ;zdvojeni B(R),B(R) DEFB #E0 ;GET-MEM-0 B(R),B(R),2*Z DEFB #04 ;nasobeni B(R),2*B(R)*Z DEFB #E2 ;GET-MEM-2 B(R),2*B(R)*Z,B(R-1) DEFB #C1 ;ST-MEM-1 B(R-1) do MEM-1 DEFB #03 ;odecet B(R),2*B(R)*Z-B(R-1)=Q DEFB #38 ;konec vypoctu Na zasobnik kalkulatoru je umistena dalsi konstanta. CALL #33C6 ; B(R),Q,A(R+1) Toto je opetovny vstup do kalkulatoru bez poskozeni BREG. CALL #3362 DEFB #0F ;soucet B(R),Q+A(R+1) DEFB #01 ;zamena Q+A(R+1),B(R) DEFB #C2 ;ST-MEM-2 B(R) do MEM-2 DEFB #02 ;vymaz Q+A(R+1)=B(R+1) DEFB #35 ;DEC-JR-NZ B(R+1) DEFB #EE ;na #3453 G-LOOP MONITOR ROM - ZX Spectrum - 129 - Funkce "PEEK" ------------- Doplnek: #2B "PEEK" Tento podprogram provazi funkci PEEK X."Posledni hodnota" je odebrana ze zasobniku za pomoci FIND-INT2 a nahrazena hodnotou ulozenou na prislusnem pametovem miste. 34AC CALL #1E99 ;"Posledni hodnota" je kompresovana do BC LD A,(BC) ;Vyzvedni pozadovany bajt 34B0 JP #2D28 ;Vystup pres STACK-A Funkce "USR" ------------ Doplnek: #2D "USR-NO" Tento podprogram ("USR cislo" je neco jineho nez "USR retezec") obsluhuje funkci USR X,kde X je cislo.Hodnota cisla X je ulozena do BC,navratova adresa je ulozena na zasobnik a program je proveden od adresy X. 34B3 CALL #1E99 ;"Posledni hodnota" je kompresovana do BC LD HL,#2D2B ;Vloz navratovou adresu podprogramu STACK-BC PUSH HL ;Uloz startovaci adresu volaneho podprogramu PUSH BC ;a proved neprimy skok na tento podprogram RET !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Poznamka: Je zajimave,ze registrovy par IY je znovu nastaven na svou puvodni hodnotu po navratu pres STACK-BC,ale dulezity ukazatel na posledni literal ktery je v H'L' obnoven neni.Proto pro uspesny navrat do basiku musi zrcadlove HL obsahovat adresu instrukce "end-calc" v podprogramu SCANNING,ktera je na adrese #2758. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Funkce "USR STRING" ------------------- Doplnek: #19 "USR-$" Podprogram provede funkci USR X$,kde X$ je retezec a v BC vraci adresu bitove matice znaku uzivatelsky definovane grafiky,odpovidajici znaku ulozenemu v X$. Podprogram hlasi chybu A,kdyz X$ neni jedine pismeno v rozsahu od "a" do "u". 34BC CALL #2BF1 ;Vyzvedni parametry retezce X$ DEC BC ;Sniz delku o jedna pro test LD A,B OR C JR NZ,#34E7 ;Nebyla-li delka jedna,skoc a ohlas chybu LD A,(DE) ;Jinak vyzvedni jediny kod retezce CALL #2C8D ;Jestlize predstavuje pismeno,skoc na vyzved- JR C,#34D3 ;nuti jeho adresy SUB #90 ;Sniz adresu na skutecnych 0-20 a ohlas chybu JR C,#34E7 ;A,je-li znak mimo rozsah CP #15 ;Opet testuj rozsah a ohlas chybu A,je-li znak JR NC,#34E7 ;mimo rozsah.Uprav rozsah na 1-21,jako rozsah INC A ;pro "a" az "u" 34D3 DEC A ;Nyni bude rozsah 1-20 ADD A,A ;Vynasobenim osmi se ziska doplnek pro adresu ADD A,A ADD A,A CP #A8 ;Testuj rozsah doplnku a ohlas chybu A, JR NC,#34E7 ;je-li mimo rozsah LD BC,(5C7B) ;Vyzvedni adresu prvniho bajtu uzivatelsky ADD A,C ;definovane grafiky do BC a pricti C k doplnku LD C,A ;Vyledek vloz zpet do C JR NC,#34E4 ;Nedoslo-li k prenosu,skoc,jinak inkrementuj B INC B 34E4 JP #2D2B ;Uloz adresu 34E7 RST #08 ;Ohlas: A-Invalid argument DEFB #09 Podprogram "TEST-ZERO" (test-nula) ---------------------------------- Podprogram je volan nejmene devetkrat k otestovani FP cisla,je-li nulove.Tento test vyzaduje,aby vsechny ctyri bajty cisla byly nulove.Podprogram se vraci s CY=1 bylo-li cislo skutecne nula. 34E9 PUSH HL ;Uschovej HL a take BC PUSH BC LD B,A ;Uschovej hodnotu A v registru B LD A,(HL) ;Vyzvedni prvni bajt INC HL ;Ukazuj na 2.bajt OR (HL) ;Proved logicke OR INC HL ;Ukazuj na 3.bajt OR (HL) ;Proved logicke OR INC HL ;Ukazuj na 4.bajt OR (HL) ;Proved logicke OR LD A,B ;Obnov puvodni hodnotu v registru A POP BC ;v registrech BC a HL POP HL RET NZ ;Vrat se s CY=0,jestlize byl kterykoli ze ctyr SCF ;bajtu nenulovy.Nastav CY=0 jako signal,ze ci- RET ;slo bylo nula a vrat se MONITOR ROM - ZX Spectrum - 131 - Operace "STRING AND NUMBER" --------------------------- Doplnek: #10 "STR & NO" Podprogram provadi binarni operaci "X$ AND Y" a vraci X$ jestlize Y je nenulo- ve,jinak vraci nulovy retezec. 352D EX DE,HL ;HL ukazuje na Y,DE na X$ CALL #34E9 ;Testuj,zda je Y nulove EX DE,HL ;Zamen zpet ukazatele.Vrat se s X$ posledni RET NC ;hodnotou,kdyz Y nebylo nula PUSH DE ;Uschovej ukazatel na cislo DEC DE ;Ukazuj na 5.bajt parametru retezce,tedy XOR A ;na vyssi bajt delky.Nuluj registr A LD (DE),A ;Vyssi bajt delky je nyni nastaven na nulu DEC DE ;Ukazuj na nizsi bajt delky LD (DE),A ;Take jej nastav na nulu POP DE ;Obnov ukazatel.Vrat se s parametry retezce RET ;jako "posledni hodnotou" Operace "COMPARISON" -------------------- Doplnky: #09 az #0E a #11 az #16 "NO-L-EQL","NO-QR-EQL","NOS-NEQL","NO-QRTR", "NO-LESS","NOS-EQL","STR-L-EQ","STR-QR-EQ","STR$-NEQL","STR-QRTR","STR-LESS" a "STR$-EQL" Tento podprogram se pouziva k provedeni dvanacti moznych porovnavacich operaci.Operacni doplnek dane operace je na vstupu v registru B. 353B LD A,B ;Doplnek do registru A SUB #08 ;Rozsah je #01-#06 a #09-#0E.Tento rozsah je BIT 2,A ;zmenen na #00-#02,#04-#06,#08-#0A a #0C-#0E JR NZ,#3543 DEC A 3543 RRCA ;Dale snizen na #00-#07 a CY=1 pro ">=" a "<" JR NC,#354E ;Operace s CY=1 jsou povazovany za sve komple- PUSH AF ;mentarni operace jakmile jsou hodnoty zameneny PUSH HL CALL #343C POP DE EX DE,HL POP AF 354E BIT 2,A ;Ciselna porovnani jsou oddelena od ciselnych JR NZ,#3559 ;porovnani otestovanim bitu 2 RRCA PUSH AF ;Uschovej doplnek CALL #300F ;Cisla jsou odectena pro zaverecne testy JR #358C 3559 RRCA ;Retezcova porovnani maji rozsah #02-#03, PUSH AF ;s CY=1 pro "=" a "<>".Uschovej doplnek CALL #2BF1 ;Delky a pocatecni adresy jsou vyzvednuty PUSH DE ;ze zasobniku kalkulatoru PUSH BC CALL #2BF1 POP HL ;Delka druheho retezce 3564 LD A,H OR L EX (SP),HL LD A,B JR NZ,#3575 ;Skoc pokud druhy retezec neni nulovy OR C 356B POP BC ;Zde je 2.retezec bud nulovy nebo mensi nez 1. JR Z,#3572 POP AF CCF ;CY je komplementovano k dosazeni spravneho JR #3588 ;vysledku testu 3572 POP AF ;Zde je CY pouzito tak,jak je JR #3588 3575 OR C ;Prvni retezec je nyni nulovy,druhy ne JR Z,#3585 ;Ani jeden retezec neni nulovy takze mohou byt LD A,(DE) ;porovnany jejich dalsi bajty SUB (HL) JR C,#3585 ;Prvni bajt je mensi JR NZ,#356B ;Druhy bajt je mensi DEC BC ;Bajty se rovnaji,takze delky jsou dekremento- INC DE ;vany INC HL EX (SP),HL DEC HL ;Proved skok na BYTE-COMP k porovnani dalsich JR #3564 ;bajtu 3585 POP BC POP AF AND A ;CY je vynulovano pro dosazeni spravnych 3588 PUSH AF ;vysledku.Pro retezcove testy je na zasobnik RST #28 ;kalkulatoru ulozena 0 DEFB #A0 ;STK-nula DEFB #38 ;konec vypoctu MONITOR ROM - ZX Spectrum - 133 - 35DE LD HL,(#5C5D) ;Aktualni hodnota CH-ADD je ulozena na zasobnik PUSH HL LD A,B ;Doplnek do A.Vytvor #00 a CY=1 pro "VAL" nebo ADD A,#E3 ;#FB a CY=0 pro "VAL$".Vytvor #FF (bit 6=1) SBC A,A ;pro "VAL" a #00 pro "VAL$" PUSH AF ;Uschovej vlajku.Vyzvedni parametry retezce, CALL #2BF1 ;uschovej jeho zacatek,inkrementuj delku PUSH DE ;a vytvor misto v pracovnim prostoru INC BC ;Obnov zacatek retezce v HL RST #30 POP HL ;Ukazatel na prvni nove vytvorene misto jde LD (#5C5D),DE ;do CH-ADD a na zasobnik PUSH DE ;Kopiruj retezec do vytvoreneho prostoru LDIR EX DE,HL ;Zamen ukazatele DEC HL ;Bajt "navic" je nahrazen znakem "CR" LD (HL),#0D ;Nuluj vlajku "SYNTAX/RUN" a proved kontrolu RES 7,(IY+1) ;syntaxe CALL #24FB RST #18 ;Vyzvedni znak za retezcem CP #0D ;Pokud to neni znak "CR",ohlas chybu JR NZ,#360C POP HL ;Obnov zacatek retezce v HL POP AF ;Vyzvedni vlajku "VAL/VAL$" a testuj bit 6 XOR (IY+1) ;oproti vysledku kontroly syntaxe AND #40 360C JP NZ,1C8A ;Ohlas chybu,pokud se neshoduji LD (#5C5D),HL ;Zacatek retezce do CH-ADD SET 7,(IY+1) ;(FLAGS) Signal: program v behu CALL #24FB ;Retezec je zpracovan jako "dalsi vyraz" POP HL ;a jeho hodnota ulozena.Vyzvedni a obnov LD (#5C5D),HL ;puvodni hodnotu v CH-ADD.Vrat se pres JR #35BF ;STK-PNTRS,coz nastavi systemove ukazatele FUNKCE "STR$" ------------- Doplnek: #2E "STR$" Podprogram provede funkci STR$ X a vraci parametry retezce,obsahujiciho ten samy text,ktery se objevil na obrazovce pri provedeni prikazu PRINT X. 361F LD BC,#0001 ;Vytvor jedno misto v pracovnim prostoru, RST #30 ;kopiruj jeho adresu do K-CUR a take ji uloz LD (#5C5B),HL ;na zasobnik PUSH HL LD HL,(#5C51) ;Aktualni kanalova adresa je ulozena PUSH HL ;na zasobnik LD A,#FF ;Otevri kanal "R",coz umozni"vypsani"vysledku CALL #1601 ;do pracovniho prostoru CALL #2DE3 ;Vypis posledni hodnotu do pracovniho prostoru POP HL ;Vyzvedni kanalovou adresu a obnov prislusne CALL #1615 ;vlajky.Obnov zacatek retezce v DE POP DE LD HL,(#5C5B) ;Adresa kurzoru ukazuje jedno misto za retezec AND A ;a proto rozdil ukazatelu je delkou retezce, SBC HL,DE ;ktera je prevedena do BC LD B,H LD C,L CALL #2AB2 ;Parametry retezce jsou ulozeny na zasobnik EX DE,HL ;kalkulatoru.Zamen ukazatele RET Podprogram "READ-IN" -------------------- Doplnek: #1A "READ-IN" Tento podprogram je volan pres kalkulator pomoci doplnku z prvniho radku rutiny INKEY$.Umoznuje nacitani dat pres odlisne proudy,nez jsou ve standartnim SPECTRU.Stejne jako INKEY$,vraci i tento podprogram parametry retezce. 3645 CALL #1E94 ;Kompresuj ciselny parametr do A a jestlize CP #10 ;neni mensi nez 16,ohlas chybu JP NC,#1E9F LD HL,(#5C61) ;Aktualni kanalova adresa jde na zasobnik PUSH HL CALL #1601 ;Otevri kanal specifikovany parametrem a prijmi CALL #15E6 ;jakoby "hodnotu klavasy" LD BC,#0000 ;Delka retezce pri "neplneni je 0 JR NC,#365F ;Skoc, kdyz nebyl zadny signal INC C ;Nastav delku na 1,vytvor tento prostor a vloz RST #30 ;do nej retezec LD (DE),A 365F CALL #2AB2 ;Predej parametry retezce na zasobnik kalkula- POP HL ;toru.Vyzvedni kanalovou adresu a obnov pri- CALL #1615 ;slusne vlajky.Vrat se pres STK-PNTRS,coz JP #35BF ;nastavi systemove ukazatele MONITOR ROM - ZX Spectrum - 135 - Podprogram "MODULUS" -------------------- Doplnek: #32 "N-MOD-M" Podprogram pocita (N mod M),kde M je cele cislo na vrcholu zasobniku kalkula- toru a N je cele cislo pod vrcholem zasobniku.Podprogram vraci celociselnou cast podilu INT(N/M) na vrcholu zasobniku (tedy jako posledni hodnotu) a pod vrchol zasobniku ulozi zbytek N-M*INT(N/M).Podprogram se pouziva pri vypoctu nahodnych cisel ke snizeni N mod 65537 (dec.). 36A0 RST #28 ; N,M DEFB #C0 ;ST-MEM-0 N,M do MEM-0 DEFB #02 ;vymaz N DEFB #31 ;zdvojeni N,N DEFB #E0 ;GET-MEM-0 N,N,M DEFB #05 ;deleni N,N/M DEFB #27 ;int N,INT(N/M) DEFB #E0 ;GET-MEM-0 N,INT(N/M),M DEFB #01 ;zamena N,M,INT(N/M) DEFB #C0 ;ST-MEM-0 N,M,INT(N/M) INT(N/M) do MEM-0 DEFB #04 ;nasobeni N,M*INT(N/M) DEFB #03 ;odecitani N-M*INT(N/M) DEFB #E0 ;GET-MEM-0 N-M*INT(N/M),INT(N/M) DEFB #38 ;konec vypoctu RET Funkce "INT" ------------ Doplnek: #27 "INT" Podprogram vraci jako posledni hodnotu celociselnou cast cisla,ktere je pri vstupu na vrcholu zasobniku kalkulatoru.Tedy INT 2.4 dava 2,ale protoze pod- program zaokrouhluje smerem dolu,bude INT -2.4 roven -3. 36AF RST #28 ; X DEFB #31 ;zdvojeni X,X DEFB #36 ;<0 X,(1/0) (log. hodnota) DEFB #00 ;skok-pravda X DEFB #04 ;na #36B7,X-NEG X Pro pripad,ze X>=0,se nyni DEFB #3A ;truncate I(X) nalezne celociselna cast X DEFB #38 ;konec vypoctu RET Pro zaporne cislo se vraci hodnota I(X),pro ostatni cisla se vraci I(X)-1. 36B7 DEFB #31 ;zdvojeni X,X DEFB #3A ;truncate X,I(X) DEFB #C0 ;ST-MEM-0 X,I(X) I(X) jde do MEM-0 DEFB #03 ;odecitani X-I(X) DEFB #E0 ;GET-MEM-0 X-I(X),I(X) DEFB #01 ;zamena I(X),X-I(X) DEFB #30 ;not I(X),(1/0) (log.hodnota) DEFB #00 ;skok-pravda I(X) Pro zaporna cisla se provede DEFB #03 ;na #36C2,EXIT I(X) preskok DEFB #A1 ;stk-jedna I(X),1 DEFB #03 ;odecitani I(X)-1 36C2 DEFB #38 ;konec vypoctu I(X) nebo I(X)-1 RET Funkce "EXPONENTIAL" -------------------- Doplnek: #26 "EXP" Podprogram provadi funkci EXP X a je prvnim ze ctyr podprogramu,ktere pouzivaji SERIES GENERATOR k vytvareni Cebysevovych polynomu.Aproximace EXP X je nalezena takto: a) X je deleno LN 2 k ziskani Y,2^Y dava pozadovany vysledek b) Je nalezena hodnota N,pro kterou plati,ze N=INT Y c) Je nalezena hodnota W,pro kterou plati,ze W=Y-N (0<=W<=1) d) Je vytvoren argument Z takovy,ze Z=2*W-1 e) Pouzitim SERIES GENERATOR se ziska hodnota 2^W f) Konecne se pricte N k exponentu,coz dava 2^(N+W),neboli 2^Y a tedy pozado- vany vysledek EXP X. 36C4 RST #28 ; X DEFB #3D ;RE-STACK X (X ve forme FP) DEFB #34 ;STK-DATA X,1/LN 2 DEFB #F1 ;exponent #81 DEFB #38,#AA,#3B,#29 DEFB #04 ;nasobeni X/LN 2=Y DEFB #31 ;zdvojeni Y,Y DEFB #27 ;int 1C46 Y,YNT Y=N DEFB #C3 ;ST-MEM-3 N do MEM-3 DEFB #03 ;odecitani Y-N=W DEFB #31 ;zdvojeni W,W DEFB #0F ;scitani 2*W MONITOR ROM - ZX Spectrum - 137 - DEFB #03 ;odecitani e',x',x',-0.8 DEFB #37 ;>0 e',x' (1/0) DEFB #00 ;skok-pravda e',x' DEFB #08 ;na 373D,GRE.8 e',x DEFB #01 ;zamena x',e' DEFB #A1 ;STK-jedna x',e',1 DEFB #03 ;odecitani x',e'-1 DEFB #01 ;zamena e',-1,x' DEFB #38 ;konec vypoctu e'-1,x' INC (HL) ; e'-1,2*X' RST #28 ;postup pro X' vetsi,postup pro X' male 373D DEFB #01 ;zamena x',e' 2*x',e'-1 DEFB #34 ;STK-data x',e',LN2 2*x',e'-1,LN2 DEFB #F0 ;exponent #80 DEFB #31,#72,#17,#F8 DEFB #04 ;nasobeni x',e*LN2 (=y1) 2*x',e'-1*LN2 (=y2) Proved krok d) (cislo 0.5 je dekadicke) DEFB #01 ;zamena y1,x y2,2*x' DEFB #A2 ;STK-polovina y1,x',0.5 y2,2*x',.5 DEFB #03 ;odecitani y1,x'-0.5 DEFB #A2 ;STK-polovina y1,x'-0.5,0.5 y2,2*x'-0.5,0.5 DEFB #03 ;odecitani y1,x'-1 y2,2*x'-1 Proved krok e) (cislo 2.5 je dekadicke) DEFB #31 ;zdvojeni y1,x'-1,x'-1,y2,2*x'-1,2*x'-1 DEFB #34 ;STK-data y1,x'-1,x'-1,2.5,y2,2*x'-1,2*x'-1,2.5 DEFB #32 ;exponent #82 DEFB #20,(#00,#00,#00) DEFB #04 ;nasobeni y1,x'-1,2.5*x'-2.5,y2,2*x'-1,5*x'-2.5 DEFB #A2 ;STK-polovina y1,x'-1,2.5*x'-2.5,0.5,y2,2*x'-1, ; 5*x'-2.5,.5 DEFB #03 ;odecitani y1,x'-1,2.5*x'-3,y2,2*x'-1,5*x'-3(=z) Proved krok f) DEFB #8C ;serie-0C y1,x'-1,z,y2,2*x'-1,z 1. DEFB #11 ;exponent #61 DEFB #AC,(#00,#00,#00) 2. DEFB #14 ;exponent #64 DEFB #09,(#00,#00,#00) 3. DEFB #56 ;exponent #66 DEFB #DA,#A5,(#00,#00) 4. DEFB #59 ;exponent #69 DEFB #30,#C5,(#00,#00) 5. DEFB #5C ;exponent #6C DEFB #90,#AA,(#00,#00) 6. DEFB #9E ;exponent #6E DEFB #70,#6F,#61,(#00) 7. DEFB #A1 ;exponent #71 DEFB #CB,#DA,#96,(#00) 8. DEFB #A4 ;exponent #74 DEFB #31,#9F,#B4,(#00) 9. DEFB #E7 ;exponent #77 DEFB #A0,#FE,#5C,#FC 10. DEFB #EA ;exponent #7A DEFB #1B,#43,#CA,#36 11. DEFB #ED ;exponent #7D DEFB #A7,#9C,#7E,#5E 12. DEFB #F0 ;exponent #80 DEFB #6E,#23,#80,#93 Nyni je posledni hodnota: LN x'/(x'-1) LN(2*x')/(2*x'-1) Proved krok g) DEFB #04 ;nasobeni LN(2^e'),LN x',LN(2^(e'-1)),LN(2*x') DEFB #0F ;scitani LN((2^e')*x'),LN(2^(e'-1)*2*x') DEFB #38 ;konec vypoctu LN x RET ;Posledni hodnota je LN x Podprogram "REDUKCE ARGUMENTU" ------------------------------ Doplnek: #39 "GET-ARGT" Podprogram prevede argument funkce SIN nebo COS na hodnotu v.Podprogram nejpr- ve nalezne hodnotu y,pro ktere plati: y=x/(2*pi)-INT(x/2*pi)+0.5), kde 0.5>y>=-0.5.Podprogram vraci: a) y=4*y pokud -1 <= 4*y <= 1 b) y=2 az 4*y pokud 1 < 4*y < 2 c) y=-4*y-2 pokud -2 <= 4*y < -1 Ve vsech pripadech -1<=y<=1 a SIN(pi*v/2)=SIN x MONITOR ROM - ZX Spectrum - 139 - 1. DEFB #14 ;exponent #64 DEFB #E6,(#00,#00,#00) 2. DEFB #5C ;exponent #6C DEFB #1F,#0B,(#00,#00) 3. DEFB #A3 ;exponent #73 DEFB #8F,#38,#EE,(#00) 4. DEFB #E9 ;exponent #79 DEFB #15,#63,#BB,#23 5. DEFB #EE ;exponent #7E DEFB #92,#0D,#CD,#ED 6. DEFB #F1 ;exponent #81 DEFB #23,#5D,#1B,#EA Po poslednim pruchodu smyckou je posledni hodnota (SIN(PI*W/2))/W DEFB #04 ;nasobeni SIN(PI*W/2)=SIN X (nebo COS X) DEFB #38 ;konec vypoctu RET ;Posledni hod. na zasobniku kal. je SIN X (nebo COS X) Funkce "TAN" ------------ Doplnek: #21 "TAN" Podprogram vraci posledni hodnotu SIN X/COS X s aritmetickym pretecenim,je-li COS X=0. 37DA RST #28 ; X DEFB #31 ;zdvojeni X,X DEFB #1F ;SIN X,SIN X DEFB #01 ;zamena SIN X,X DEFB #20 ;COS SIN X,COS X DEFB #05 ;deleni SIN X/COS X=TAN X ;Je-li to potreba,ohlas aritmeticke preteceni DEFB #38 ;konec vypoctu TAN X RET ;Posledni hodnota na zasobniku kalkulatoru je TAN X Funkce "ARCTAN" --------------- Doplnek: #24 "ATN" Podprogram je poslednim ze ctyr,ktere pouzivaji podprogram "SERIES GENERATOR" k vytvareni Cebysevovych polynomu.Podprogram vraci realne cislo mezi -PI/2 a PI/2,ktere se rovna hodnote v radianech uhlu jehoz TAN je X.Aproximace ATN je nalezena takto: a) 1. Jestlize -10 0,(1/0) DEFB #00 ;skok-pravda 0 DEFB #06 ;na #386C,LAST 0 - skoc,jestlize X=0 a Y ja kladne DEFB #A1 ;STK-jedna 0,1 DEFB #01 ;zamena 1,0 DEFB #05 ;deleni Deleni nulou ohlasi chybu 386A DEFB #02 ;vymaz DEFB #A1 ;STK-jedna 1 386C DEFB #38 ;konec vypoctu RET 386E DEFB #FF,#FF ... #FF 3CFF DEFB #FF 3D00 az 3FFF ------------ Tato oblast obsahuje matice znakoveho souboru ASCII #20 az #7F. Napriklad matice pismene A vypada takto: #00 0 0 0 0 0 0 0 0 . . . . . . . . #3C 0 0 1 1 1 1 0 0 . . * * * * . . #42 0 1 0 0 0 0 1 0 . * . . . . * . #42 0 1 0 0 0 0 1 0 . * . . . . * . #7E 0 1 1 1 1 1 1 0 . * * * * * * . #42 0 1 0 0 0 0 1 0 . * . . . . * . #42 0 1 0 0 0 0 1 0 . * . . . . * . #00 0 0 0 0 0 0 0 0 . . . . . . . . MONITOR ROM - ZX Spectrum - 143 - 1076 ED-SYMBOL 1736 OPEN 1AAB P-RUN 107F ED-ERROR 1756 OPEN-1 1AAE P-LIST 107C ED-GRAPH 175D OPEN-2 1AB1 P-POKE 10AB KEY-INPUT 1765 REPORT-F 1AB5 P-RANDOM 1097 CLEAR-SP 1767 OPEN-3 1AB8 P-CONT 10E6 KEY-MODE 1781 OPEN-K 1ABB P-CLEAR 10DB KEY-M&CL 1785 OPEN-S 1ABE P-CLS 10F4 KEY-FLAG 1789 OPEN-P 1AC1 P-PLOT 10FA KEY-CONTR 178B OPEN-END 1AC5 P-PAUSE 1105 KEY-DATA 1793 CAT-ETC 1AC9 P-READ 110D KEY-NEXT 1795 AUTO-LIST 1ACC P-DATA 1113 KEY-CHAN 17CE AUTO-L-1 1ACF P-RESTORE 111B KEY-DONE 17E1 AUTO-L-2 1AD2 P-DRAW 111D ED-COPY 17E4 AUTO-L-3 1AD6 P-COPY 1150 ED-BLANK 17ED AUTO-L-4 1AD9 P-LPRINT 115E ED-SPACES 17F5 LLIST 1ADC P-LLIST 1167 ED-FULL 17F9 LIST 1ADF P-SAVE 117C ED-C-DONE 17FB LIST-1 1AE0 P-LOAD 117E ED-C-END 1814 LIST-2 1AE1 P-VERIFY 1190 SET-HL 181A LIST-3 1AE2 P-MERGE 1195 SET-DE 181F LIST-4 1AE3 P-BEEP 11A7 REMOVE-FP 1822 LIST-5 1AE7 P-CIRCLE 11B7 NEW 1833 LIST-ALL-1 1AEB P-INK 11CB START/NEW 1835 LIST-ALL 1AEC P-PAPER 11DA RAM-CHECK 1855 OUT-LINE 1AED P-FLASH 11DC RAM-FILL 1865 OUT-LINE1 1AEE P-BRIGHT 11E2 RAM-READ 187D OUT-LINE2 1AEF P-INVERSE 11EF RAM-DONE 1881 OUT-LINE3 1AF0 P-OVER 1219 RAM-SET 1894 OUT-LINE4 1AF1 P-OUT 12A2 MAIN-EXEC 18A1 OUT-LINE5 1AF5 P-BORDER 12A9 MAIN-1 18B4 OUT-LINE6 1AF9 P-DEF-FN 12AC MAIN-2 18B6 NUMBER 1AFC P-OPEN 12CF MAIN-3 18C1 OUT-FLASH 1B02 P-CLOSE 1303 MAIN-4 18E1 OUT-CURS 1B06 P-FORMAT 1313 MAIN-G 18F3 OUT-C-1 1B0A P-MOVE 133C MAIN-5 1909 OUT-C-2 1B10 P-ERASE 1373 MAIN-6 190F LN-FETCH 1B14 P-CAT 1376 MAIN-7 191C LN-STORE 1B17 LINE-SCAN 1384 MAIN-8 1925 OUT-SP-2 1B28 STMT-LOOP 1386 MAIN-9 192A OUT-SP-NO 1B29 STMT-L-1 1555 REPORT-G 192B OUT-SP-1 1B52 SCAN-LOOP 155D MAIN-ADD 1937 OUT-CHAR 1B55 GET-PARAM 157D MAIN-ADD1 195A OUT-CH-1 1B6F SEPARATOR 15AB MAIN-ADD2 1968 OUT-CH-2 1B76 STMT-RET 15C4 REPORT-J 196C OUT-CH-3 1B7B REPORT-L 15D4 WAIT-KEY 1974 LINE-AD-1 1B7D STMT-R-1 15DE WAIT-KEY1 1980 CP-LINES 1B8A LINE-RUN 15E4 REPORT-8 1988 INC 1B9E LINE-NEW 15E6 INPUT-AD 198B EACH-STMT 1BB0 REPORT-0 15EF OUT-CODE 1990 EACH-S-1 1BB2 REM 15F2 PRINT-A-2 1998 EACH-S-2 1BB3 LINE-END 15F7 CALL-SUB 199A EACH-S-3 1BBF LINE-USE 1601 CHAN-OPEN 19A5 EACH-S-4 1BD1 NEXT-LINE 160E REPORT-O 19AD EACH-S-5 1BEC REPORT-N 1610 CHAN-OP-1 19B1 EACH-S-6 1BEE CHECK-END 1615 CHAN-FLAG 19B8 NEXT-ONE 1BF4 STMT-NEXT 162C CALL-JUMP 19C7 NEXT-O-1 1C0D CLASS-03 1634 CHAN-K 19CE NEXT-O-2 1C10 CLASS-00 1642 CHAN-S 19D5 NEXT-O-3 1C11 CLASS-05 1646 CHAN-S-1 19D6 NEXT-O-4 1C16 JUMP-C-R 164D CHAN-P 19DB NEXT-O-5 1C1F CLASS-01 1652 ONE-SPACE 19DD DIFFER 1C22 VAR-A-1 1655 MAKE-ROOM 19E5 RECLAIM-1 1C2E REPORT-2 1664 POINTERS 19E8 RECLAIM-2 1C30 VAR-A-2 166B PTR-NEXT 19FB E-LINE-NO 1C46 VAR-A-3 167F PTR-DONE 1A15 E-L-1 1C4E CLASS-02 168F LINE-ZERO 1A1B OUT-NUM-1 1C56 VAL-FET-1 1691 LINE-NO-A 1A28 OUT-NUM-2 1C59 VAL-FET-2 1695 LINE-NO 1A30 OUT-NUM-3 1C6C CLASS-04 169E RESERVE 1A42 OUT-NUM-4 1C79 NEXT-2NUM 16B0 SET-MIN 1A7A P-LET 1C7A EXPT-2NUM 16BF SET-WORK 1A7D P-GO-TO 1C82 EXPT-1NUM 16C5 SET-STK 1A81 P-IF 1C8A REPORT-C 16D4 REC-EDIT 1A86 P-GO-SUB 1C8C EXPT-EXP 16DB INDEXER-1 1A8A P-STOP1 1C96 PERMS 16DC INDEXER 1A8D P-RETURN 1CBE CLASS-09 16E5 CLOSE 1A90 P-FOR 1CD6 CL-09-1 16FC CLOSE-1 1A98 P-NEXT 1CDB CLASS-0B 1701 CLOSE-2 1A9C P-PRINT 1CDE FETCH-NUM 171C CLOSE-STR 1A9F P-INPUT 1CE6 USE-ZERO 171E STR-DATA 1AA2 P-DIM 1CEE STOP 1725 REPORT-0 1AA5 P-REM 1CF0 IF 1727 STR-DATA1 1AA8 P-NEW 1D00 IF-1 MONITOR ROM - ZX Spectrum - 145 - 2951 STK-F-ARG 2D4F E-TO-FP 3159 NEAR-ZERO 295A SFA-LOOP 2D55 E-SAVE 315D ZERO-RSLT 296B SFA-CP-VR 2D60 E-LOOP 315E SKIP-ZERO 2981 SFA-MATCH 2D6D E-DIVISN 316C NORMALISE 2991 SFA-END 2D6E E-FETCH 316E SHIFT-ONE 2996 STK-VAR 2D71 E-TST-END 3186 NORML-NOW 29A1 SV-SIMPLE$ 2D7B E-END 3195 OFLOW-CLR 29AE SV-ARRAYS 2D7F INT-FETCH 31AD REPORT-6 29C0 SV-PTR 2D8C P-INT-STO 31AF DIVISION 29C3 SV-COMMA 2D8E INT-STORE 31D2 DIV-LOOP 29D8 SV-CLOSE 2DA2 FP-TO-BC 31DB DIV-34TH 29E0 SV-CH-ADD 2DAD FP-DELETE 31E2 DIV-START 29E7 SV-COUNT 2DC1 LOG 31F2 SUBN-ONLY 29EA SV-LOOP 2DD5 FP-TO-A 31F9 NO-RSTORE 29FB SV-MULT 2DE1 FP-A-END 31FA COUNT-ONE 2A12 SV-RPT-C 2DE3 PRINT-FP 3214 TRUNCATE 2A20 REPORT-3 2DF2 PF-NEGTVE 3221 T-GR-ZERO 2A22 SV-NUMBER 2DF8 PF-POSTVE 3223 ???? 2A2C SV-ELEM$ 2E01 PF-LOOP 3225 ???? 2A45 SV-SLICE 2E1E PF-SAVE 3233 T-FIRST 2A48 SV-DIM 2E24 PF-SMALL 323F T-SMALL 2A49 SV-SLICE? 2E56 PF-LARGE 3252 T-NUMERIC 2A52 SLICING 2E6F PF-MEDIUM 325E T-TEST 2A7A SL-RPT-C 2E7B PF-BITS 3261 T-SHIFT 2A81 SL-SECOND 2E8A PF-BYTES 3267 T-STORE 2A94 SL-DEFINE 2EA1 PF-DIGITS 326C T-EXPNENT 2AA8 SL-OVER 2EA9 PF-INSERT 326D X-LARGE 2AAD SL-STORE 2EB3 PF-TEST-2 3272 NIL-BYTES 2AB1 STK-ST-0 2EB8 PF-ALL-9 327E BYTE-ZERO 2AB2 STK-ST-$ 2ECB PF-MORE 3283 BITS-ZERO 2AB6 STK-STORE 2ECF PF-FRACTN 328A LESS-MASK 2ACC INT-EXP1 2EDF PF-FRN-LP 3290 IX-END 2ACD INT-EXP2 2EEC PR-FR-DGT 3293 RE-ST-TWO 2AE8 I-CARRY 2EEF PR-FR-EXX 3296 RESTK-SUB 2AEB I-RESTORE 2F0C PF-ROUND 3297 RE-STACK 2AEE DE,(DE+1) 2F18 PF-RND-LP 32B1 RS-MRLMSE 2AF4 GET-HL*DE 2F25 PF-R-BACK 32B2 RSTK-LOOP 2AFF LET 2F2D PF-COUNT 32BD RS-STORE 2B0B L-EACH-CH 2F46 PF-NOT-E 32C5 STK-ZERO 2B0C L-NO-SP 2F4A PF-E-SBRN 32C8 STK-ONE 2B1F L-TEST-CH 2F52 PF-OUT-LP 32CC STK-HALF 2B29 L-SPACES 2F59 PF-OUT-DT 32CE STK-PI/2 2B3E L-CHAR 2F5E PF-DC-OUT 32D3 STK-TEN 2B4F L-SINGLE 2F64 PF-DEC-0S 335B CALCULATE 2B59 L-NUMERIC 2F6C PF-E-FRMT 335E GEN-ENT-1 2B66 L-EXISTS 2F83 PF-E-POS 3362 GEN-ENT-2 2B72 L-DELETE$ 2F85 PF-E-SIGN 3365 RE-ENTRY 2B9B L-LENGTH 2F8B CA=10*A+C 336C SCAN-ENT 2BA3 L-IN-W/S 2F9B PREP-ADD 3380 FIRST-3D 2BA6 L-ENTER 2FAF NEG-BYTE 338C DOUBLE-A 2BAF L-ADD$ 2FDD SHIFT-FP 338E ENT-TABLE 2BC0 L-NEW$ 2FE5 ONE-SHIFT 33A1 DELETE 2BC6 L-STRING 2FF9 ADDEND-0 33A2 FP-CALC-2 2BEA L-FIRST 2FFB ZEROS-4/5 33A9 TEST-5-SP 2BF1 STK-FETCH 3004 ADD-BACK 33B4 STACK-NUM 2C02 DIM 300D ALL-ADDED 33C0 MOVE-FP 2C05 D-RPORT-C 300F SUBTRACT 33C6 STK-DATA 2C15 D-RUN 3014 ADDITION 33C8 STK-CONST 2C1F D-LETTER 3032 ???? 33DE FORM-EXP 2C2D D-SIZE 303C ADDN-OFLW 33F1 STK-ZEROS 2C2E D-NO-LOOP 303E FULL-ADDN 33F7 SKIP-CONS 2C70 DIM-CLEAR 3055 SHIFT-LEN 33F8 SKIP-NEXT 2C7F DIM-SIZES 307C TEST-NEG 3406 LOC-MEM 2C88 ALPHANUM 309F ADD-REP-6 340F GET-MEM-0 2C8D ALPHA 30A3 END-COMPL 341B STK-ZERO 2C9B DEC-TO-FP 30A5 GO-NC-MLT 342D ST-MEM-0 2CA2 BIN-DIGIT 30A9 HL=HL*DE 343C EXCHANGE 2CB3 BIN-END 30B1 HL-LOOP 343E SWAP-BYTE 2CB8 NOT-BIN 30BC HL-AGAIN 3449 SERIES-06 2CCB DECIMAL 30BE HL-END 3453 G-LOOP 2CCF DEC-RPT-C 30C0 PREP-M/D 346A ABS 2CD5 DEC-STO-1 30CA MULTIPLY 346E NEGATE 2CDA NXT-DGT-1 30E5 LD 3474 NEG-TEST 2CEB E-FORMAT 30EA MULT-RSLT 3483 INT-CASE 2CF2 SING-FLAG 30EF MULT-OFLW 34A5 IN 2CFE SING-DONE 30F0 MULT-LONG 34AC PEEK 2CFF ST-E-PART 3114 MLT-LOOP 34B0 IN-PK-STK 2D18 E-FP-JUMP 311B NO-ADD 34B3 USR-NO 2D1B NUMERIC 3125 STRT-MLT 34BC USR-$ 2D22 STK-DIGIT 313B MAKE-EXPT 34D3 USR-RANGE 2D28 STACK-A 313D DIVN-EXPT 34E4 USR-STACK 2D2B STACK-BC 3146 OFLW1-CLR 34E7 REPORT-A 2D3B INT-TO-FP 3151 OFLW2-CLR 34E9 TEST-ZERO 2D40 NXT-DGT-2 3155 TEST-NORM 34F9 GREATHER-0 MONITOR ROM - ZX Spectrum - 147 - Systemove promenne serazene podle adres *************************************** 5C08 LAST-K 5C09 REPDEL 5C0A REPPER 5C0B DEFADD 5C0C DEFADD-HI 5C0D K-DATA 5C0E CHURCHL 5C0F TVDATA-HI 5C16 STRMS-6 5C36 CHARS 5C38 RASP/PIP 5C3A ERR-NR 5C3B FLAGS 5C3C TV-FLAG 5C3D ERR-SP 5C3F LIST-SP 5C40 CHANS 5C41 MODE 5C42 NEW-PPC 5C44 NSPPC 5C45 PPC 5C47 SUBPPC 5C48 BORDCR 5C48 MEM-0-1(MEMBOT) 5C49 E-PPC-LO 5C4A E-PPC-HI 5C4B VARS 5C4D DEST 5C4F CHANS 5C51 CURCHL 5C53 PROG 5C55 NXTLIN 5C57 DATADD 5C59 E-LINE 5C5B K-CUR 5C5D CH-ADD 5C5F X-PTR 5C61 WORKSP 5C63 STKBOT 5C65 STKEND-LO 5C66 STKEND-HI 5C67 BREG 5C68 MEM 5C6A FLAGS2 5C6B DF-SZ 5C6C S-TOP 5C6E OLDPPC 5C71 FLAGX 5C72 STRLEN 5C74 T-ADDR 5C76 SEED 5C78 FRAMES1 5C7B UDG 5C7D COORDS-LO 5C7E COORDS-HI 5C80 PR-CC 5C82 ECHO-E 5C84 DF-CC 5C86 DF-CCL 5C88 S-POSN 5C89 S-POSN-HI 5C8A S-POSNL 5C8B S-POSNL-HI 5C8C SCR-CT 5C8D ATTR-P 5C8F ATTR-T 5C90 MASK-T 5C91 P-FLAG 5C92 MEMBOT 5CB2 RAMTOP 5CB4 P-RAMT 5CBA S-POSNL MONITOR ROM - ZX Spectrum - 149 - NOTES: I. When C is entered this program calculates and prints SIN C degrees, SIN (C+20) degrees and SIN (C+30) degrees.It also prints the values obtained by using the ROM program.For a specimen of results,try ente- these values in degrees: 0;5;100;-80;-260;3600;-7200. II. The constants A(1) to A(6) in lines 40 to 90 are given (apart from a factor of 1/2) in Abramovitz and Stegun >>Handbook of Mathematical Functions (Dover 1965)<< page 76.They can be checked by integrating (SIN (PI*X/2))/X over the interval U=0 to PI, after first multiplying by COS(N*U) for each constant (i.e. N=1,2,...,6) and substituting COS U=2*X*X-1.Each result should then be divided by PI.(This integra- tion can be performed by approximate methods e.g. using Simpson's Rule if there is a reasonable computer or programmable calculator to hand.) EXP X ----- 10 REM DEMONSTRATION FOR EXP X 20 REM USING THE 'SERIES GENERATOR' 30 LET T=0 (This makes the first variable) 40 DIM A(8) 50 LET A(1)=0.000000001 60 LET A(2)=0.000000053 70 LET A(3)=0.000001851 80 LET A(4)=0.000053453 90 LET A(5)=0.001235714 100 LET A(6)=0.021446556 110 LET A(7)=0.248762434 120 LET A(8)=1.456999875 130 PRINT 140 PRINT "ENTER START VALUE" 150 INPUT C 160 CLS LET C=C-10 180 PRINT "BASIC PROGRAM","ROM PROGRAM" 190 PRINT "-------------","-----------" 200 PRINT 210 FOR J=1 TO 4 220 LET C=C+10 230 LET D=C*1.442695041 (D=C*(1/LN 2);EXP C=2**D) 240 LET N=INT D 250 LET Z=D-N (2**(N+Z) is now required) 260 LET Z=2*Z-1 270 LET BREG=8 280 REM USE "SERIES GENERATOR" 290 GO SUB 550 300 LET V=PEEK 23627+256*PEEK 23628+1 (V=(VARS)+1) 310 LET N=N+PEEK V 320 IF N>255 THEN STOP (STOP with arithmetic overflow) 330 IF N<0 THEN GO TO 360 340 POKE V,N 350 GO TO 370 360 LET T=0 370 PRINT TAB 11;"EXP ";C 380 PRINT 390 PRINT T,EXP C 400 PRINT 410 NEXT J 420 GO TO 130 NOTES: I. When C is entered this program calculates and prints EXP C,EXP(C+10), EXP(C+20) and EXP(C+30).It also prints the values obtained by using the ROM program.For a specimen of results,try entering these values: 0;15;65 (with overflow at the end);-100;-40. II. The exponent is tested for overflow and for a zero result in lines 320 and 330.These tests are simpler in BASIC than in machine code,since the variable N,unlike the A register,is not confined to one byte. III. The constants A(1) to A(8) in lines 50 to 120 can be obtained by inte- grating 2**X over the interval U=0 to PI,after first multiplying the COS(N*U) for each constant (i.e. for N=1,2,...,8) and substituting COS U = 2*X-1.Each result should then be divided by PI. MONITOR ROM - ZX Spectrum - 151 - ATN X ----- 10 REM DEMONSTRATION FOR ATN X 20 REM USING THE 'SERIES GENERATOR' 30 DIM A(12) 40 LET A(1)=-.0000000002 50 LET A(2)=0.0000000010 60 LET A(3)=-.0000000066 70 LET A(4)=0.0000000432 80 LET A(5)=-.0000002850 90 LET A(6)=0.0000019105 100 LET A(7)=-.0000131076 110 LET A(8)=0.0000928715 120 LET A(9)=-.0006905975 130 LET A(10)=0.0055679210 140 LET A(11)=-.0529464623 150 LET A(12)=0.8813735870 160 PRINT 170 PRINT "ENTER START VALUE" 180 INPUT C 190 CLS 200 PRINT "BASIC PROGRAM","ROM PROGRAM" 210 PRINT "-------------","-----------" 220 PRINT 230 FOR J=1 TO 4 240 LET B=J*C 250 LET D=B 260 IF ABS B>=1 THEN LET D=-1/B 270 LET Z=2*D*D-1 280 LET BREG=12 290 REM USE 'SERIES GENERATOR' 300 GO SUB 550 310 LET T=D*T 320 IF B>=1 THEN LET T=T+PI/2 330 IF B<=-1 THEN LET T=T-PI/2 340 PRINT TAB 8;"ATN ";B 350 PRINT 360 PRINT T,ATN B (or PRINT T*180/PI,ATN B*180/PI 370 PRINT to obtain the answers in degres) 380 NEXT J 390 GO TO 160 NOTES: I. When C is entered this program calkulates and prints ATN C,ATN(C*2), ATN (C*3),ATN (C*4).For a specimen of results,try entering these values: 0.2;-1;10 and -100.The results may be found more interesting if converted to yield degrees by multiplying the answers in line 360 by 180/PI. II. The constants A(1) to A(12) in lines 40 to 150 are given (apart from a factor of 1/2) in Abramowitz and Stegun Handbook of Mathematical Functions (Dover 1965) page 82.They can be checked by integrating ATN X/X over the interval U=0 to PI,after first multiplying by COS(N*U) for each parameter (i.e. for n=1,2,....,12) and substituting COS U=2*X*X-1.Each result should then be divided by PI. An alternative subroutine for SIN X: It is straightforward to produce the full expansion of the Chebyshev polynomials and this written in BASIC as follows': 550 LET T=(32*Z*Z*Z*Z*Z*-40*Z*Z*Z+10*Z)*A(1) +(16*Z*Z*Z*Z-16*Z*Z+2)*A(2) +(8*Z*Z*Z-6*Z)*A(3) +(4*Z*Z-2)*A(4) +2*Z*A(5) +A(6) 560 RETURN This subroutine is called instead of the SERIES GENERATOR and can be seen to be of a similar accuracy. An alternative subroutine for EXP X: The full expansion for EXP X is: 550 LET T=(128*Z^7-224*Z^5+112*Z^3-14*Z)*A(1) +(64*Z^6-96*Z^4+36*Z^2-2)*A(2) +(32*Z^5-40*Z^3+10*Z)*A(3) +(16*Z^4-16*Z^2+2)*A(4) +(8*Z^3-6*Z)*A(5) +(4*Z^2-2)*A(6) +2*Z*A(7) +A(8) 560 RETURN MONITOR ROM - ZX Spectrum - 153 - 500 REM 'DRAW A LINE' from last position to X,Y 510 LET PLOTx=PEEK 23677: LET PLOTy=PEEK 23678 520 LET dx=SGN X: LET dy=SGN Y 530 LET X=ABS X: LET Y=ABS Y 540 IF X>=Y THEN GOTO 580 550 LET L=X: LET B=Y 560 LET ddx=0: LET ddy=dy 570 GOTO 610 580 IF X+Y=0 THEN STOP 590 LET L=Y: LET B=X 600 LET ddx=dx: LET ddy=0 610 LET H=B 620 LET i=INT (B/2) 630 FOR N=B TO 1 STEP -1 640 LET i=i+L 650 IF i175 THEN STOP 720 LET PLOTx=PLOTx+ix 730 IF PLOTx<0 OR PLOTx>255 THEN STOP 740 PLOT PLOTx,PLOTy 750 NEXT N 760 RETURN NOTE ON SMALL INTEGERS AND -65536 --------------------------------- 1. Small integers n are those for which -65536 is less than or equal to n which is less than or equal to 65536.The form in which they are held is described in 'STACK BC'.Note that the manual is inaccurate when it says that the third and fourth bytes hold n plus 131072 if n is negative.Since the range of n is then -1 to -65535,the two bytes can only hold n plus 131072 if it is taken mod 65536; i.e. they hold n plus 65536.The manual is fudging the issue. The fact is that this is not a true twos complement form (as the form n plus 131072,in other circumstances,could be).Here the same number can stand for two different numbers according to the sign byte: e.g. 00 01 stands for 1 if the sign byte is 00 and for -65535 if the sign byte is FF; similarly FF FF stands for 65535 if the sign byte is 00 and for -1 if the sign byte is FF. 2. Accepting that negative numbers are given a special 'twos complement' form the main feature about this method of holding numbers is that they are ready for 'short addition' wihout any further twos complementing.They are simply fetched and stored direct by the addition subroutine.But for multiplication they need to be fetched by INT-FETCH and stored afterwards by INT-STORE.These subroutines twos complement the number when fetching or storing it.The calls to INT-STORE are from 'multiply' (after 'short multiplication'),from 'truncate' (after forming a 'small integer' betwen -65535 and 65535 inclusive),from 'negate'/'abs' for the 'integer case' and from 'sgn' to store 1 or -1.The calls to INT-FETCH are from PRINT-FP to fetch the integer part of the number when it is 'small',from 'multiply' twice to fetch two 'small integers',from 'RE-STACK' to fetch a 'small integer' for re-stacking,from 'negate'/'abs' to fetch a 'small integer' for manipulation and from FP-TO-BC to fetch the integer for transfer to BC. THE NUMBER -65536 ----------------- 3. The number -65536 can fit into the 'small integer' format as 00 FF 00 00 00. It is then the 'limiting number', the one which when twos complemented overflows (cf. 80 hex in a simple one byte or 7 bit system,i.e. -128 decimal, which when twos complemented still gives 80 hex i.e. -128 decimal since the positive number 128 decimal does not fit into the system) 4. Some awareness of this may have inspired the abortive attempt to create 00 FF 00 00 00 in 'truncate'.It is abortive since it does not even survive the INT routine of which 'truncate' is a part.It just leads to the mistake INT(-65536) equals -1. 5. But the main error is that this number has been allowed to arise from 'short addition' of two smaller negative integers and then simply put on the stack as 00 FF 00 00 00.The system cannot cope with this number.The solution proposed in 'addition' is to form the full five byte floating-point form at once; i.e. test for the number first,at about byte 3032,as follows: MONITOR ROM - ZX Spectrum - 155 - 0 B S A H ********* Predmluva 1 Uvod 1 THE RESTART ROUTINES AND TABLES (Rutiny restartu a tabulky) ----------------------------------------------------------- 0000 START 3 0008 Error (podprogram chybovych hlaseni) 3 0010 Print a character (vytiskni znak) 3 0018 Collect character (vyzvedni znak) 3 0020 Collect next character (vyzvedni dalsi znak) 3 0028 Calculator 3 0030 Make BC spaces (vytvor prostor BC bajtu) 3 0038 Mascable interrupt (maskovane preruseni) 3 0053 ERROR-2 (chyba-2) 4 0066 Non-maskable interrupt (nemaskovane preruseni) 4 0074 CH-ADD+1 4 007D SKIP-OVER (preskok) 4 0095 Token tables (tabulky klicovych slov) 5 0205 Key tables (tabulky klaves) 6 THE KEYBOARD ROUTINES (Podprogramy osetrujici klavesnici) --------------------------------------------------------- 028E Keyboard scanning (testovani klavesnice) 7 02BF KEYBOARD (klavesnice) 7 0310 Repeating key (opakovani klavesy) 8 031E K-TEST 8 0333 Keyboard decoding (dekodovani klavesnice) 9 THE LOUDSPEAKER ROUTINES (Reproduktorove podprogramy) ----------------------------------------------------- 03B5 BEEPER 10 03F8 BEEP 11 046E Semi-tone table 12 THE CASSETTE HANDLING ROUTINES (Podprogramy obsluhujici kazetovy magnetofon) ---------------------------------------------------------------------------- 04C2 SA-BYTES 13 053F SA/LD-RET 14 0556 LD-BYTES 14 05E3 LD-EDGE-2 15 0605 SAVE-ETC 16 07CB VERIFY control (ovladani verifikace) 19 0802 Load a data block (nahrani bloku dat) 19 0808 LOAD control (ovladani LOAD) 19 08B6 MERGE control (ovladani MERGE) 21 0970 SAVE control (ovladani SAVE) 22 09A1 Cassette messages (hlaseni pri praci s kazetovym magnetofonem) 22 THE SCREEN & PRINTER HANDLING ROUTINES (Podprogramy pro obrazovku a tiskarnu) ----------------------------------------------------------------------------- 09F4 PRINT-OUT (vytiskni) 23 0A11 Control character table (tabulka ridicich znaku) 23 0A23 Cursor left (kurzor doleva) 23 0A3D Cursor right (kurzor doprava) 23 0A4F Carriage return (navrat voziku) 23 0A5F Print comma (vypis carku) 24 0A69 Print a question mark (vypis otaznik) 24 0A6D Control characters with operands (ridici znaky s operandy) 24 0AD9 PO-ABLE 25 0ADC Position store (uschovani pozice) 25 0B03 Position fetch (vyzvednuti pozice) 25 0B24 Print any character (vytiskni jakykoliv znak) 25 0B7F Print all characters (vytiskni vsechny znaky) 26 0BDB Set attribute byte (nastav atributovy bajt) 27 0C0A Message printing (vypis hlaseni) 27 0C3B PO-SAVE 28 0C41 Table search (prohledani tabulek) 28 0C55 Test for scroll (test na skrol) 28 0CF8 'scroll?' message (hlaseni 'scroll?') 29 0D4D Temporary colour items (prechodne barevne polozky) 30 0D6B CLS command (prikaz CLS) 30 0DAF Clearing the whole display area (Vycisteni cele obrazovky) 30 0DD9 CL-SET 31 0DFE Scrolling 31 0E44 Clear lines (vycisteni radku) 32 0E88 CL-ATTR 32 0E9B CL-ADDR 33 0EAC COPY command 33 0ECD COPY-BUFF 33 0EF4 COPY-LINE 33 0F2C EDITOR 34 0F81 ADD-CHAR 35 0FA0 Editing keys table (tabulka editacnich klaves) 35 0FA9 EDIT key 35 0FF3 Cursor down editing (kurzor dolu pri editaci) 36 MONITOR ROM - ZX Spectrum - 157 - 1C01 Command class table (tabulky prikazovych trid) 60 1C0D Command classes - 00,03 & 05 60 1C16 JUMP-C-R (skok C-R) 60 1C1F Command classes - 01,02 & 04 60 1C22 Variable in assignment (promenna v prideleni) 60 1C56 Fetch a value (vyzvedni hodnotu) 61 1C79 Expect numeric/string expressions (ocekavani ciselneho nebo retezcoveho vyrazu) 61 1C96 Set permanent colours(class 07)(nastaveni permanentnich barev) 62 1CBE Command class - 09 62 1CDB Command class - 0B 62 1CDE Fetch a number (vyzvedni cislo) 62 1CEE STOP command 63 1CF0 IF command 63 1D03 FOR command 63 1D86 LOOK-PROG 64 1DAB NEXT command 65 1DDA NEXT-LOOP 65 1DEC READ command 66 1E27 DATA command 66 1E39 PASS-BY 66 1E42 RESTORE command 66 1E4F RANDOMIZE command 66 1E5F CONTINUE command 67 1E67 GO TO command 67 1E7A OUT command 67 1E80 POKE command 67 1E85 TWO-PARAM (dva parametry) 67 1E94 Find integers (najdi cela cisla) 67 1EA1 RUN command 67 1EAC CLEAR command 68 1EED GO SUB command 68 1F05 TEST-ROOM (testuj prostor) 68 1F1A Free memory (volna pamet) 69 1F23 RETURN command 69 1F3A PAUSE command 69 1F54 BREAK-KEY 69 1F60 DEF FN command 69 1FC3 UNSTACK-Z 70 1FC9 LPRINT command 70 1FCF PRINT command 70 1FF5 Print a carriage return (proved navrat voziku) 71 1FFC Print items 71 2045 End of printing (konec tisknuti) 71 204E Print position (tiskova pozice) 71 2070 Alter stream (zmena proudu) 72 2089 INPUT command 72 21B9 IN-ASSIGN 74 21D6 IN-CHAN-K 74 21E1 Colour item routines (program barevnych polozek) 74 226C CO-CHANGE 75 2294 BORDER command 76 22AA Pixel addres (adresa "pixlu") 76 22CB Point (bod) 76 22DC PLOT command 77 2307 STK-TO-BC 77 2314 STK-TO-A 77 2320 CIRCLE command 77 2382 DRAW command 79 247D Initial parameters (nastaveni parametru) 82 24B7 Line drawing (rysovani primek) 82 EXPRESSION EVALUATION (Ohodnoceni vyrazu) ----------------------------------------- 24FB SCANNING 83 2530 SYNTAX-Z 84 2535 Scanning SCREEN$ 84 2580 Scanning ATTR 85 2596 Scanning function table 85 25AF Scanning function rutines 85 26C9 Scanning variable rutine 88 2734 Scanning main loop (hlavni smycka) 89 2795 Table of operators (tabulky operatoru) 90 27B0 Table of priorities (prioritni tabulky) 90 27BD Scanning function (FN) 90 28AB FN-SKPOVR 92 28B2 LOOK-VARS (prohledani promennych) 92 2951 Stack function argument (uschovej argument funkce) 94 2996 STK-VAR (uloz promennou) 95 2A52 SLICING 97 2AB6 STK-STORE 98 2ACC INT-EXP 98 2AEE DE,(DE+1) 98 2AF4 GET-HL*DE 99 2AFF LET command 99 2BF1 STK-FETCH (vyzvednuti ze zasobniku) 102 MONITOR ROM - ZX Spectrum - 159 - 3713 Natural logarithm (#25) 136 3783 Reduce argument (#39) (uprava argumentu) 137 37AA Cosine (#20) 138 37B5 Sine (#1F) 138 37DA Tan (#21) 139 37E2 Arctan (#24) 139 3833 Arcsin (#22) 140 3843 Arccos (#23) 140 384A Square root (#28) 141 3851 Exponentiation (#06) 141 Seznam navesti monitoru serazeny podle adres 142 Seznam systemovych promennych serazeny podle adres 147 APPENDIX ( BASIC program for the main series ) ---------------------------------------------- Series generator 148 SIN X 148 EXP X 149 LN X 150 ATN X 151 The "DRAW" algorithm 152 The "CIRCLE" algorithm 152 Note on Small Integers and -65536 153 Obsah 155