| | S I N C L A I R Personal Computer $$$$$$$$$$$$$$$$$$$$$ $$$$$$$ $$$$$$$ $$$$$$$$$$$$$$$$$$$$$ $$$$$$$ $$$$$$$ $$$$$$$$$$$$$$$$$$$$$ $$$$$$$ $$$$$$$ $$$$$$$ $$$$$$$ $$$$$$$ $$$$$$$ $$$$$$$$$$$$$$ $$$$$$$ $$$$$$$$$$$$ $$$$$$$ $$$$$$$$$$ $$$$$$$ $$$$$$$$$$ $$$$$$$ $$$$$$$$$$$$ $$$$$$$ $$$$$$$$$$$$$$ $$$$$$$ $$$$$$$ $$$$$$$ $$$$$$$$$$$$$$$$$$$$$ $$$$$$$ $$$$$$$ $$$$$$$$$$$$$$$$$$$$$ $$$$$$$ $$$$$$$ $$$$$$$$$$$$$$$$$$$$$ $$$$$$$ $$$$$$$ $$$$$$$$$ $$$$$$$ $$$$$$$$$ $$$$$$$$$ $$$$$$$$$ $$$$$$$ $$$ $$$ $$$ $$$ $$$$$$$$$ $$$$$$$$ $$$$$$$$$ $$$$$$$$$ $$$$$$$$$ $$$$$$$$ $$$ $$$ $$$$ $$$$ $$$ $$$ $$$ $$$ $$$ $$$ $$$ $$$ $$$ $$$ $$$ $$$ $$$$$$$$$ $$$ $$$ $$$ $$$ $$$ $$$ $$$ $$$ $$$ $$$ $$$ $ $$$ $$$$$$$$$ $$$$$$$$ $$$$$$ $$$ $$$ $$$$$$$$ $$$ $$$ $$$ $$$ $$$$$$$$$ $$$$$$$ $$$$$$ $$$ $$$ $$$$$$$ $$$ $$$ $$$ $$$ $$$ $$$ $$$ $$$ $$$ $$$$$ $$$ $$$ $$$ $$$ $$$ $$$ $$$ $$$ $$$ $$$ $$$ $$$$$$ $$$ $$$ $$$ $$$ $$$$$$$$$ $$$ $$$$$$$$$ $$$$$$$$$ $$$ $$$ $$$ $$$ $$$ $$$ $$$ $$$$$$$$$ $$$ $$$$$$$$$ $$$$$$$$$ $$$ $$$ $$$ $$$$$$$ $$$ $$$ ----------------------------------------------------- | | | MONITOR ROM - ZX Spectrum | | | ----------------------------------------------------- MONITOR ROM - ZX Spectrum - 2 - INTERPRETACE PRIKAZU BASIC Tato cast monitoroveho programu povazuje basicky radek za soubor prikazu. Pro kazdy prikaz je zde "prikazova" rutina,ktera provede (interpretuje) prislusny prikaz jako sled instrukci ve strojovem kodu. HODNOCENI VYRAZU Spectrum ma velmi obsazny program pro hodnoceni vyrazu,ktery umoznuje vyuzit sirokou skalu typu promennych,funkci a operaci.Tato cast monitoru je opet dosti pomala a to prave proto,ze se zabyva vsemi moznymi alternativami. Zvlaste zpracovani retezcu je velmi dobre zvladnuto.Vsechny jednoduche retezce jsou ulozeny dynamicky a jejich stare kopie jsou okamzite,jakmile se stanou nadbytecnymi,zniceny.To znamena,ze neni potreba provadet vytridovani "smeti" tak jako u jinych systemu. ARITMETICKE RUTINY Spectrum pouziva dva typy cisel. Celociselne hodnoty v rozsahu -65535 az 65535 jsou takzvane kratke (integer) formy,zatimco vsechna ostatni cisla jsou ukla- dana v petibajtove forme zvane pohybliva radova carka (floating point).Soucas- na verze monitoru ma vsak bohuzel take dve nasledujici chyby: 1) Chyba v deleni ( 34. bit je pri deleni ztracen ). 2) Hodnota -65536 je nekdy ulozena ve forme integer a jindy ve forme floating point,coz nekdy pusobi problemy. FLOATING POINT KALKULATOR Kalkulator Spectra zpracovava cisla a retezce. Jeho operace jsou specifikovany tzv. "literaly". Tato cast monitoroveho programu obsahuje rutiny pro vsechny matematicke funkce. Funkce jako sin,exp,ln atd. jsou ziskavany aproximacnim zpusobem. Aproximace se provadeji rozvojem Cebysevovych polynomu. Celkove se da rici,ze 16K monitor nabizi extremne siroky rozsah ruznych basickych prikazu a funkci,ale protoze jeho tvurci meli k dispozici jen omezeny prostor v pameti,je tento program spise kompaktnejsi nez rychlejsi. Rovnez je treba si uvedomit,ze v tak rozsahlem programu se lze pri jeho tvorbe dopustit nekolika chyb. Nektere z chyb nalezenych v monitoru Spectra jsou ne- podstatne a jsou spise rezu estetickeho nez funkcniho,nektere z chyb jsou jiz pak dost zavazne.Uzivatel je na tyto chyby ve vsech pripadech upozornen. MONITOR ROM - ZX Spectrum - 4 - 0048 PUSH BC ;Uschovej registry PUSH DE CALL #02BF ;Nyni testuj klavesnici POP DE ;Obnov registry POP BC POP HL POP AF EI ;Maskovane preruseni je pred navratem povoleno RET ERROR-2 - Rutina pro obslouzeni chyb ------------------------------------ Navratove adresy do prekladace ukazuji na data,ktera urcuji,ke ktere chybe doslo.Tato data jsou vyzvednuta a prenesena do systemove promenne ERR-NR.Nez se provede odskok dopredu a vycisteni zasobniku kalkulatoru,je take vycisten zasobnik. 0053 POP HL ;Adresa na zasobniku ukazuje na kod chyby LD L,(HL) 0055 LD (IY+0),L ;(ERR-NR) Je prenesena do ERR-NR a provede se LD SP,(#5C3D) ;vycisteni zasobniku pred odskokem do SET-STK JP #16C5 DEFB #FF,#FF,#FF,#FF ;Nevyuzita mista DEFB #FF,#FF,#FF Rutina nemaskovaneho preruseni ------------------------------ Tato rutina neni v normalnim SPECTRU vyuzita,ale mela by umoznovat NMI (nemaskovane preruseni).Systemova promenna na adrese #5CB0,ktera se jmenuje NMIADD,musi mit nulovou hodnotu aby doslo k resetu. 0066 PUSH AF ;Uschovej registry PUSH HL LD HL,(#5CB0) ;Dva bajty promenne NMIADD musi byt oba nulove LD A,H OR L JR NZ,#0070 ;Pozn.: Zde melo byt spravne JR Z,#0070 JP (HL) ;Skok na START 0070 POP HL ;Obnov hodnoty v registrech a vrat se POP AF RETN CH-ADD+1 -------- Adresa,ktera se nachazi v CH-ADD je inkrementovana a opet ulozena.Nyni se vezme obsah mista adresovaneho CH-ADD.Vstupni body rutiny TEMP-PIR1 a TEMP-PIR2 jsou pouzity,aby nastavily CH-ADD na prechodnou periodu. 0074 LD HL,(#5C5D) ;Vyzvedni adresu 0077 INC HL ;inkrementuj ukazatel 0078 LD (#5C5D),HL ;nastav adresu LD A,(HL) ;vyzvedni adresovanou hodnotu RET ;a vrat se SKIP-OVER --------- Hodnota,ktera do teto rutiny vstupuje v registru A,je testovana zda se jedna o znak,ktery je mozno tisknout.Ruzne specialni kody zpusobuji,ze registr HL je jednou nebo dvakrat inkrementovan a podle toho se soucasne upravuje hodnota CH-ADD. 007D CP #21 ;Vrat se s vynulovanym CY,jestlize se jedna RET NC ;o obycejny znak CP #0D ;Vrat se,jestlize bylo dosazeno konce radky RET Z CP #10 ;Jestlize se jedna o hodnotu v rozsahu RET C ;#00 az #0F vrat se s nastavenym CY CP #18 ;Vrat se s kody #18 az 20 CCF ;rovnez s nastavenym CY RET C INC HL ;Jednou preskoc CP #16 ;Skoc dopredu pri code #10 az 15 (prikazy INK JR C,#0090 ;az OVER) INC HL ;Jeste jednou skoc (prikazy AT & TAB) 0090 SCF ;Vrat se s nastavenym CY LD (#5C5D),HL ;a s CH-ADD nastavenou na prislusnou adresu RET MONITOR ROM - ZX Spectrum - 6 - TABULKY KLAVES --------------- Ve SPECTRU je 6 oddelenych tabulek klaves.Vysledny kod znaku zavisi na stisteni urcite klavesy a na momentalne pouzitem modu. (a) Tabulka hlavnich klaves - L mod a CAPS SHIFT. 0205 42 48 59 36 35 54 47 56 B H Y 6 5 T G V 020D 4E 4A 55 37 34 52 46 43 N J U 7 4 R F C 0215 4D 4B 49 38 33 45 44 58 M K I 8 3 E D K 021D 0E 4C 4F 39 32 57 53 5A SS L O 9 2 W S Z 0225 20 0D 50 30 31 51 41 SP EN P 0 1 Q A Pozn.: SS = SYMBOL SHIFT SP = SPACE EN = ENTER (b) Extended mode.Nesiftovane klavesy pismen. 022C E3 C4 E0 E4 READ BIN LPRINT DATA 0230 B4 BC BD BB TAN SGN ABS SQR 0234 AF B0 B1 C0 CODE VAL LEN USR 0238 A7 A6 BE AD PI INKEY$ PEEK TAB 023C B2 BA E5 A5 SIN INT RESTORE RND 0240 C2 E1 B3 B9 CHR$ LLIST COS EXP 0244 C1 B8 STR$ LN (c) Extended mode.Siftovane klavesy pismen. 0246 7E DC DA 5C ~ BRIGHT PAPER \ 024A B7 7B 7D D8 ATN { } CIRCLE 024E BF AE AA AB IN VAL$ SCREEN$ ATTR 0252 DD DE DF 7F INVERSE OVER OUT 0256 B5 D6 7C D5 ASN VERIFY | MERGE 025A 5D DB B6 D9 ] FLASH ACS INK 025E 5B D7 [ BEEP (d) Ridici kody.Klavesy cislic a CAPS SHIFT. 0260 0C 07 06 DELETE EDIT CAPS LOCK 0263 04 05 08 TRUE VIDEO INV VIDEO vlevo 0266 0A 0B 09 dolu nahoru vpravo 0269 0F GRAPHICS (e) Kody symbolu.Klavesy pismen a SYMBOL SHIFT. 026A E2 2A 3F CD STOP * ? STEP 026E C8 CC CB 5E >= TO THEN ^ 0272 AC 2D 2B 3D AT - + = 0276 2E 2C 3B 22 . , ; " 027A C7 3C C3 3E <= < NOT > 027E C5 2F C9 60 OR / <> ` 0282 C6 3A AND : (f) Extended mode.Klavesy cislic a SYMBOL SHIFT. 0284 D0 CE AB FORMAT DEF FN FN 0287 CA D3 D4 LINE OPEN # CLOSE # 028A D1 D2 A9 MOVE ERASE POINT 028D CF CAT MONITOR ROM - ZX Spectrum - 8 - 02D1 LD A,L ;Zmeni se ukazatel a testuje se 2.set.Nizsi LD HL,#5C04 ;bajt adresy 1.setu je porovnan s nizsim bajtem CP L ;adresy 2.setu a provede se odskok pri kontrole JR NZ,#02C6 ;2.setu.Provede se navrat,nebyla-li stistena ;zadna klavesa nebo pouze jedna z klaves SHIFT CALL #031E ;Proved nezbytne testy a vrat se je-li treba RET NC ;Nyni bude rozliseno zda se jedna o novy stisk, LD HL,#5C00 ;nebo je-li stistena nejaka klavesa jiz delsi CP (HL) ;dobu.Nejdrive zhodnot 1.set a shoduji-li se JR Z,#0310 ;hodnoty,skoc dopredu EX DE,HL ;jinak uschovej adresu KSTATE0 LD HL,#5C04 ;podivej se do 2.setu a jsou-li kody shodne, CP (HL) ;skoc dopredu (tzn. opakuj) JR Z,#0310 BIT 7,(HL) ;Nova klavesa bude akceptovana,je-li jeden ze JR NZ,#02F1 ;setu systemu KSTATE volny.Posud 2.set a je-li EX DE,HL ;volny skoc dopredu.Nyni testuj 1.set a pokra- BIT 7,(HL) ;cuj,je-li volny RET Z Nove tlacitko musi byt nyni akceptovano.Ale pred tim nez bude do LAST-K uloze- na nova hodnota,musi byt byte systemu KSTATE nastaveny na spravne hodnoty tak, aby neobsahovaly zadne opakovaci hodnoty.Nyni muze byt zjisten kod tlacitka. 02F1 LD E,A ;Kod je okopirovan do registru E LD (HL),A ;a do KSTATE0/4 INC HL LD (HL),#05 ;Pocitadlo pruchodu je nastaveno na hodn. 5 INC HL LD A,(#5C09) ;Treti promenna tohoto systemu je nastavena LD (HL),A ;na hodnotu systemove promenne REPDEL (0.7sec) INC HL ;HL ukazuje nyni na KSTATE3/7.Dekodovani hlav- LD C,(IY+7) ;(MODE) niho kodu zavisi na stavu MODE,bitu 3 LD D,(IY+1) ;(FLAGS) promenne FLAGS a SHIFToveho bajtu PUSH HL ;Vyzvedni hodnotu MODE a FLAGS a uschovej uka- CALL #0333 ;zatel po dobu dekodovani hlavniho kodu.Konecna POP HL ;hodnota je ulozena v promenne KSTATE3/7 odkud LD (HL),A ;je vybirana v pripade opakovani.Dalsi tri ;radky jsou spolecne pro vyhodnoceni jak nove 0308 LD (#5C08),A ;vlozenych klaves tak opakujicich klaves SET 5,(IY+1) ;(FLAGS) Do LAST-K vloz novou hodnotu a signa- RET ;lizuj,ze byla stlacena nova klavesa a vrat se K-REPEAT - Rutina opakovani klavesy ( AUTOREPEAT ) -------------------------------------------------- Klavesa bude opakovana pri prvnim vyskytu po zpozdovaci periode REPDEL (normalne za 0.7 sec.) a pri dalsich vyskytech (opakovani) po zpozdovaci periode REPPER (normalne 0.1 sec.). 0310 INC HL ;Ukazuj na citac 5ti volani v setu,ktery je LD (HL),#05 ;prave pouzivan a nastav ho na hodnotu 5 INC HL ;HL nyni ukazuje na 3.systemovou promennou, DEC (HL) ;tj. na REPPER/REPDEL,ktera je prave dekre- RET NZ ;mentovana a je proveden navrat,kdyz zpozdo- ;vaci perioda neprobehla LD A,(#5C0A) ;V opacnem pripade bude hodnotu zpozdeni uda- LD (HL),A ;vat hodnota na systemove promenne REPPER INC HL ;Opakovani bylo prijato,takze bude nakonec LD A,(HL) ;do registru A ulozena hodnota KSTATE3/7 JR #0308 ;a predana rutine K-END K-TEST ------ Hodnota klavesy je testovana a provede se navrat,jestlize nebyla stistena zadna klavesa nebo pouze nektery SHIFT.Jinak bude nalezen kod prislusne klavesy. 031E LD B,D ;Okopiruj SHIFTovaci bajt,vyuluj registr D LD D,#00 ;a prenes cislo klavesy do registru A LD A,E ;Bylo-li to CAPS SHIFT nebo zadna klavesa, CP #27 ;proved navrat RET NC CP #18 ;Pokud se nejedna o SYMBOL SHIFT, JR NZ,#032C ;provede se odskok dopredu BIT 7,B ;SYMBOL SHIFT a jine klavesy jsou akceptovany RET NZ ;Navrat je-li pouze o SYMBOL SHIFT.Hlavni kod 032C LD HL,#0205 ;je nalezen v tabulce hlavnich klaves.Bazova ADD HL,DE ;adresa tabulky.Najdi v tabulce kod klavesy LD A,(HL) SCF ;Signal: platny stisk RET MONITOR ROM - ZX Spectrum - 10 - REPRODUKTOROVE RUTINY ********************* Dva podprogramy v teto casti jsou: a) rutina BEEPER obsluhujici reproduktor; b) rutina pro prikaz BEEP. Reproduktor je aktivovan logickou 0 na bitu D4 behem instrukce OUT #FE,ktera pouziva port #FE.Podobne pri logicke 1 je reproduktor dezaktivovan.Stridanim logickych urovni na D4 vznika BEEP.(pozn. prekl.: D4 oznacuje bit 4 na datove sbernici.) Uvazujme ton stredni C,jehoz frekvence je 261.63 Hz.K vytvoreni tohoto tonu musi byt reproduktor stridave zapinan a vypinan kazdou 1/523.26 sekundy.Systemove hodiny ve SPECTRU jsou nastaveny na kmitocet 3.5 MHz a ton stredni C bude tedy vyzadovat vystridani logickych urovni kazdych 6689 T stavu.Tato posledni hodnota je nepatrne snizena aby se predeslo nevyhnutelnym casovym ztratam.Predstavuje delku casove smycky pro podprogram BEEPER. Podprogram BEEPER ----------------- Do tohoto podprogramu se vstupuje s hodnotou f*t v registrovem paru DE,kde F je dana frekvence po dobu t sekund.Registrovy par HL obsahuje pocet T stavu deleno 4.Tedy pro ton stredni C v trvani jedne sekundy DE obsahuje hodnotu #0105 coz je INT (261.63*1) a HL obsahuje #066A,coz je odvozeno od 6689/4-30.125 03B5 DI ;Zakaz preruseni behem trvani BEEPU LD A,L ;Prechodna uschova L SRL L ;Kazda "1" v registru L SRL L ;ma pocitat 4 T stavy,ale provedenim INT(L/4) CPL ;dochazi k citani 16 T stavu AND #03 LD C,A ;Vraci puvodni hodnotu do L a zjistuje zbytek LD B,#80 ;po deleni LD IX,#03D1 ;Bazova adresa casove smycky a oprava delky ADD IX,BC ;casove smycky za kazdou "1" zlomkove casti LD A,(#5C48) ;Vyzvedni soucasnou barvu pro BORDER a uloz ji AND #38 ;do bitu 0,1,2 registru A RRCA RRCA RRCA OR #08 ;Vystup MIC je vypnut Zde se vstupuje do smycky,ktera produkuje vlastni zvuk.V DE je pocet kompletnich pruchodu,HL obsahuje delku casove smycky. 03D1 NOP ;Pricte 4 T stavy za kazdy drivejsi vstupni 03D2 NOP ;bod,ktery je pouzit 03D3 NOP 03D4 INC B ;Hodnoty v BC prijdou z HL (viz dale) INC C 03D6 DEC C ;Casova smycka,tedy BC*4T stavy JR NZ,#03D6 ;(Pri polovicnim cyklu se bube C rovnat L+1) LD C,#3F DEC B JP NZ,#03D6 ;Reproduktor je nyni stridave zapinan a vypinan XOR #10 ;Flipuj bit 4 OUT (#FE),A ;Vykonej instrukci OUT pri zachovani BORDERu LD B,H ;Resetuj registr B LD C,A ;Uschovej registr A BIT 4,A ;Jestlize jsi v bode polovicniho cyklu,skoc JR NZ,#03F2 ;Po uplnem cyklu se testuje registrovy par DE LD A,D ;Jestlize byl jiz vykonan posledni kompletni OR E ;pruchod,skoc dal JR Z,#03F6 LD A,C ;Obnov uschovane hodnoty LD C,L ;Resetuj registr C DEC DE ;Dekrementuj citac pruchodu smyckou a skoc JP (IX) ;zpet na prislusnou pocatecni lokaci smycky ;Parametry pro druhy polovicni cyklus jsou na- ;staveny 03F2 LD C,L ;Resetuj registr C,pricti 18 T stavu,protoze INC C ;tato cesta je kratsi a skoc zpet JP (IX) ;na prislusnou pocatecni lokaci smycky ;Maskovane preruseni je povoleno po ukonceni ;BEEPu 03F6 EI ;Dovoleni preruseni RET ;Zaverecny navrat MONITOR ROM - ZX Spectrum - 12 - Pocet kompletnich cyklu pro BEEP je dan soucinem f*t. RST #28 ;t DEFB #E0 ;GET-MEM-0 t,f DEFB #04 ;nasobeni f*t DEFB #E0 ;GET-MEM-0 f*t,f DEFB #34 ;STK-DATA Na vrcholu zasobniku se vytvori DEFB #80 ;KK=3.5*10^6/8 konstanta 4 bajty (KK=437500) DEFB #43 ;exponent #93 DEFB #55,#9F,#80,(#00) f*t,f,KK DEFB #01 ;zamena f*t,KK,f DEFB #05 ;deleni f*t,KK/f DEFB #34 ;STK-DATA DEFB #35 ;exponent #85 DEFB #71,(#00,#00,#00) f*t,KK/f,30.125 DEFB #03 ;odecitani f*t,KK/f-30.125 DEFB #38 ;konec vypoctu Poznamka: Hodnota 437500/f dava delku polovicniho cyklu.Jeji snizeni o 30.125 poskytne 120.5 T stavu,behem kterych dojde k produkci noty,nastaveni citacu a podobne.Nyni se prenesou hodnoty do patricnych registru. CALL #1E99 ;Hodnota casove smycky je kompresovana do BC PUSH BC ;a je uschovana Poznamka: Jestlize je tato hodnota prilis vysoka,dojde k vyvolani chybove rutiny,coz vylouci hodnoty od +70 az +127. CALL #1E99 ;Hodnota f*t je kompresovana do BC POP HL ;Casova smycka do HL LD D,B LD E,C ;f*t do DE Nyni posledni test hodnoty f*t. LD A,E OR E ;Navrat,pokud nejsou pozadovany zadne cykly RET Z DEC DE ;Dekrementace citace pruchodu smyckou JP #03B5 ;a skok do rutiny BEEPER 046C RST #08 ;Ohlas: B - Integer out of range DEFB #0A TABULKA PULTONU --------------- Tato tabulka obsahuje frekvence dvanacti pultonu v oktave. frekvence (Hz) ton 046E DEFB #89,#02,#D0,#12,#86 261.63 C DEFB #89,#0A,#97,#60,#75 277.18 C# DEFB #89,#12,#D5,#17,#1F 293.66 D DEFB #89,#1B,#90,#41,#02 311.13 D# DEFB #89,#24,#D0,#53,#CA 329.63 E DEFB #89,#2E,#9D,#36,#B1 349.23 F DEFB #89,#38,#FF,#49,#3E 369.99 F# DEFB #89,#43,#FF,#6A,#73 392 G DEFB #89,#4F,#A7,#00,#54 415.30 G# DEFB #89,#5C,#00,#00,#00 440 A DEFB #89,#69,#14,#F6,#24 466.16 A# DEFB #89,#76,#F1,#10,#05 493.88 B "NAZEV PROGRAMU" (ZX 81) ------------------------ Nasledujici program je pro ZX81 a nebyl odstranen,kdyz se program prepisoval pro SPECTRUM. 04AA DEFB #CD,#FB,#24,#3A DEFB #3B,#5C,#87,#FA DEFB #8A,#1C,#E1,#D0 DEFB #E5,#CD,#F1,#2B DEFB #62,#6B,#0D,#F8 DEFB #09,#CB,#FE,#C9 MONITOR ROM - ZX Spectrum - 14 - 051A DJNZ #051A ;Pri 1.pruchodu MIC on a modra.Pri 2.pruchodu 051C OUT (#FE),A ;MIC off a zluta LD B,#3E ;Casova konstanta pro 2.pruchod JR NZ,#0511 ;Zpet na konec 1.pruchodu DEC B ;jinak puls 13 T XOR A ;CY nastaven na nulu INC A ;Registr A je 1; MIC on a modra Smycka 8 bitu: Registr L obsahuje nahravany bajt a bit prenosu CY je nastaven na jedna (jako navesti) z rutiny SA-START.Kazdy bit je odeslan a CY vynulovan. Po osmi pruchodech rutinou bude registr L vynulovan a program pokracuje dal. 0525 RL L ;Bit 7 do CY a navesti do bitu 0 JP NZ,#0514 ;Opakovani do vynulovani registru L DEC DE ;Dekrementuj citac bajtu INC IX ;Posun bazovou adresu o 1 vpred LD B,#31 ;Nastav casovou konstantu pro prvni bit LD A,#7F ;dalsiho bajtu.Adresa portu pro klavesu BREAK IN A,(#FE) ;a jeji otestovani.Navrat (do SA-LD-RET) RRA ;v pripade stisknuti BREAK RET NC LD A,D ;jinak test citace bajtu a skok zpet i kdyz je INC A ;citac nulovy (aby bylo mozno odeslat jeste JP NZ,#04FE ;paritni bajt LD B,#3B ;Navrat,jestlize je citac bajtu nastaven 053C DJNZ #035C ;na #FFFF,ale az po kratke prodleve RET Poznamka: Vynulovany bit zpusobi puls MIC off nasledovany pulsem MIC on,oba v delce 855 T stavu.Jednickovy bit dava pulsy 2krat delsi.Povsimnete si, ze mezi synchronizacnim pulsem,indikacnim bajtem a dalsimi bajty nejsou zadne mezery. SA/LD-RET --------- Je spolecna pro SAVE i LOAD.BORDER je nastaven na puvodni barvu a naposledy je testovano tlacitko BREAK. 053F PUSH AF ;Ulozeni CY (CY je resetovano pri chybe LOADu) LD A,(#5C48) ;Vyzvednuti barvy BORDERu ze systemove promenne AND #38 RRCA RRCA RRCA ;Prenos barvy BORDERu do bitu 2,1,0 OUT (#FE),A ;Nastav BORDER na puvododni barvu LD A,#7F ;Test tlacitka BREAK IN A,(#FE) RRA EI ;Povoleni mask. preruseni JR C,#0554 ;Neni-li BREAK,skoc na SA/LD-END 0552 RST #08 ;Ohlas: D - BREAK-CONT repeats DEFB #0C 0554 POP AF ;Obnoveni puvocniho stavu CY RET ;Navrat do volaci rutiny LD-BYTES -------- Tato rutina je volana pro funkce LOAD nebo VERIFY hlavicky (z #076E) nebo dat (z #0802). 0556 INC D ;Z je vynulovan (nebot D nemuze obsahovat #FF) EX AF,AF' ;V A je #00 pro hlavicku a #ff pro blok dat,CY DEC D ;je 0 pro VERIFY a 1 pro LOAD.Registr D zpet DI ;na puvodni hodnotu a zakaz preruseni LD A,#0F ;Bily BORDER OUT (#FE),A LD HL,#053F ;Adresa SA/LD-RET na zasobnik PUSH HL IN A,(#FE) ;Test portu #FE RRA ;Rotace nact. bajtu,ale zvazeni jen bitu EAR AND #20 OR #02 ;Signal border cerveny je ulozen i do regis- LD C,A ;tru C (#22 pro OFF a #02 pro ON stav vstupu CP A ;EAR).Nulovy indikator je nastaven na 1 Prvnim ukolem pri cteni dat z pasku je zjistit,zda existuje nejaky pulsni signal (tedy hrany on-off a off-on). 056B RET NZ ;Navrat pri BREAKu 056C CALL #05E7 ;Neni-li pritomen signal behem 1400 T stavu, JR NC,#056B ;navrat s CY=1.Jinak je BORDER nastaven LD HL,#0415 ;na cyan.Dale se ceka a zjistuje,zda je signal 0574 DJNZ #0574 ;stale pritomen.Delka cekani je temer DEC HL ;1 sekunda LD A,H OR L MONITOR ROM - ZX Spectrum - 16 - Nasleduje vzorkovaci smycka.Obsah registru B je zvysen pri kazdem pruchodu. Navrat "bez nalezu" pri dosazeni 0 v registru B. 05ED INC B ;Citani pruchodu RET Z ;CY=0 & Z=1 "bez nalezu" LD A,#7F ;Cteni z portu #7FFE (BREAK a EAR) IN A,(#FE) RRA RET NC ;CY=0 & Z=0,kdyz byla stisknuta klavesa BREAK XOR C ;Test bajtu s poslednim "typem hrany" AND #20 JR Z,#05ED ;Skok zpet,je-li bez zmeny Byla nalezena nova hrana v dovolenem case periody.Nyni se zmeni barva BORDERu a CY se nastavi na 1. LD A,C ;Zmena posledniho "typu hrany" a barvy BORDERu CPL LD C,A AND #07 ;Bere se jen barva BORDERu OR #08 ;Signal MIC-off OUT (#FE),A ;Zmena barvy BORDERu (cervena - cyan nebo SCF ;modra - zluta).Signalizace uspesneho nalezeni RET ;pred navratem Rutina LD-EDGE-1 trva 465 T; plus 58 T z kazdeho pruchodu vzorkovaci smyckou pri neuspesnem hledani.Napriklad pri ocekavani sync pulsu (viz LD-SYNC na #058F) je povoleno 10 pruchodu vzorkovaci smyckou.Hledani hrany probiha behem cca 1100 T (465+10*58+prechody).Tak je zajisteno zachyceni casti off pulsu sync,ktery prichazi po dlouhych pulsech zavadeciho signalu. RUTINY PRIKAZU SAVE,LOAD,VERIFY,MERGE ===================================== SAVE-ETC -------- Uziva se jako vstupni bod pro vsechny ctyri povely.Hodnota v T-ADDR se u jednotlivych funkci lisi.V prvni casti rutiny probiha konstrukce hlavicky v pracovni oblasti (WORKSPACE). 0605 POP AF ;Zniceni navratove adresy SCAN-LOOP LD A,(#5C74) ;Redukce T-ADDR-lo o #E0; pak je 00 pro SAVE SUB #E0 ;01 pro LOAD,02 pro VERIFY,03 pro MERGE LD (#5C74),A CALL #1C8C ;Ulozeni parametru na zasobnik kalkulatoru CALL #2530 ;Skok pri testovani syntaxe JR Z,#0652 LD BC,#0011 ;17 adres pro hlavicku SAVE, LD A,(#5C74) ;ale 34 pro ostatni povely AND A JR Z,#0621 LD C,#22 0621 RST #30 ;Vytvori se pozadovany prostor v pracovni PUSH DE ;oblasti POP IX ;Predani parametru z DE do IX LD B,#0B ;Nazev programu muze mit az 10 znaku,ale nej- LD A,#20 ;drive se ulozi 11 mezer na pripravene misto 0629 LD (DE),A INC DE DJNZ #0629 LD (IX+1),#FF ;Nulove jmeno jen pri #FF CALL #2BF1 ;Parametry jmena jsou vyvolany a je testovana LD HL,#FFF6 ;jeho delka.Tato hodnota je -10 (komplement) DEC BC ;Neni-li jmeno delsi nez 10 pokracuje se dal ADD HL,BC INC BC JR NC,#064B LD A,(#5C74) ;Ale LOAD,VERIFY,MERGE jsou umozneny i pri AND A ;nulovych a velmi dlouhych nazvech JR NZ,#0644 0642 RST #08 ;Ohlas: F - Invalid file name DEFB #0E 0644 LD A,B ;Pokracovani prace se jmenem programu: OR C ;Skok dal,je-li delka nazvu nulova JR Z,#0652 LD BC,#000A ;Useknuti prebytecnych znaku 064B PUSH IX ;Nyni je nazev prenesen do WORKSPACE (od jeho POP HL ;druhe adresy).Presun pocatecni adresy do re- INC HL ;gisru HL.Posun na druhou adresu EX DE,HL ;Vymena ukazatelu a prenos jmena LDIR 0652 RST #18 ;Dale jsou zvazovany nektere parametry,pripo- CP #E4 ;jene za povel (pokud existuji).Nacteni znaku JR NZ,#06A0 ;Jedna se o znak "DATA"?Skoc,kdyz ne LD A,(#5C74) CP #03 ;Neni mozny MERGE "nazev" DATA MONITOR ROM - ZX Spectrum - 18 - 0716 CP #CA ;Zjisteni pritomnosti LINE a dalsich moznych JR Z,#0723 ;parametru.Je-li token LINE,skoc zpet CALL #1BEE ;Posun na dalsi cast povelu pri zjistovani LD (IX+14),#B0 ;syntaxe.Uz nejsou dalsi parametry JR #073A 0723 LD A,(#5C74) ;Zjisteni cisla,ktere musi nasledovat po vyrazu AND A ;LINE.Nelze provest SAVE "nazev" LINE bez JP NZ,#1C8A ;udani cisla RST #20 ;Vyzvednuti nasledujiciho znaku a zvyseni CH-ADD CALL #1C82 ;Ulozeni cisla do kalkulatoroveho zasobniku CALL #1BEE ;Posun na dalsi cast povelu pri zjistovani CALL #1E99 ;syntaxe.Prenos cisla radku autostartu do BC LD (IX+13),C ;a jeho ulozeni LD (IX+14),B 073A LD (IX+0),#00 ;LINE a zadny parametr jsou oba typu 0 Parametry urcujici program a jeho promenne jsou nalezeny a ulozeny do hlavickove casti pracovni oblasti. LD HL,(#5C59) ;Ukazatel konce oblasti promennych LD DE,(#5C53) ;Ukazatel pocatku basickeho programu SCF ;Odecet pro urceni delky programu + promennych SBC HL,DE ;a jeji ulozeni LD (IX+11),L LD (IX+12),H LD HL,(#5C4B) ;Opakovani odectu,ale jen pro zjisteni delky SBC HL,DE ;samotneho programu LD (IX+15),L LD (IX+16),H EX DE,HL ;Presun ukazatele do HL Ve vsech pripadech byly pripraveny hlavickove informace: -------------------------------------------------------- IX+00 obsahuje cislo typu dat IX+01 az IX+10 obsahuje jmeno (#FF v IX+1 znamena data bez jmena) IX+11 az IX+12 obsahuje pocet bajtu bloku dat IX+13 az IX+16 obsahuje ruzne parametry,jejichz obsah zalezi na typovem cisle 075A LD A,(#5C74) ;Nyni se separuje jedna z operaci SAVE,LOAD, AND A ;VERIFY nebo MERGE JP Z,#0970 ;Je-li povel SAVE,skoc dopredu V pripade zbylych tri operaci je prvnich 17 bajtu hlavickove casti pracovni oblasti vybaveno informacemi,jak je uvedeno vyse.Ted je cas pro odebrani hlavicky z pasku. PUSH HL ;Ulozeni ukazatele adresu urceni LD BC,#0011 ;Formovani 1.adresy 2.hlavickove oblasti do IX ADD IX,BC 0767 PUSH IX ;Smycka pro nacteni hlavicky.Ulozeni 1.adresy LD DE,#0011 ;2.hlavickove oblasti.LOAD 17ti bajtu XOR A ;Signal: LOAD CALL #0556 ;Hledani hlavicky POP IX ;Obnova 1.adresy 2.hlavickove oblasti JR NC,#0767 ;Skoky dokud neskonceno Nova hlavicka se vypise na obrazovce,ale rutina pokracuje jen tehdy,kdyz se "novy" typ nelisi od "stareho": LD A,#FE CALL #1601 ;Ujisteni,ze kanal S je otevren LD (IY+82),#03 ;(SCR-CT) Nastaveni citace skrolovani LD C,#80 ;Signal: typy se nelisi LD A,(IX+0) CP (IX-17) ;Porovnani "noveho" typu se "starym" JR NZ,#078A ;Lisi-li se,skoc LD C,#F6 ;Kdyz OK.,tak dej signal: 10 znaku a porovnej 078A CP #04 ;je.Je-li cislo "typu 4" a vice je hlavicka JR NC,#0767 ;nesmyslna a odskakuje se LD DE,#09C0 ;1.adresa bloku uvedenych hlaseni PUSH BC ;Ulozeni registru C dokud neni zobrazeno CALL #0C0A ;hlaseni: Program:,Number array:, POP BC ;Character array:,Bytes: . "Nove" jmeno bylo PUSH IX ;zobrazeno a bude se porovnavat se "starym" POP DE ;Do DE je prenesena adresa typoveho bajtu LD HL,#FFF0 ;"noveho jmena.V HL je vytvorena adresa ADD HL,DE ;typoveho bajtu "stareho" jmena LD B,#0A ;Konstanta pro porovnani 10ti znaku nazvu LD A,(HL) INC A JR NZ,#07A6 ;Jedna-li se o nejaky typ hlavicky,skoc LD A,C ;Jinak je signalizovano uspesne porovnani ADD A,B ;(To je z toho duvodu,ze se jednalo jiz LD C,A ;o samotny blok dat) MONITOR ROM - ZX Spectrum - 20 - 082E POP HL ;LOAD pole.Obnov ukazatel a skoc,jedna-li se LD A,(IX+0) ;o LOAD basickeho programu AND A JR Z,#0873 LD A,H OR L JR Z,#084C ;Skoc,jedna-li se o LOAD noveho pole DEC HL ;Ulozeni delky existujiciho pole do BC LD B,(HL) DEC HL LD C,(HL) DEC HL ;Posun na stare jmeno.Pricteni dvou bajtu INC BC ;pro delku a jeden bajt pro jmeno INC BC INC BC LD (#5C5F),IX ;Uschovani IX,dokud se pracuje se starym polem CALL #19E8 LD IX,(#5C5F) 084C LD HL,(#5C59) ;Urceni mista pro ulozeni noveho pole.Nalezeni DEC HL ;konce oblasti promennych,ktery je oznacen LD C,(IX+11) ;bajtem #80.Do BC je ulozena delka noveho LD B,(IX+12) ;pole,ktera je okamzite uschovana PUSH BC INC BC ;Nyni se prictou 3 bajty pro jmeno a delku pole INC BC INC BC LD A,(IX-3) ;Je zjisten nazev pole a okamzite uschovan PUSH AF CALL #1655 ;Je vytvoren prostor v poctu BC bajtu INC HL ;HL ukazuje na 1.bajt pole,kam bude po POP AF ;zjisteni ulozeno jeho jmeno LD (HL),A POP DE ;Opet je vyzvednuta delka pole a po bajtech INC HL ;ulozena LD (HL),E INC HL LD (HL),D ;HL nyni ukazuje na adresu,kam bude ukladan INC HL ;jiz samotny obsah pole.Tato adresa je zaroven PUSH HL ;okamzite prenesena do IX POP IX SCF ;Signal: LOAD LD A,#FF ;Signal: blok dat JP #0802 ;Skok na LOADovaci rutinu LOAD basickeho programu a jeho promennych: 0873 EX DE,HL ;Uschovani 1.adresy programu do DE.Nalezeni LD HL,(#5C59) ;konce oblasti promennych,ktery je oznacen DEC HL ;bajtem #80.Uschovani IX.Do BC je ulozena LD (#5C5F),IX ;delka programu a okamzite uschovana LD C,(IX+11) LD B,(IX+12) PUSH BC CALL #19E5 ;Tato rutina znici stary basicky program POP BC ;Delka noveho programu je opet ulozena do BC PUSH HL ;Jsou uschovany ukazatele programove oblasti PUSH BC ;a delky programu CALL #1655 ;Vytvoreni noveho mista pro program a promenne LD IX,(#5C5F) ;Obnoveni hodnoty v IX INC HL ;Systemova promenna VARS je nastavena na novou LD C,(IX+15) ;hodnotu,ktera jiz odpovida parametrum noveho LD B,(IX+16) ;programu ADD HL,BC LD (#5C4B),HL LD H,(IX+14) ;Je testovano,zda byl pritomen prikaz LINE LD A,H AND #C0 JR NZ,#08AD ;Skok,jestlize se nejedna o autostart LD L,(IX+13) ;Jinak jsou nastaveny systemove promenne LD (#5C42),HL ;NEWPPC a NSPPC LD (IY+10),#00 ;(NSPPC) 08AD POP DE ;Nyni muze byt nacten blok dat.Je vyzvednuta POP IX ;delka a adresa 1.bajtu programu SCF ;Signal: LOAD LD A,#FF ;Signal: blok dat JP #0802 MONITOR ROM - ZX Spectrum - 22 - MERGE A LINE OR VARIABLE ------------------------ Do tohoto podprogramu se vstupuje s nasledujicimi parametry: CY = 0 - MERGE basickeho radku CY = 1 - MERGE promenne Z = 0 - bude se pridavat Z = 1 - bude se nahrazovat HL - ukazuje na start noveho vstupu DE - ukazuje,kam se provede MERGE 092C JR NZ,#093E ;Skoc,jde-li o "pridavek" EX AF,AF' ;Uschovej flagy a "novy" ukazatel,zatimco bude LD (#5C5F),HL ;provedena likvidace stareho radku nebo EX DE,HL ;promenne CALL #19B8 CALL #19E8 EX DE,HL ;Restauruj vsechny ukazatele a flagy LD HL,(#5C5F) EX AF,AF' 093E EX AF,AF' ;Nyni muze dojit k vlozeni "noveho".Uschovej PUSH DE ;flagy a cilovy ukazatel CALL #19B8 ;Nalezni delku "noveho" LD (#5C5F),HL ;Uschovej ukazatel na "nove" LD HL,(#5C53) ;Vyzvedni PROG,aby se predeslo poskozeni EX (SP),HL ;Uschovej ho na zasobniku vyzvedni ukazatel PUSH BC ;"noveho" a uschovej delku EX AF,AF' ;Obnov flagy JR C,#0955 ;Skoc pri pridavani nove promenne DEC HL ;Novy radek je vlozen pred cilovou lokaci CALL #1655 ;Vytvor prostor pro novy radek INC HL JR #0958 ;Skoc dopredu 0955 CALL #1655 ;Vytvor prostor pro novou promennou 0958 INC HL ;Ukazuj na 1.novou lokaci POP BC ;Obnov delku POP DE ;Vyzvedni PROG a uloz na patricne misto LD (#5C53),DE LD DE,(#5C5F) ;Tez vyzvedni novy ukazatel a opet uloz delku PUSH BC ;a "novy" ukazatel PUSH DE EX DE,HL ;Zamen ukazatele a kopiruj "nove" do prostoru, LDIR ;ktery byl vytvoren.Nova promenna nebo radek POP HL ;musi byt nyni odstranen z pracovniho prostoru POP BC ;Vyzvedni ukazatel na "nove".Vyzvedni delku PUSH DE ;Uschovej ukazatel na "stare" CALL #19E8 ;Odstran radek nebo promennou z prac. prostoru POP DE ;Vyzvedni ukazatel na "stare" a vrat se RET RUTINA SAVE CONTROL ------------------- Rutina SAVE je velmi primocara. 0970 PUSH HL ;Uschovej si ukazatel LD A,#FD ;Signal: kanal K CALL #1601 ;Otevri kanal K XOR A ;Signal 1.hlaseni LD DE,#09A1 ;Baze tabulky kazetovych hlaseni CALL #0C0A ;Tiskni hlaseni: Start tape,press any key SET 5,(IY+2) ;(TV-FLAG) Signal: obrazovka bude vyzadovat CALL #15D4 ;smazani.Cekej na stisk klavesy.Po stisknuti PUSH IX ;klavesy se zacne nahravat hlavicka.Uschovej LD DE,#0011 ;si adresu hlavicky.Pocitadlo 17ti bajtu,ktere XOR A ;budou nahrany.Signal: hlavicka CALL #04C2 ;Nahrani hlavicky POP IX ;Obnoveni adresy hlavicky LD B,#32 ;Nasleduje pauza asi 1 sec. pred nahranim dat 0991 HALT DJNZ #0991 ;Pauza 50ti preruseni LD E,(IX+11) ;Do DE uloz delku zaznamenavaneho bloku dat LD D,(IX+12) LD A,#FF ;Signal: blok dat POP IX ;Obnoveni ukazatele 1.adresy bloku a nakonec JP #04C2 ;se vsechno nahraje Kazetova hlaseni ---------------- Kazde hlaseni je zakonceno invertovanym znakem,tzn. bit 7 tohoto znaku je log. 1.Bajt #0D (carriage return) zpusobi tisk od leveho okraje na dalsim radku. 09A1 DEFB #80 ;Pro inverzi znaku 09A2 DEFM #??,'Start tape,press any key.' 09C1 DEFM #0D,'Program:' 09CB DEFM #0D,'Number array:' 09DA DEFM #0D,'Character array:' 09EC DEFM #0D,'Bytes:' MONITOR ROM - ZX Spectrum - 24 - Podprogram TISKNI CARKU ----------------------- Soucasna sloupcova hodnota je manipulovana a registr A je nastaven na #00 pro TAB 0,nebo na #10 pro TAB 16. 0A5F CALL #0B03 ;Proc znovu ? LD A,C ;Cislo sloupce DEC A DEC A ;Posun doprava o dva sloupce a test AND #10 ;V registru A bude nyni #00 nebo #10 JR #0AC3 ;Vystup pres PO-FILL Podprogram TISK OTAZNIKU ------------------------ Kdykoliv dojde k pokusu o tisk znaku,ktery tisknout nelze,vytiskne se misto nej otaznik. 0A69 LD A,#3F ;Kod otazniku JR #0AD9 ;Tisk znaku Ridici znaky s operandy ----------------------- Ridici znaky od INK do OVER vyzaduji jeden operand,zatimco ridici znaky AT & TAB musi byt nasledovany dvema operandy.Tato rutina v pripade jednoho operandu ulozi kod ridiciho znaku do TVDATA-lo a operand je v registru A. V pripade dvou operandu je prvy ulozen do TVDATA-hi a druhy v registru A. 0A6D LD DE,#0A87 ;Zmena adresy pro "vystupni rutinu" na #0A87 LD (#5C0F),A ;Uloz prvy operand do TVDATA-hi JR #0A80 Pro AT a TAB je vstupni bod zde. 0A75 LD DE,#0A6D ;Zmena adresy pro "vystupni rutinu" na #0A6D JR #0A7D Vstupni bod pro ridici znaky barev INK az OVER. 0A7A LD DE,#0A87 ;Zmena adresy pro "vystupni rutinu" na #0A6D 0A7D LD (#5C0E),A ;Uloz kod ridiciho znaku Adresa "vystupni rutiny" je zmenena prechodne. 0A80 LD HL,(#5C51) ;HL ukazuje na adresu "vystupni" rutiny LD (HL),E ;Vlozeni teto nove adresy zpusobi,ze dalsi INC HL ;kod bude povazovan za operand LD (HL),D RET Jakmile jsou operandy ulozeny,rutina pokracuje 0A87 LD DE,#09F4 ;Obnoveni puvodni adresy pro PRINT-OUT (#09F4) CALL #0A80 ;Vyzvedni ridici kod a prvy operand (jestli LD HL,(#5C0E) ;budou dva operandy). "posledni" operand LD D,A ;a ridici kod jsou presunuty LD A,L CP #16 ;Jedna-li se o INK az OVER,pak skok dopredu JP C,#2211 JR NZ,#0AC2 ;Skok dopredu jde-li o TAB Nyni zpracuj ridici charakter AT. LD B,H ;Cislo radku LD C,D ;Cislo sloupce LD A,#1F ;Prevraceni cisla sloupce tj. #00 az #1F se SUB C ;zmeni na #1F az #00 JR C,#0AAC ;Musi byt v rozsahu ADD A,#02 ;Pricteni doplnku,aby C obsahoval #21 az #22 LD C,A BIT 1,(IY+1) ;(FLAGS) Pri obsluze tiskarny skok dopredu JR NZ,#0ABF LD A,#16 ;Prevraceni cisla radku tj. #00 az #15 se SUB B ;zmeni na #16 az #01 0AAC JP C,#1E9F ;Je-li vse v poradku,skok dopredu INC A ;Rozsah #16 az #01 se zmeni na #17 az #02 LD B,A INC B ;A nyni na #18 az #03 BIT 0,(IY+2) ;(TV-FLAG) Jedna-li se o tisk v dolni casti JP NZ,#0C55 ;obrazovky,proved pripadny skrol CP (IY+49) ;(DF-SZ) Vyvolej chybove hlaseni pri nedostat- JP C,#0C86 ;ku mista 0ABF JP #0DD9 ;Navrat pres CL-SET k PO-STORE 0AC2 LD A,H ;Zde zpracuj ridici znak.Vyzvedni prvy operand 0AC3 CALL #0B03 ;Aktualni tiskova pozice ADD A,C ;Pricteni aktualni sloupcove hodnoty DEC A ;Zjisti kolik "mezer",modulo 32 je zapotrebi MONITOR ROM - ZX Spectrum - 26 - JR NZ,#0B4C ;polovina RET 0B52 SUB #A5 ;Nyni se oddeli znaky UDG a tokens JR NC,#0B5F ;Skok dopredu pri tokens ADD A,#15 ;Znaky UDG jsou nyni od #00 do #0F PUSH BC ;Uschovej hodnoty aktualni tiskove pozice LD BC,(#5C7B) ;Vyzvedni bazovou adresu oblasti UDG JR #0B8A ;Skoc dopredu 0B5F CALL #0C10 ;Vytiskni token a vrat se pres PO-FETCH JP #0B03 0B65 PUSH BC ;Uschovej hodnoty soucasne pozice LD BC,(#5C36) ;Vyzvedni bazovou adresu oblasti CHARS 0B6A EX DE,HL ;a uschovej tiskovou adresu v HL LD HL,#5C3B ;Umozni uvodni mezeru RES 0,(HL) ;Jestlize se nejedna o mezeru, CP #20 ;potom skoc dopredu JR NZ,#0B76 SET 0,(HL) ;Ale potlac uvodni mezeru jestlize jiz existuje 0B76 LD H,#00 ;Prevedeni kodu znaku do HL LD L,A ADD HL,HL ADD HL,HL ADD HL,HL ;HL=HL*8 ADD HL,BC ;Nalezeni bazove adresy znaku.Je vyzvednuta POP BC ;aktualni tiskova pozice a bazova adresa EX DE,HL ;prevedena do DE Podprogram tisk vsech znaku --------------------------- Tento podprogram tiskne osmibitove matice vsech znaku.Na vstupu obsahuje DE bazovou adresu znakove formy,HL cilovou adresu a v BC je aktualni tiskova pozice pro radek a sloupec. 0B7F LD A,C ;Vezmi cislo sloupce a posun se o 1 pozici DEC A ;vpravo LD A,#21 JR NZ,#0B93 ;Nejde-li o novy radek,skoc dopredu DEC B ;Posun o 1 pozici dolu LD C,A BIT 1,(IY+1) ;(FLAGS) JR Z,#0B93 ;Pri obsluze obrazovky skok dopredu PUSH DE ;Uschovej bazovou adresu behem vyprazdnovani CALL #0ECD ;bafru a obnov ji POP DE LD A,C ;Vezmi cislo noveho sloupce 0B93 CP C ;Testuj zda-li byl pouzit novy radek PUSH DE CALL Z,#0C55 ;Kdyz ano,podivej se zda neni treba skrolovat POP DE ;displej Nyni posud soucasny stav INVERSE & OVER. PUSH BC ;Uschovej pozicni a cilove hodnoty PUSH HL LD A,(#5C91) ;Vyzvedni P-FLAG LD B,#FF ;Priprav masku #FF pro OVER 1 RRA JR C,#0BA4 ;Testuj bit 0 a proved skok pri OVER 1 INC B ;Uprav masku na #00 pro OVER 0 0BA4 RRA ;Rotuj bit 2 do CY a priprav masku #00 RRA ;pro INVERSE 0 a masku #FF pro INVERSE 1 SBC A,A LD C,A ;Uloz masku do registru C LD A,#08 ;Nastav registr A jako citac pixlovych radku AND A ;Nuluj CY flag BIT 1,(IY+1) ;(FLAGS) Pri obsluze obrazovky skoc dopredu JR Z,#0BB6 SET 1,(IY+48) ;(FLAGS-2) Signal:bafr jiz neni prazdny SCF ;Nastav CY jako signal:pouziva se tiskarna 0BB6 EX DE,HL ;Pred vstupem do smycky zamen bazovou a cilo- ;vou adresu Zde bude behem osmi pruchodu smyckou proveden tisk znaku. 0BB7 EX AF,AF' ;Uschovej CY flag v registru F' LD A,(DE) ;Vyzvedni stavajici pixlovy radek AND B ;Pouzij masku pro OVER XOR (HL) ;a vysledek XORuj s pixlovym radkem XOR C ;Proved XOR take s maskou pro INVERSE LD (DE),A ;a uloz na cilovou adresu EX AF,AF' JR C,#0BD3 ;Vyzvedni CY a skoc,je-li nastaven pro tiskarnu INC D ;Uprav cilovou adresu 0BC1 INC HL ;Posun se na dalsi radek zdrojove matice DEC A ;Dekrementuj citac a skoc zpet,pokud neni JR NZ,#0BB7 ;nulovy.HL musi obsahovat spravnou vyssi MONITOR ROM - ZX Spectrum - 28 - Podprogram PO-SAVE ------------------ Tento podprogram umoznuje tzv. rekursivni tisk (tim ze vola sam sebe).Obsahy registru jsou uschovany. 0C3B PUSH DE ;Uschovej DE,HL a BC EXX RST #10 ;Vytiskni jeden znak a obnov HL,BC a DE EXX POP DE RET Podprogram PROHLEDAVANI TABULEK ------------------------------- Tento podprogram vraci DE jako ukazatel na prvni znak pozadovane polozky a CY=0,ma-li byt posouzena uvodni mezera. 0C41 PUSH AF ;Uschovej cislo polozky.Bazova adresa do HL EX DE,HL INC A ;Uprav rozsah na #00 az "?".Cekej na inverto- 0C44 BIT 7,(HL) ;vany znak a pokud neni,vracej se do smycky INC HL JR Z,#0C44 DEC A ;Pocitej polozky,dokud nenajdes tu pozadovanou JR NZ,#0C44 EX DE,HL ;DE ukazuje na prvni znak.Vyzvedni cislo POP AF ;polozky a pro prvnich 32 cisel se vracej CP #20 ;s CY=1 RET C LD A,(DE) ;Testuj prvni znak a je-li to pismeno,bude SUB #41 ;zapotrebi uvodni mezera RET Podprogram TESTOVANI SCROLL --------------------------- Tento podprogram se vola,kdykoli by mohlo dojit ke skrolovani.K tomu dochazi ve trech pripadech: a) Pri zpracovani ridiciho znaku CR (carriage return). b) Je-li pouzito AT v INPUT radku. c) Jestlize vypis presahne aktualni radek a bude zapotrebi pokracovat na dalsim radku. Na vstupu obsahuje registr B cislo radku,ktery ma byt testovan. 0C55 BIT 1,(IY+1) ;(FLAGS) Jestlize obsluhujes tiskarnu,vrat se RET NZ LD DE,#0DD9 ;Adresa CL-SET na zasobnik PUSH DE LD A,B ;Cislo radku do A BIT 0,(IY+2) ;(TV-FLAG) JP NZ,#0D02 ;Jedna-li se o INPUT..AT,skoc dopredu CP (IY+49) ;(DF-SZ) Je-li cislo radku nizsi nez DF-SZ JR C,#0C86 ;a je-li vyssi,vrat se pres CL-SET RET NZ BIT 4,(IY+2) ;(TV-FLAG) Pokud neobsluhujes autolisting, JR Z,#0C88 ;skoc dopredu LD E,(IY+45) ;(BREG) Vyzvedni citac radku,dekrementuj ho DEC E ;a skoc dopredu,je-li potreba skrolovat JR Z,#0CD2 ;Jinak otevri kanal "K",obnov zasobnik, LD A,#00 ;signalizuj konec autolistingu a vrat se CALL #1601 ;pres CL-SET LD SP,(#5C3F) RES 4,(IY+2) ;(TV-FLAG) RET 0C86 RST #08 ;Ohlas: Out of screen DEFB #04 0C88 DEC (IY+82) ;(SCR-CT) Nyni posud,je-li potreba vypsat JR NZ,#0CD2 ;sdeleni "scroll?".Dekrementuj skrolovaci citac LD A,#18 ;Neni-li nulovy,ke sdeleni nedojde.Citac je SUB B ;nastaven na novou hodnotu.Aktualni hodnoty LD (#5C8C),A ;ATTR-T a MASK-T LD HL,(#5C8F) ;jsou uschovany.Aktualni hodnota P-FLAG je PUSH HL ;uschovana LD A,(#5C91) PUSH AF LD A,#FD CALL #1601 ;Kanal "K" je otevren XOR A LD DE,#0CF8 ;Sdeleni "scroll?" ma cislo 0,baze CALL #0C0A ;Vypsani na obrazovku SET 5,(IY+2) ;(TV-FLAG) Signal: cistit dolni cast obrazovky LD HL,#5C3B ;po stisku klavesy.Toto je FLAGS SET 3,(HL) ;Signal: " L mod " RES 5,(HL) ;Signal:zatim zadna klavesa.Poznamka: Zde mel EXX ;byt uschovan take DE CALL #15D4 ;Vyzvedni kod stistene klavesy.Obnov registry EXX MONITOR ROM - ZX Spectrum - 30 - Subrutina barevnych polozek --------------------------- Toto je jedna z nejdulezitejsich subrutin.Je pouzivana kdykoliv je zapotrebi, aby permanentni barevne hodnoty byly zkopirovany do prechodnych systemovych promennych.Nejprve jsou zpracovany ATTR-T a MASK-T. 0D4D XOR A ;Registr A je vynulovan.Jsou vyzvednuty LD HL,(#5C8D) ;soucasne hodnoty ATTR-P a MASK-P.Jedna-li se BIT 0,(IY+2) ;(TV-FLAG) o hlavni cast obrazovky,skoc vpred JR Z,#0D5B LD H,A ;Jinak pouzij hodnotu #00 a hodnotu systemove LD L,(IY+14) ;(BORDCR) promenne BORDCR.Obe pak uloz 0D5B LD (#5C8F),HL ;na ATTR-T a MASK-T.Dalsi na rade je P-FLAG LD HL,#5C91 ;Toto je P-FLAG.Skoc dopredu,jestlize se JR NZ,#0D65 ;jedna o dolni cast obrazovky (A=0).Jinak vy- LD A,(HL) ;zvedni hodnotu P-FLAG a presun liche bity RRCA ;na mista sudych 0D65 XOR (HL) ;Pokracuj v kopirovani sudych bitu do registru AND #55 ;A a do systemove promenne P-FLAG XOR (HL) LD (HL),A RET Rutina CLS ---------- Hned na zacatku je smazan cely displej - "pixly" jsou vynulovany a atributove bajty jsou nastaveny na hodnotu,ktera odpovida systemove promenne ATTR-P. Potom bude smazana take nizsi cast obrazovky. 0D6B CALL #0DAF ;Hlavni cast displeje je smazana 0D6E LD HL,#5C3C RES 5,(HL) ;Signal: nemaz spodni cast po stisteni SET 0,(HL) ;tlacitka.Signal: spodni cast.Nastav barevne CALL #0D4D ;hodnoty ( ATTR-T podle BORDCR ) LD B,(IY+49) ;(DF-SZ) Dolni cast obrazovky je pak vycistena CALL #0E44 ;za pomoci techto hodnot LD HL,#5AC0 ;S vyjimkou atributovych bajtu pro radky 22 LD A,(#5C8D) ;a 23 jsou vsechny atributove bajty nastaveny DEC B ;podle hodnot v ATTR-P.Adresa 1.atributu pro JR #0D8E ;radek 22.Vyzvedni ATTR-P.Citac radku.Skoc 0D87 LD C,#20 ;dopredu do smycky.32 znaku na radek 0D89 DEC HL ;Vracej se zpet po radku a nastavuj atributove LD (HL),A ;bajty DEC C JR NZ,#0D89 0D8E DJNZ #0D87 ;Opakuj smycku.Velikost spodni casti obrazovky LD (IY+49),#02 ;(DF-SZ) bude nastavena.Jeji velikost-2 radky 0D94 LD A,#FD ;Nyni jeste zbyvaji dalsi "uklidove prace".Ka- CALL #1601 ;nal "K" bude otevren.Vyzvedni adresu soucas- LD HL,(#5C51) ;neho kanalu a jako vystupni adresu pouzij LD DE,#09F4 ;#09F4 AND A 0DA0 LD (HL),E ;(PRINT-OUT) a vstupni adresa #10AB (KEY-INPUT) INC HL LD (HL),D INC HL LD DE,#10A8 ;Prvni je ulozena vystupni adresa, CCF ;pak adresa vstupni.Protoze se jedna o dolni JR C,#0DA0 ;cast displeje,bude nejnizsi tiskovy radek LD BC,#1721 ;cislo 23.Vrat se pres CL-SET JR #0DD9 Subrutina MAZANI CELEHO DISPLEJE -------------------------------- Tato subrutina je volana: a) Prikazem CLS b) Hlavni provadeci rutinou c) Autolistingem 0DAF LD HL,#0000 ;Vynuluje se systemova promenna COORDS LD (#5C7D),HL RES 0,(IY+48) ;(FLAGS-2) Signal: obrazovka je cista.Proved CALL #0D94 ;"uklidove prace".Kanal "S" bude otevren LD A,#FE ;Permanentni barvy budou nastaveny CALL #1601 CALL #0D4D LD B,#18 ;24 radku displeje bude smazano CALL #0E44 LD HL,(#5C51) ;Zajisti,ze soucasna vystupni adresa je #09F4 LD DE,#09F4 LD (HL),E INC HL ;Nastav skrolovaci citac LD (HL),D ;Protoze se jedna o horni cast obrazovky,bude LD (IY+82),#01 ;(SCR-CT) nejvyssi tisknuty radek "radek 0" LD BC,#1821 ;Pokracuj do rutiny CL-SET MONITOR ROM - ZX Spectrum - 32 - Subrutina SMAZANI RADKU ----------------------- Tato subrutina vycisti spodni radky obrazovky,jejichz pocet je v registru B. 0E44 PUSH BC ;Cislo radku je uschovano CALL #0E9B ;V HL je prinesena pocatecni adresa radku.C je LD C,#08 ;znovu nastaveno jako citac 8"pixlovych" radku 0E4A PUSH BC ;Zde prichazi smycka,ktera vycisti vsechny PUSH HL ;"pixlove" radky.Uschovej cislo radku,citac LD A,B ;"pixlovych" radku a adresu.Uschovej c. radku 0E4D AND #07 ;v reg. A.Zjisti o kolik se jedna znaku nebo RRCA ;"B mod 8" radku a tuto hodnotu predej do re- RRCA ;gistru C (ktery bude obsahovat #00 pro novou RRCA ;tretinu) LD C,A LD A,B ;Vyzvedni c.r. a nastav BC tak,aby cislo ktere LD B,#00 ;obsahuje bylo o jednu mensi nez pocet znaku DEC C LD D,H ;Nastav DE tak,aby ukazoval na prvni znak LD E,L LD (HL),#00 ;Vycisti"pixlovy"bajt prvniho znaku,nastav INC DE ;DE na 2.znak a vycisti cely "pixlovy" radek LDIR LD DE,#0701 ;Pro kazdou tretinu displeje bude HL zvyseno ADD HL,DE ;o konstantu #0701.Dekrementuj citac radku DEC A AND #F8 LD B,A ;Predej cislo tretiny do registru B.Skoc zpet, JR NZ,#0E4D ;jsou-li zde jeste nejake tretiny k osetreni POP HL ;Zde se zjisti,jestli smycka probehla 8 krat INC H ;Priprav adresu pro kazdy "pixlovy" radek POP BC ;Vyzvedni citace.Dekrementuj citac"pixlovych" DEC C ;radku a skoc zpet,pokud neni konec JR NZ,#0E4A Nyni musi byt nastaveny atributove bajty.Hodnota ATTR-P bude pouzita pri obsluze hlavni casti displeje a hodnota BORDCR pri dolni casti displeje. CALL #0E88 ;Je nalezen pocet atributovych bajtu a adresa LD H,D ;prvniho z nich.HL ukazuje na prvni atributovy LD L,E ;bajt a DE na druhy INC DE LD A,(#5C8D) ;Vyzvedni hodnotu ATTR-P.Jedna-li se o hlavni BIT 0,(IY+2) ;(TV-FLAG) cast obrazovky skoc,jinak pouzij JR Z,#0E80 ;hodnotu BORDER LD A,(#5C48) 0E80 LD (HL),A ;Nastav atributovy bajt.Jeden bajt uz je hotov DEC BC LDIR ;A nyni bude jeho hodnota okopirovana do vsech POP BC ;ostatnich bajtu.Obnov si cislo radku LD C,#21 ;Nastav cislo sloupce na nejkrajnejsi levou RET ;pozici a vrat se Subrutina CL-ATTR ----------------- Tato subrutina ma dve rozdilne funkce: a) Vypocitat adresu atributoveho bajtu pro danou adresu v pameti a ulozit ji do DE.Povsimnete si,ze hodnoty na vstupu ukazuji na devaty"pixlovy"radek znaku. b) Pro dany pocet radku v registru B je v registrovem paru BC navracen pocet znaku pripadajicich na tyto radky. 0E88 LD A,H ;Vyzvedni vyssi bajt adresy a vynasob ho 32 RRCA RRCA RRCA DEC A ;Jdi zpatky na 8"pixlovy"radek OR #50 ;Adresuj oblast atributu LD H,A ;Vytvor novy vyssi bajt a celou adresu preved EX DE,HL ;do DE LD H,C ;V C je vzdy nula a v B je cislo radku LD L,B ADD HL,HL ADD HL,HL ADD HL,HL ADD HL,HL ADD HL,HL ;Hodnotu vynasobenou cislem 32 preved zpet LD B,H ;do registroveho paru BC LD C,L RET MONITOR ROM - ZX Spectrum - 34 - Pred vykonanim jakehokoliv tisku se musi provest tri testy. 0EFD CALL #1F54 ;Nebyl-li stlacen BREAK,skoc dopredu JR C,#0F0C LD A,#04 ;Signal:motor stop OUT (#FB),A EI ;Povol maskovane preruseni CALL #0EDF ;Vycisti bafr tiskarny a ohlas: RST #8 ;D - BREAK-CONT repeats DEFB #0C 0F0C IN A,(#FB) ;Zjisti v jakem stavu se nachazi tiskarna ADD A,A ;Proved okamzity navrat neni-li tiskarna RET M ;pripojena JR NC,#0EFD ;Pockej na jehlu LD C,#20 ;Konstanta pro 32 bajtu a vstup do smycky 0F14 LD E,(HL) ;Vyzvedni bajt a posun ukazatel INC HL LD B,#08 ;V jednom bajtu je 8 bitu 0F18 RL D ;Posun D doleva RL E ;Kazdy bit presun do CY RR D ;Posun D zpet a naber CY z E 0F1E IN A,(#FB) ;Znovu otestuj stav tiskarny a cekej na signal RRA JR NC,#0F1E LD A,D ;Nyni jdi dopredu a predej bit tiskarne OUT (#FB),H Poznamka: bit 2=0 signal: zapni motor, bit 1=1 signal: zpomal motor, bit 7=1 signal: vlastni tisk. DJNZ #0F18 ;Tiskni kazdy bit DEC C ;Dekrementuj citac bajtu JR NZ,#0F14 ;Skoc zpet,jestli jsou zde jeste nejake bajty RET ;Jinak se vrat Rutiny editoru -------------- Editor se vola pri dvou prilezitostech: a) Z hlavni provadeci rutiny tak,aby mohl uzivatel vlozit radek do programu. b) Z rutiny prikazu INPUT. Nejprve je ulozen chybovy zasobnik a potvrzena alternativni adresa. 0F2C HL,(#5C3D) ;Na zasobnik je ulozena aktualni adresa PUSH HL 0F30 LD HL,#107F ;Toto je adresa ED-ERRORu.Jakakoliv udalost, PUSH HL ;ktera by vedla ke spusteni rutiny chybovych LD (#5C3D),SP ;hlaseni zpusobi navrat do rutiny ED-ERROR Nyni se vstupuje do smycky ktera obslouzi kazdy uder na klavesu. 0F38 CALL #15D4 ;Z tohoto podprogramu se vrat po stisteni PUSH AF ;klavesy.Prechodne si uschovej CODE LD D,#00 ;Vynuluj registr D a vyzvedni si trvani klave- LD E,(IY-1) ;(PIP) soveho cvaknuti,jeho vysku a udelej PIP LD HL,#00C8 CALL #03B5 POP AF ;Obnov CODE a uloz na zasobnik adresu ED-LOOP LD HL,#0F38 PUSH HL ;Nyni analyzuj ziskane CODE CP #18 ;Akceptuj vsechny znakove kody,graficke kody JR NC,#0F81 ;a vsechny tokens CP #07 JR C,#0F81 ;Akceptuj i carku "," (tisk v druhe polovine CP #10 ;radku).Akceptuj vsechny editacni klavesy JR C,#0F92 ;Nyni jsou posouzeny klavesy od INK po TAB LD BC,#0002 ;INK a PAPER vyzaduji dve mista LD D,A ;Okopiruj kod do D CP #16 JR C,#0F6C ;Skoc dopredu s kodem INK a PAPER INC BC ;Zde budou posouzeny AT a TAB.Jsou pozadovana BIT 7,(IY+55) (FLAGX) 3 mista.Skoc dopredu neobsluhujes-li JP Z,#101E ;INPUT LINE... CALL #15D4 ;Vezmi druhy kod a dej ho do E LD E,A ;Nyni jsou vyzvednuty ostatni bajty pro ridici 0F6C CALL #15D4 ;znaky.Vyzvedni dalsi kod PUSH DE ;Uschovej oba kody LD HL,(#5E5B) ;Vyzvedni K-CUR RES 0,(IY+7) ;(MODE) Signal "K" mode CALL #1655 ;Vytvor prostor dvou nebo tri bajtu POP BC ;Obnov predchozi kod INC HL ;Ukazuj na prvni misto a vloz tam prvni kod LD (HL),B INC HL LD (HL),C ;Druhy kod bude prepsan jedna-li se o INK JR #0FBB ;a PAPER MONITOR ROM - ZX Spectrum - 36 - Editacni podprogram KURZOR DOLU ------------------------------- 0FF3 BIT 5,(IY+55) ;(FLAGX) V INPUT modu skoc dopredu JR NZ,#1001 LD HL,#5C49 ;Je nalezeno cislo dalsiho radku a je CALL #190F ;proveden novy automaticky LISTING JR #106E 1001 LD (IY+0),#10 ;(ERR-NR) Hlaseni "STOP in INPUT" JR #1024 Editacni podprogram KURZOR DOLEVA --------------------------------- 1007 CALL #1031 ;Kurzor je posunut JR #1011 Editacni podprogram KURZOR DOPRAVA ---------------------------------- 100C LD A,(HL) ;Testuj soucasny znak a je-li to ENTER, CP #0D ;vrat se RET Z INC HL ;Postav kurzor za znak 1011 LD (#5C5B),HL ;Nastav systemovou promennou K-CUR RET Subrutina DELETE v editu ------------------------ 1015 CALL #1031 ;Posun kurzor doleva LD BC,#0001 ;Zrus soucasny znak JP #19E8 Subrutina ED-IGNORE ------------------- 101E CALL #15D4 ;Dalsi 2 znaky z klavesove vstupni rutiny CALL #15D4 ;budou ignorovany Subrutina ENTER EDIT -------------------- 1024 POP HL ;Navratove adresy ED-LOOP a ED-ENTER jsou POP HL ;odhozeny 1026 POP HL ;Puvodni hodnota ERR-SP je obnovena LD (#5C3D),HL BIT 7,(IY+0) ;(ERR-NR) Jestlize nebyly zadne chyby,vrat se RET NZ LD SP,HL ;Jinak proved neprimy skok do chybove rutiny RET Subrutine ED-EDGE ----------------- Adresa je v registrovem paru HL a bude dekrementovana v pripade,ze kurzor jiz neni na zacatku radku.Je zabezpeceno,ze kurzor nebude stat mezi ridicimi znaky a jejich parametry. 1031 SCF ;DE obsahuje E-LINE (pri editaci), nebo WORKSP CALL #1195 ;(pri INPUTu).CY flag bude nastaven,ma-li byt SBC HL,DE ;kurzor na zacatku radku ADD HL,DE INC HL ;Oprava po odecteni POP BC ;Znic navratovou adresu a vrat se pres ED-LOOP, RET C ;byl-li nastaven CY PUSH BC ;Obnov navratovou adresu LD B,H ;Uloz soucasnou adresu kurzoru do BC LD C,L 103E LD H,D ;Tato smycka zajisti,ze ridici znaky nebudou LD L,E ;oddeleny od svych parametru.HL bude ukazovat INC HL ;na znak,ktery stoji za znakem,na ktery ukazuje LD A,(DE) ;DE.Vyzvedni kod znaku(adresa je v DE) AND #F0 CP #10 JR NZ,#1051 ;Nejedna-li se o znaky od INK az TAB,skoc INC HL ;Preskoc jeden znak a opet vyzvedni jeho kod LD A,(DE) SUB #17 ;CY flag je pri TAB vynulovan ADC A,#00 Poznamka: Touto instrukci jsou oddeleny AT a TAB, ale ty stejne nejsou v teto forme implementovany, takze to nevadi. JR NZ,#1051 ;Skoc,pokud se nejedna o AT a TAB,ktere,jsou-li INC HL ;pouzity,maji dva parametry 1051 AND A ;Priprav se na pravdive odecteni SBC HL,BC ;CY flag bude nastaven na nulu,kdyz posunovany ADD HL,BC ;ukazatel dosahne K-CUR EX DE,HL ;Pro dalsi mycku pouzij posunuty ukazatel,ale JR C,#103E ;skoc zpet,jestlize jsi prekrocil K-CUR RET ;Poznamka:Bude to ridici znak,ktery bude ;vymazan pouzitim DELETE MONITOR ROM - ZX Spectrum - 38 - 10E6 CP #0E RET C ;Zkontroluj dolni limit SUB #0D ;Sniz rozsah LD HL,#5C41 CP (HL) ;Byl zmenen? LD (HL),A ;Vloz kod noveho modu a skoc,kdyz bylo zmenen JR NZ,#10F4 LD (HL),#00 ;Jinak nastav "L" mod 10F4 SET 3,(IY+2) ;(TV-FLAG) Signal modu mohl byt zmenen.Nuluj CP A ;CY flag a vrat se RET 10FA LD B,A ;Nyni jsou manipulovany kody ridicich znaku AND #07 ;pro FLASH,BRIGHT a INVERSE.Uschovej kod.Nastav LD C,A ;registr C na #00 az #07.Registr A nyni obsa- LD A,#10 ;huje kod pro INK.Ale nebyli-li kod shiftovan, BIT 3,B ;nastav registr A na hodnotu PAPER JR NZ,#1105 INC A ;Parametr je nyni uschovan v promenne K-DATA 1105 LD (IY-45),C ;a kanalova adresa je zmenena z KEY-INPUT LD DE,#110D ;(K-DATA) na KEY-NEXT.Uloz parametr JR #1113 Poznamka: Pri prvnim pruchodu pres KEY-INPUT je v registru A vracena hodnota kontrolniho kodu.Pri dalsim vstupu pres KEY-NEXT se vraci parametr. 110D LD A,(#5C0D) ;Vyzvedni parametr LD DE,#10A8 ;Nyni nastav vstupni adresu na hodnotu prvni 1113 LD HL,(#5C40) ;kanalove adresy.Vyzvedni kanalovou adresu INC HL INC HL ;Nyni nastav vstupni adresu LD (HL),E INC HL LD (HL),D 111B SCF ;Konecny vystup s pozadovanym kodem v registru RET ;A.Signalizuj,ze kod byl nalezen a vrat se Program pro okopirovani dolni casti obrazovky --------------------------------------------- Tato rutina je volana kdykoliv ma byt radek z editacni oblasti nebo z oblasti INPUTu vytisknut na obrazovku. 111D CALL #0D4D ;Pouzij permanentni barvy RES 3,(IY+2) ;(TV-FLAG) Signal:mod nezmenen RES 5,(IY+2) ;Signal:necistit dolni cast obrazovky LD HL,(#5C8A) PUSH HL ;Uschovej soucasnou hodnotu S-POSNL LD HL,(#5C3D) PUSH HL ;Uschovej soucasnou hodnotu ERR-SP LD HL,#1167 PUSH HL ;Uschovej tuto hodnotu na zasobnik a tim se LD (#5C3D),SP ;tato hodnota stane vstupnim bodem pri chybe LD HL,(#5C82) PUSH HL ;Uloz na zasobnik hodnotu ECHO-E.HL bude uka- SCF ;zovat na zacatek prostoru a DE na jeho konec CALL #1195 EX DE,HL ;Zamen ukazatele CALL #187D ;Nyni vytiskni radek EX DE,HL ;Opet zamen ukazatele a vytiskni kurzor CALL #18E1 LD HL,(#5C8A) ;Vyzvedni soucasnou hodnotu S-POSNL a zamen ji EX (SP),HL ;s ECHO-E a predej ji do DE EX DE,HL CALL #0D4D ;Vyzvedni permanentni barvy Zbytek radku, ktery byl prave obsluhovan je nyni vyplnen mezerami,tistenymi v barvach permanentniho PAPERu. 1150 LD A,(#5C8B) ;Vyzvedni cislo soucasneho radku a odecti SUB D ;cislo stareho radku JR C,#117C ;Skoc dopredu,neni-li treba doplnit mezery JR NZ,#115E ;Skoc dopredu,jestlize se nenachazis na stej- LD A,E ;nem radku.Vyzvedni stare cislo sloupce a o- SUB (IY+80) ;(S-POSNL-lo) decti ho od noveho cisla sloupce JR NC,#117C ;Skoc,kdyz neni zapotrebi mezerovat 115E LD A,#20 ;Kod mezery PUSH DE ;Uschovej stare hodnoty CALL #09F4 ;Vytiskni mezeru POP DE ;Vyzvedni stare hodnoty JR #1150 ;Skoc zpatky MONITOR ROM - ZX Spectrum - 40 - 11E2 AND A ;Priprav se pro pravdivy odecet SBC HL,DE ADD HL,DE ;CY flag=0 pri dosazeni konce.Posun ukazatel INC HL JR NC,#11EF ;Skoc,jsi-li na konci.Ale je-li zde nula,znaci DEC (HL) ;to ze pamet je vadna.Pouzij soucasnou hodnotu JR Z,#11EF ;HL jako nejvyssi moznou adresu DEC (HL) ;#01 se meni na #00 JR Z,#11E2 ;Pruchod dalsim testem,dokud nedoslo k selhani 11EF DEC HL ;HL ukazuje na posledni provozuschopne misto Nyni budou obnoveny puvodne uschovane systemove promenne (coz nema zadny smysl jestlize program bezi od STARTu). EXX ;Prepni registry,restartuj P-RAMT,RASP/PIP,UDG LD (#5CB4),BC ;a znovu prepni registry LD (#5C38),DE LD (#5C7B),HL EXX INC B ;Testuj signal START/NEW JR Z,#1219 ;Skoc,prichazis-li z rutiny NEW Prepis systemovych promennych,jestlize prichazi od STARTu a inicializace oblasti UDG. LD (#5CB4),HL ;Toto je max.fyzicka RAM LD DE,#3EAF ;Posledni bajt pismene "U" ve znakovem souboru LD BC,#00A8 ;Toto je pocet bajtu pro 21 pismen EX DE,HL ;Prepni ukazatele LDDR ;Okopiruj znakove formy pismen "A" az "U" EX DE,HL ;Prepni zpet ukazatele INC HL ;Ukazuj na prvni bajt a nastav UDG LD (#5C7B),HL DEC HL ;Jedno misto dolu LD BC,#0040 LD (#5C38),BC Nastav systemove promenne RASP a PIP Zbytek teto rutiny je spolecny jak pro START,tak pro NEW. 1219 LD (#5CB2),HL ;Nastav RAMTOP a systemovou promennou CHARS LD HL,#3C00 LD (#5C36),HL LD HL,(#5CB2) ;Nyni nastav zasobnik.Jeho nejvyssi misto bude LD (HL),#3E ;obsahovat #3E.Dalsi misto je ponechano aby DEC HL ;obsahovalo nulu.Tato dve mista reprezentuji LD SP,HL ;posledni ulozku DEC HL DEC HL ;Nyni prekroc dve mista,abys ziskal spravnou LD (#5C3D),HL ;hodnotu pro ERR-SP IM I ;Takto pokracuje iniciacni rutina.Prerusovaci LD IY,#5C3A ;mod IMI.IY obsahuje vzdy hodnotu ERR-NR.Mas- EI kovane preruseni bude povoleno,hodiny nastaveny LD HL,#5CB6 ;a kazdou 1/50 sec.otestovana klavesnice.Toto LD (#5C4F),HL ;je bazova adresa oblasti kanal.infor. LD DE,#15AF ;Pocatecni kanalova data jsou presunuta LD BC,#0015 ;z tabulky (na adrese #15AF) do oblasti EX DE,HL ;kanal.inform. LDIR EX DE,HL DEC HL ;Systemova promenna DATADD je nastavena tak, LD (#5C57),HL ;aby ukazovala na posledni misto oblasti INC HL ;kanalovych dat a promenne PROG a VARS LD (#5C53),HL ;na misto za ni LD (#5C4B),HL LD (HL),#80 ;Uloz koncovy znak INC HL ;Jedno misto dopredu pro spravnou hodnotu LD (#5C59),HL ;E-LINE LD (HL),#0D ;Zajisti,aby v editacni oblasti byl pouze znak INC HL ;CR.Nyni vloz dalsi koncovy bajt a pohni se LD (HL),#80 ;zase dopredu,abys ziskal hodnoty pro WORKS INC HL ;STKBOT a STKEND LD (#5C61),HL LD (#5C63),HL LD (#5C65),HL LD A,#38 ;Inicializuj systemove promenne pro barvy na: LD (#5C8D),A ;BORDER 7,INK 0,PAPER 7,BRIGHT 0 a FLASH 0 LD (#5C8F),A LD (#5C48),A LD HL,#0523 ;Hodnoty pro syst.promenne REPDEL a REPPER LD (#5C09),HL DEC (IY-58) ;Uloz na KSTATE-0 hodnotu #FF DEC (IY-54) ;Uloz na KSTATE-4 hodnotu #FF LD HL,#15C6 ;Prenes data z tabulky proudovych dat do infor- LD DE,#5C10 ;macni oblasti proudovych dat LD BC,#000E LDIR MONITOR ROM - ZX Spectrum - 42 - 133C CALL #15EF ;Vytiskni sdeleni a vloz mezeru LD A,#20 RST #10 LD A,B ;Vyzvedni znovu hodnotu sdeleni a pouzij ji LD DE,#1391 ;k identifikaci sdeleni CALL #0C0A,PO-MSG XOR A LD DE,#1536 CALL #0C0A ;Vytiskni sdeleni a udelej za nim carku LD BC,(#5C45) ;a mezeru.Vyzvedni cislo aktualniho radku CALL #1A1B ;a take je vytiskni LD A,#3A RST #10 ;Dale vytiskni ":" LD C,(IY+13) ;(SUBPPC) Vyzvedni cislo aktualniho prikazu LD B,#00 ;do registru BC a vytiskni ho CALL #1A1B CALL #1097 ;Vycisti editacni oblast LD A,(#5C3A) ;Vyzvedni opet cislo chyby a inkrementuj ho INC A ;jako obvykle.Skoc dopredu,nedoslo-li k chybe JR Z,#1386 CP #09 ;Skoc,byl-li program zastaven prikazem STOP JR Z,#1373 ;nebo BREAK CP #15 JR NZ,#1376 1373 INC (IY+13) ;Jinak bude promenna SUBPPC nezmenena 1376 LD BC,#0003 ;Systemove promenne OLDPPC a OSPPC musi byt LD DE,#5C70 ;nyni upraveny tak,aby ukazovaly na cislo LD HL,#5C44 ;prikazu ve spravnem radku,kde se bude pokra- BIT 7,(HL) ;covat.Hodnoty ktere budou pouzity,budou nale- JR Z,#1384 ;zeny v PPC a SUBPPC, pokud ovsem NS-PPC neu- ADD HL,BC ;kazuje,ze k BREAKu doslo pri skoku (napr. pri 1384 LDDR ;prikazu GOTO) 1386 LD (IY+10),#FF ;NSPPC je nastavena,aby ukazovala "zadny skok" RES 3,(IY+1) ;(FLAGS) Je nastaven "K" mod a je proveden JP #12AC ;odskok,ale tak aby nebyl proveden programovy ;listing,pokud to neni treba Chybova hlaseni --------------- Posledni znak kazdeho hlaseni je "invertovan" (+#80). 1391 DEFB #80 - zde se prekroci pocateci bajt 1392 REPORT 0 - 'OK' 1394 REPORT 1 - 'NEXT without FOR' 13A4 REPORT 2 - 'Variable not found' 13B6 REPORT 3 - 'Subscript wrong' 13C6 REPORT 4 - 'Out of memory' 13D2 REPORT 5 - 'Out of screen' 13DF REPORT 6 - 'Number too big' 13ED REPORT 7 - 'RETURN without GOSUB' 1401 REPORT 8 - 'End of file' 140C REPORT 9 - 'STOP statement' 141A REPORT A - 'Invalid argument' 142A REPORT B - 'Integer out of range' 143E REPORT C - 'Nonsense in BASIC' 144F REPORT D - 'BREAK-CONT repeats' 1463 REPORT E - 'Out of DATA' 146E REPORT F - 'Invalid file name' 147F REPORT G - 'No room for line' 148F REPORT H - 'STOP in INPUT' 149C REPORT I - 'FOR without NEXT' 14AC REPORT J - 'Invalid I/O device' 14BE REPORT K - 'Invalid colour' 14CC REPORT L - 'BREAK into program' 14DE REPORT M - 'RAMTOP no good' 14EC REPORT N - 'Statement lost' 14FA REPORT O - 'Invalid stream' 1508 REPORT P - 'FN without DEF' 1516 REPORT Q - 'Parameter error' 1525 REPORT R - 'Tape loading error' Jsou zde take jeste nasledujici dve sdeleni. 1537 DEFB ', ' ;'carka' a 'mezera' 1539 DEFB #0C,' 1982 Sinclair Research Ltd.' 1555 LD A,#10 ;"G" ma kod "10+07+30" LD BC,#0000 ;Nuluj registry B a C JP #1313 ;G - No room for line bude ohlaseno po odskoku MONITOR ROM - ZX Spectrum - 44 - Pocatecni proudova data ----------------------- Na pocatku existuje sedm proudu: od #FD do #03. 15C6 DEFB #10,#00 ;proud #FD smeruje ke kanalu "K" 15C8 DEFB #06,#00 ;proud #FE smeruje ke kanalu "S" 15CA DEFB #0B,#00 ;proud #FF smeruje ke kanalu "R" 15CC DEFB #01,#00 ;proud #00 smeruje ke kanalu "K" 15CE DEFB #01,#00 ;proud #01 smeruje ke kanalu "K" 15D0 DEFB #06,#00 ;proud #02 smeruje ke kanalu "S" 15D2 DEFB #10,#00 ;proud #03 smeruje ke kanalu "P" Subrutina CEKEJ NA KLAVESU -------------------------- Tento podprogram je ridici podprogram pro volani aktualnich inputovych podprogramu. 15D4 BIT 5,(IY+2) ;(TV-FLAG) Neni-li treba cistit dolni cast JR NZ,#15DE ;obrazovky,skoc SET 3,(IY+2) ;Jinak signal:posuzuj mod jako kdyby se zmenil 15DE CALL #15E6 ;Volej vstupni podprogram neprimo pres INPUT-AD RET C ;Vrat se s akceptovatelnymi kody JR Z,#15DE ;Skoc,nebyla-li stistena zadna klavesa Jsou-li CY i Z nastaveny na nulu,znamena to,ze nebylo stisteno zadne tlacitko a doslo k nejake chybe. 15E4 RST #08 ;Ohlas: 8 - End of file DEFB #07 Subrutina INPUT-AD ------------------ Registry jsou uschovany a HL ukazuje na adresu vstupni rutiny. 15E6 EXX ;Uschovej registry PUSH HL LD HL,(#5C51) ;Vyzvedni bazovou adresu aktualni kanalove INC HL ;informace.Prekroc vystupni adresu a skoc INC HL JR #15F7 Hlavni tiskovy podprogram ------------------------- Tento podprogram je volan bud s absolutni hodnotou nebo radnym znakovym kodem v registru A. 15EF LD E,#30 ;Hodnota v registru A zvysena o #30 ADD A,E 15F2 EXX ;Uschovej registry PUSH HL ;Vyzvedni bazovou adr.aktualni kanal.informace LD HL,(#5C51) ;Nyni volej skutecny podprogram.HL ukazuje ; 15F7 LD E,(HL) ;na adresu vstupni nebo vystupni rutiny.Vyzved- INC HL ;ni nizsi bajt LD D,(HL) ;Vyzvedni vyssi bajt EX DE,HL ;Prenes aresu do HL CALL #162C ;Zavolej pozadovanou rutinu a obnov registry POP HL EXX ;Odtud bude proveden navrat,pokud cestou RET ;nedoslo k chybe Subrutina CHAN-OPEN ------------------- Do teto subrutiny vstupuje v registru A platne cislo proudu (normalne #FD az #03) a v zavislosti na tomto cisle je otevren prislusny kanal. 1601 ADD A,A ;Hodnota v A je zdvojena a pak zvetsena o #16 ADD A,#16 LD L,A ;Vysledek je predan do L LD H,#5C ;Adresa #5C16 je bazovou adresou pro proud #00 LD E,(HL) ;Vyzvedni prvni a druhy bajt pozadovanych INC HL ;kanalovych dat LD D,(HL) LD A,D OR E JR NZ,#1610 ;Skoc,nejsou-li oba bajty nulove,jinak ohlas: 160E RST #08 ;O - Invalid stream DEFB #17 S pouzitim proudovych dat nyni najdi bazovou adresu kanalove informace,ktera souvisi s danym kanalem. 1610 DEC DE ;Sniz proudova data.Toto je bazova adresa LD HL,(#5C4F) ;informacni oblasti kanalovych dat v niz bude ADD HL,DE ;nyni nalezena pozadovana adresa MONITOR ROM - ZX Spectrum - 46 - 166B LD E,(HL) ;Vyzvedni dva bajty soucasneho ukazatele INC HL LD D,(HL) EX (SP),HL ;Zamen systemove promenne s adresami "pozice" AND A SBC HL,DE ;CY flag bude nastaven,jestlize ma byt hodnota ADD HL,DE ;teto promenne pozmenena EX (SP),HL ;Obnov "pozici" JR NC,#167F ;Skoc dopredu,nema-li se tento ukazatel menit PUSH DE ;Jinak uschovej starou hodnotu.Nyni k ni EX DE,HL ;pricti hodnotu v BC a vloz tuto novou hodnotu ADD HL,BC ;do systemove promenne EX DE,HL LD (HL),D ;Nejprve vyssi bajt,pak nizsi DEC HL LD (HL),E INC HL ;Ukazuj zase na prvni bajt POP DE ;Vyzvedni starou hodnotu 167F INC HL ;Ukazuj na dalsi systemovou promennou DEC A ;a jestlize nebylo posouzeno vsech 14 JR NZ,#166B ;systemovych promennych vrat se zpet do smycky EX DE,HL ;Nalezeni velikosti bloku,ktery se bude presu- POP DE ;novat.Stara hodnota STKEND jde do HL,hodnoty POP AF ;ostatnich registru jsou obnoveny AND A ;Nyni nalezni rozdil mezi starou hodnotou SBC HL,DE ;STKEND a "pozici".Preved vysledek do BC LD B,H LD C,L INC BC ;a zvys o 1 pro bajt navic ADD HL,DE ;Uprav zpet na starou hodnotu STKEND a preved EX DE,HL ;ji do DE RET Rutina vyzvednuti cisla radku ----------------------------- Na vstupu ukazuje HL na misto,ktere ma byt posouzeno.Jestlize se na tomto miste nachazi bajt,jehoz hodnota je vyssi bajt cisla radku,vraci se toto cislo v DE.V opacnem pripade se stejnym zpusobem otestuje lokace adresovana DE a jestlize ani tato nesplnuje podminku,vraci se cislo radku 0. 168F DEFB #00 ;Cislo radku 0 DEFB #00 1691 EX DE,HL ;Posuzuj druhy ukazatel LD DE,#168F ;Pouzij radek cislo 0 1695 LD A,(HL) ;Zde je obvykly vstupni bod.Vyzvedni vyssi AND #C0 ;bajt a testuj JR NZ,#1691 ;Skoc,je-li nevhodny LD D,(HL) ;Vyzvedni vyssi bajt INC HL LD E,(HL) ;Vyzvedni nizsi bajt RET Podprogram "REZERVUJ MISTO" --------------------------- Tento podprogram je vetsinou volan pouzitim RST #30,BC-SPACES. V tomto vstupnim bode se vsak predpoklada,ze na zasobniku je ulozen WORKSP a pod nim pocet mist,ktera maji byt rezervovana. Podprogram vytvari prostor mezi pracovnim prostorem a zasobnikem kalkulatoru. 169E LD HL,(#5C63) ;Vyzvedni aktualni hodnotu STKBOT a dekrementuj DEC HL ;ji k ziskani posledni lokace pracov. prostoru CALL #1655 ;Vytvor BC mist INC HL ;Ukazuj na druhy bajt noveho prostoru INC HL POP BC ;Vyzvedni starou hodnotu WORKSP a obnov ji LD (#5C61),BC POP BC ;Restauruj BC,tedy pocet mist.Zamen ukazatele EX DE,HL INC HL ;HL ukazuje na 1.z premistenych bajtu RET Poznamka: Lze take tvrdit,ze po navratu z rutiny ukazuje DE na prvni bajt "navic" a HL na posledni bajt "navic",kdyz tyto bajty navic byly pridany za puvodni misto (HL)+1. Podprogram SET-MIN ------------------ Tento podprogram nastavuje editacni oblast a jejich minimalni hodnoty,tedy je vlastne "cisti". 16B0 LD HL,(#5C59) ;Vyzvedni E-LINE LD (HL),#0D ;Editacni oblast bude obsahovat pouze znak CR LD (#5C5B),HL ;nasledovany koncovym bajtem INC HL LD (HL),#80 INC HL LD (#5C61),HL ;Uloz HL do WORKSP MONITOR ROM - ZX Spectrum - 48 - Podprogram ZAVRI PROUD ---------------------- 171C POP HL ;Vyzvedni ukazatel oblasti kanalovych dat RET Podprogram PROUDOVA DATA ------------------------ Podprogram vraci proudova data pro dany proud v registrovem paru DE. 171E CALL #1E94 ;Cislo proudu jde ze zasobniku kalkulatoru CP #10 ;do registru A.Jestlize je cislo proudu JR C,#1727 ;vetsi nez #0F,vyvola se chybove hlaseni 1725 RST #08 ;Ohlas: Invalid stream DEFB #17 1727 ADD A,#03 ;Zde se pokracuje s platnymi cisly proudu RLCA ;Uprava na rozsah #03 az #12.Uprava na rozsah LD HL,#5C10 ;#06 az #24.Bazova adresa oblasti proudovych LD C,A ;dat.Kod proudu jde do BC LD B,#00 ADD HL,BC ;Vypocet adresy v oblasti proudovych dat LD C,(HL) ;a preneseni nalezenych dat do BC INC HL LD B,(HL) DEC HL ;Ukazatel zpet na prvni bajt dat RET Podprogram prikazu OPEN# ------------------------ Tento prikaz poskytuje uzivateli moznost otevirat proudy.Musi byt udan kod kanalu a to "K","k","S","s","P" nebo "p".Povsimnete si,ze neni snaha pridelit proudum #00 az #03 jejich inicializacni hodnoty. 1736 RST #28 ;Pouzij kalkulator DEFB #01 ;zamena Zamena cisla proudu a kod kanalu DEFB #38 ;konec CALL #171E ;Vyzvedni data pro proud LD A,B ;Jsou-li datove bajty nulove, znamena to, OR C ;ze proud byl uzavren a provede se skok JR Z,#1756 EX DE,HL ;Uschovej DE LD HL,(#5C4F) ;Vyzvedni bazovou adresu oblasti kanalovych ADD HL,BC ;informaci a nalezni kod kanalu,ktery je INC HL ;pripojen k prave oteviranemu proudu INC HL INC HL LD A,(HL) EX DE,HL ;Obnov DE CP #4B ;Ziskany kod musi byt "K",nebo "S",nebo "P", JR Z,#1756 ;jinak skok na chybove hlaseni CP #53 JR Z,#1756 CP #50 JR NZ,#1725 1756 CALL #175D ;Vyzvedni prislusna data do DE.Vloz tyto data LD (HL),E ;do dvou bajtu v oblasti proudovych dat INC HL LD (HL),D RET Podprogram OPEN-2 ----------------- Rutina nalezne prislusne proudove data bajty pro kanal,ktery je pripojen k prave oteviranemu proudu. 175D PUSH HL ;Uschovej HL CALL #2BF1 ;Vyzvedni parametry kodu kanalu LD A,B ;Jestize ma vyraz nulovou hodnotu, OR C ;vyvolej chybove hlaseni JR NZ,#1767 1765 RST #08 ;Ohlas: Invalid file name DEFB #0E 1767 PUSH BC ;Pokracuj zde pokud se nevyskytla zadna chyba LD A,(DE) ;Je uschovana delka vyrazu.Vyzvedni prvni znak AND #DF ;Preved mala pismena na velka a prenes kod LD C,A ;do C.Bazova adresa tabulky otevirani proudu LD HL,#177A CALL #16DC ;Vyhledej pozadovany doplnek JR NC,#1765 ;Skoc zpet,nebyl-li nalezen.Preved doplnek LD C,(HL) ;do BC LD B,#00 ADD HL,BC ;HL nyni ukazuje na zacatek prislusne rutiny POP BC ;Vyzvedni delku vyrazu a skoc do prislusne JP (HL) ;rutiny MONITOR ROM - ZX Spectrum - 50 - 17E1 LD (#5C6C),HL ;Nyni muze dojit k automatickemu listingu.Pro 17E4 LD HL,(#5C6C) ;pripad,ze E-PPC je mensi nez S-TOP vyzvedni CALL #196E ;cislo nejvyssiho radku a jeho adresu JR Z,#17ED ;Nebyla-li nalezena,pouzij adresu v DE EX DE,HL 17ED CALL #1833 ;Vypis listingu.Do tohoto mista se provede RES 4,(IY+2) ;(TV-FLAG) navrat,nebylo-li zapotrebi skrolingu RET ;k vypsani aktualniho radku Vstupni bod LLIST ----------------- Je nutne otevreni kanalu pro tiskarnu. 17F5 LD A,#03 ;Proud #03 a skok dopredu JR #17FB Vstupni bod LIST ---------------- Je nutne otevreni kanalu pro obrazovku. 17F9 LD A,#02 ;Proud #02 a signal: Obycejny listing v hlavni 17FB LD (IY+2),#00 ;(TV-FLAG) casti obrazovky CALL #2530 ;Pri kontrole syntaxe kanal neotvirej CALL NZ,#1601 RST #18 ;Vyzvedni aktualni znak do A a podivej se, CALL #2070 ;je-li nutne menit proud.Skoc,kdyz proud nebyl JR C,#181F ;zmenen RST #18 ;Vyzvedni aktualni znak do A.Skoc,je-li to CP #3B ;strednik JR Z,#1814 CP #2C ;Neskakej,je-li to carka JR NZ,#181A 1814 RST #20 ;Vyzvedni dalsi znak a zvys CH-ADD.Musi nasle- CALL #1C82 ;dovat ciselny vyraz (napriklad LIST #5.20) JR #1822 ;Skoc s timto dopredu 181A CALL #1CE6 ;Pouzij nulu a skoc dopredu JR #1822 181F CALL #1CDE ;Vyzvedni jakykoliv radek 1822 CALL #1BEE ;V pripade kontroly syntaxe prejdi na dalsi CALL #1E99 ;prikaz.Cislo radku do BC LD A,B ;Vyssi bajt do A AND #3F ;Limitace vyssiho bajtu na spravnou velikost LD H,A ;a prevedeni celeho cisla radku do HL LD L,C LD (#5C49),HL ;Nastav E-PPC.Najdi adresu tohoto nebo CALL #196E ;nejblizsiho existujiciho radku 1833 LD E,#01 ;Signal: pred aktivnim radkem 1835 CALL #1855 ;Vstup do ridici smycky pro vypis serie radku RST #10 ;Vypis cely basicky radek."Navrat voziku" BIT 4,(IY+2) ;(TV-FLAG) Pokud neprovadis automaticky JR Z,#1835 ;listing,skoc zpet LD A,(#5C6B) ;Zbyva-li jeste misto v hlavni casti SUB (IY+79) ;(S-POSN-hi) obrazovky,skoc JR NZ,#1835 XOR E ;Jestlize obrazovka je uz plna a aktualni RET Z ;radek byl vytisten,vrat se PUSH HL ;Nicmene pokud aktualni radek vytisten nebyl, PUSH DE ;je potreba zvysit S-TOP a tisknout dalsi LD HL,#5C6C ;radek pri pouziti skrolovani CALL #190F POP DE POP HL JR #1835 ;Skok zpet do smycky Vypsani celeho basickeho radku ------------------------------ Na vstupu ukazuje HL na zacatek radku,tedy na vyssi bajt cisla radku.Nez bude cislo vypsano,zjisti se,zdali radek stoji pred a nebo za aktualnim radkem. 1855 LD BC,(#5C49) ;Vyzvedni cislo aktualniho radku a porovnavej CALL #1980 LD D,#3E ;Kurzor aktualniho radku do D.Skoc dopredu,ti- JR Z,#1865 ;sknes-li aktualni radek LD DE,#0000 ;Nuly do DE a E na #01,jestlize radek je stoji RL E ;pred aktualnim radkem a E na #00,stoji-li za ;CY flag prichazi z CP-LINES 1865 LD (IY+45),E ;(BREG) Uschovej znacku LD A,(HL) ;Vyzvedni vyssi bajt cisla radku a je-li CP #40 ;listing u konce,zahod navratovou adresu POP BC RET NC ;a proved plny navrat PUSH BC ;Vrat navratovou adresu a tiskni cislo radku CALL #1A28 ;vcetne uvodnich mezer INC HL ;Posun ukazatel na prvni prikazovy kod radku INC HL INC HL MONITOR ROM - ZX Spectrum - 52 - JR Z,#18F3 ;Skoc dopredu,pokud se nejedna o Extended nebo ADD A,#43 ;Graphics mode.Pricti prislusny doplnek JR #1909 ;pro "E" nebo "G".Skok na tisk 18F3 LD HL,#5C3B RES 3,(HL) ;Signal: "K" mod LD A,#4B ;Znak K BIT 2,(HL) ;Ma-li byt tisk v modu "K",skok na tisk JR Z,#1909 SET 3,(HL) ;Signal: "L" mod INC A ;Vytvor zank L BIT 3,(IY+48) ;(FLAGS2) Pokud nejsi v modu "C",skoc JR Z,#1909 LD A,#43 ;Znak C 1909 PUSH DE ;Uschovej DE a tiskni kurzor CALL #18C1 POP DE ;Obnov DE a vrat se RET Podprogram vyzvednuti cisla radku --------------------------------- Na vstupu adresuje HL bud systemovou promennou S-TOP nebo E-PPC.Po navratu obsahuje S-TOP nebo E-PPC cislo nasledujiciho radku. 190F LD E,(HL) ;Vyzvedni cislo radku z dane systemove promenne INC HL LD D,(HL) PUSH HL ;Uschovej ukazatel EX DE,HL ;Nalezena hodnota jde do HL a je inkrementovana INC HL CALL #196E ;Je nalezena adresa tohoto,nebo nasledujiciho CALL #1695 ;radku a jeho cislo POP HL ;Obnoveni ukazatele na systemovou promennou Tento vstupni bod je pouzivan editorem. 191C BIT 5,(IY+55) ;(FLAGX) Pokud jsi v modu INPUT,vrat se RET NZ LD (HL),D ;Uloz cislo radku na pozadovanou systemovou DEC HL ;promennou a vrat se LD (HL),E RET Tisk znaku basickeho radku -------------------------- Opakovanym volanim tohoto podprogramu je zajisten tisk vsech znaku a tokens v basickem radku.Vstupni bod OUT-SP-NO se pouziva pro tisk cisel radku,ktera vyzaduji uvodni mezery. 1925 LD A,E ;A obsahuje #20 pro mezeru a #FF pro "nemezeru" AND A ;Testuj tuto hodnotu a vrat se,nema-li byt RET M ;mezera JR #1937 ;Skoc na vytisknuti mezery 192A XOR A ;Vynuluj A V HL je cislo radku a v BC je hodnota pro opakovane odcitani(-1000,-100,-10 ). 192B ADD HL,BC ;Pokusne odecteni INC A ;Pocitej kazdy pokus JR C,#192B ;Skoky zpet do vycerpani SBC HL,BC ;Vrat posledni odecet a nepocitej ho DEC A ;Jestlize nebylo mozne provest odecitani,skoc JR Z,#1925 ;zpet na pripadny tisk mezery.Jinak vytiskni JP #15EF ;cislici Vstupni bod OUT-CHAR se pouziva pro tisk znaku,tokens a ridicich znaku. 1937 CALL #2D1B ;CY=0,jednalo-li se o cislici JR NC,#196C ;Skoc dopredu a tiskni cislici CP #21 ;Take vsechny ridici znaky a mezeru JR C,#196C RES 2,(IY+1) ;(FLAGS) Signal: tisk v "K" modu CP #CB ;Jedna-li se o token THEN,skoc JR Z,#196C CP #3A ;Pokud se nejedna o dvojtecku,skoc JR NZ,#195A BIT 5,(IY+55) ;(FLAGX) Jsi-li v modu INPUT,skoc dopredu JR NZ,#1968 ;a tiskni dvojtecku BIT 2,(IY+48) ;(FLAGS2) Pokud dvojtecka neni v uvozovkach, JR Z,#196C ;skoc(jedna se o oddelovac prikazu) JR #1968 ;Skoc na tisk dvojtecky,ktera byla v uvozovkach 195A CP #22 ;Akceptuj vsechny znaky,krome uvozovek JR NZ,#1968 PUSH AF ;Uschovej kod znaku LD A,(#5C6A) ;Flipuj bit 2 systemove promenne FLAGS2 XOR #04 LD (#5C6A),A POP AF ;Obnov kod znaku MONITOR ROM - ZX Spectrum - 54 - Podprogram NEXT-ONE ------------------- Tento podprogram umi nalezt dalsi radek v programu,nebo dalsi promennou v oblasti VARS. 19B8 PUSH HL ;Uschovej adresu aktualniho radku nebo promenne LD A,(HL) ;Vyzvedni prvni bajt.Jestlize hledas radek,skoc CP #40 JR C,#19D5 BIT 5,A ;Jedna-li se o retezec nebo pole,skoc JR Z,#19D6 ADD A,A ;Jde-li se o jednopismennou ciselnou promennou, JP M,#19C7 ;skoc CCF ;Ciselne promenne s dlouhymi nazvy 19C7 LD BC,#0005 ;Ciselna promenna zabira pet mist,ale ridici JR NC,#19CE ;promenna FOR-NEXT potrebuje 18 mist LD C,#12 19CE RLA ;CY bude 0 pro promenne s dlouhymi nazvy,dokud INC HL ;nebude nalezen posledni znak LD A,(HL) ;Vyzvedni dalsi znak.Kdyz nejsi na konci,skoc JR NC,19CE JR #19DB ;Skoc (BC=#0005 nebo #0012) 19D5 INC HL ;Krok za nizsi bajt cisla radku.Nyni ukazuj 19D6 INC HL ;na nizsi bajt delky.Vyzvedni delku do BC LD C,(HL) INC HL LD B,(HL) INC HL ;"Dalsi" adresa je nalezena ve vsech pripadech 19DB ADD HL,BC ;Ukazuj na 1.bajt dalsiho radku nebo promenne POP DE ;Vyzvedni adresu predchoziho a pokracuj Podprogram DIFERENCE -------------------- V registru BC se vraci delka mezi dvema ukazateli.Ukazatele se vraci zamenene. 19DD AND A ;Priprava pravdiveho odecitani SBC HL,DE LD B,H ;Nalezenou delku predej do BC a obnov ukazatel LD C,L ADD HL,DE EX DE,HL ;Zamen ukazatele RET Podprogram RECLAIMING --------------------- Vstupni bod RECLAIM-1 se pouziva v pripade,kdy DE ukazuje na prvni misto,ktere ma byt "zruseno" a HL ukazuje na prvni misto,ktere ma byt ponechano.Vstupni bod RECLAIM-2 se pouziva v pripade,kdy HL ukazuje na prvni misto,ktere ma byt "zruseno" a v BC je pocet bajtu,ktere maji byt "zruseny". 19E5 CALL #19DD ;K ziskani potrebnych hodnot pouzij DIFERENCE 19E8 PUSH BC ;Uschovej pocet bajtu LD A,B ;Vsechny systemove ukazatele nad touto oblasti CPL ;musi byt snizeny o "BC",a proto je jeho obsah LD B,A ;komplementovan LD A,C CPL LD C,A INC BC CALL #1664 ;Vrat adresu prvniho mista do DE a vypocti EX DE,HL ;adresu prvniho mista,ktere ma byt ponechano POP HL ADD HL,DE PUSH DE ;Uschovej adresu prvniho mista po dobu LDIR ;reklamace,vyzvedni ji do HL POP HL RET Podprogram E-LINE-NO -------------------- Podprogram vyzvedne cislo radku v editacni oblasti.Pokud radek nema cislo (primy prikaz),bude se povazovat za radek 0.Ve vsech pripadech se cislo radku vraci v BC. 19FB LD HL,(#5C59) ;Vyzvedni ukazatel editovaneho radku a postup DEC HL ;jedno misto pred nej ??? LD (CH-ADD),HL ;Nastav CH-ADD RST #20 ;Vyzvedni prvni kod do A LD HL,#5C92 ;Udelej z pameti kalkulatoru zasobnik kalkula- ??? LD (STKEND),HL ;toru.Nyni cti cislo radku CALL #2D3B CALL #2DA2 ;Kompresuj cislo do BC ??? JR C,#1A15 ;Skoc dopredu pokud cislo 65535 LD HL,#D8F0 ADD HL,BC ;Testuj na "10.000" 1A15 JP C,#1C8A ;Skok na chybove hlaseni(cislo 9999) JP #16C5 ;Navrat pres SET-STK obnovi oblasti kalkulatoru MONITOR ROM - ZX Spectrum - 56 - B) Tabulka parametru V tabulce parametru je az 8 polozek pro kazdy z padesati basickych prikazu. Tyto polozky obsahuji udaje o tride prikazu,o pozadovanych separatorech a je-li to potreba,take adresy prikazovych rutin. 1A7A DEFB #01 ;P-LET CLASS-01 DEFB #3D ;rovnitko DEFB #02 ;CLASS-02 1A7D DEFB #06 ;P-GO-TO CLASS-06 DEFB #00 ;CLASS-00 DEFB #67,#1E ;GOTO,#1E67 1A81 DEFB #06 ;P-IF CLASS-06 DEFB #CB ;THEN DEFB #05 ;CLASS-05 DEFB #F0,#1C ;IF,#1CF0 1A86 DEFB #06 ;P-GO-SUB CLASS-06 DEFB #00 ;CLASS-00 DEFB #ED,#1E ;GO SUB,#1EED 1A8A DEFB #00 ;P-STOP CLASS-00 DEFB #EE,#1C ;STOP,#1CEE 1A8D DEFB #00 ;P-RETURN CLASS-00 DEFB #23,#1F ;RETURN,#1F23 1A90 DEFB #04 ;P-FOR CLASS-04 DEFB #3D ;rovnitko DEFB #06 ;CLASS-06 DEFB #CC ;TO DEFB #06 ;CLASS-06 DEFB #05 ;CLASS-05 DEFB #03,#1D ;FOR,#1D03 1A98 DEFB #04 ;P-NEXT CLASS-04 DEFB #00 ;CLASS-00 DEFB #AB,#1D ;NEXT,#1DAB 1A9C DEFB #05 ;P-PRINT CLASS-05 DEFB #CD,#1F ;PRINT,#1FCD 1A9F DEFB #05 ;P-INPUT CLASS-05 DEFB #89,#20 ;INPUT,#2089 1AA2 DEFB #05 ;P-DIM CLASS-05 DEFB #02,#2C ;DIM,#2C02 1AA5 DEFB #05 ;P-REM CLASS-05 DEFB #B2,#1B ;REM,#1BB2 1AA8 DEFB #00 ;P-NEW CLASS-00 DEFB #B7,#11 ;NEW,#11B7 1AAB DEFB #03 ;P-RUN CLASS-03 DEFB #A1,#1E ;RUN,#1EA1 1AAE DEFB #05 ;P-LIST CLASS-05 DEFB #F9,#17 ;LIST,#17F9 1AB1 DEFB #08 ;P-POKE CLASS-08 DEFB #00 ;CLASS-00 DEFB #80,#1E ;POKE,#1E80 1AB5 DEFB #03 ;P-RANDOM CLASS-03 DEFB #4F,#1E ;RANDOMIZE,#1E4F 1AB8 DEFB #00 ;P-CONT CLASS-00 DEFB #5F,#1E ;CONTINUE,#1E5F 1ABB DEFB #03 ;P-CLEAR CLASS-03 DEFB #AC,#1E ;CLEAR,#1EAC 1ABE DEFB #00 ;P-CLS CLASS-00 DEFB #6B,#0D ;CLS,#0D6B 1AC1 DEFB #09 ;P-PLOT CLASS-09 DEFB #00 ;CLASS-00 DEFB #DC,#22 ;PLOT,#22DC 1AC5 DEFB #06 ;P-PAUSE CLASS-06 DEFB #00 ;CLASS-00 DEFB #3A,#1F ;PAUSE,#1F3A 1AC9 DEFB #05 ;P-READ CLASS-05 DEFB #ED,#1D ;READ,#1DED 1ACC DEFB #05 ;P-DATA CLASS-05 DEFB #27,#1E ;DATA,#1E27 1ACF DEFB #03 ;P-RESTORE CLASS-03 DEFB #42,#1E ;RESTORE,#1E42 1AD2 DEFB #09 ;P-DRAW CLASS-09 DEFB #05 ;CLASS-05 DEFB #82,#23 ;DRAW,#2382 1AD6 DEFB #00 ;P-COPY CLASS-00 DEFB #AC,#0E ;COPY,#0EAC 1AD9 DEFB #05 ;P-LPRINT CLASS-05 DEFB #C9,#1F ;LPRINT,#1FC9 1ADC DEFB #05 ;P-LLIST CLASS-05 DEFB #F5,#17 ;LLIST,#17F5 1ADF DEFB #0B ;P-SAVE CLASS-0B 1AE0 DEFB #0B ;P-LOAD CLASS-0B 1AE1 DEFB #0B ;P-VERIFY CLASS-0B 1AE2 DEFB #0B ;P-MERGE CLASS-0B 1AE3 DEFB #08 ;P-BEEP CLASS-08 DEFB #00 ;CLASS-00 DEFB #F8,#03 ;BEEP,#03F8 MONITOR ROM - ZX Spectrum - 58 - Prikaz byl identifikovan,takze nyni je treba posoudit jeho prvni cast. LD HL,#1B76 ;Navratova adresa STMT-RET je ulozena PUSH HL ;na zasobnik LD C,A ;Uloz si prechodne prikaz do registru C, RST #20 ;zatimco opet posunes CH-ADD LD A,C ;Redukuj kod prikazu konstnatou #CE,cimz SUB #CE ;dosahnes rozsahu od #00 az do #31 pro padesat JP C,#1C8A ;prikazu.Oznam chybu v pripade,ze nejde o kod LD C,A ;prikazu.Prenes kod prikazu do BC LD HL,#1A48 ;Toto je bazova adresa tabulky syntaxe ADD HL,BC ;Pozadovany do plnek je predan do C a pouzit LD C,(HL) ;k vypoctu bazove adresy pro prikazove polozky ADD HL,BC ;v tabulce parametru JR #1B55 ;S touto adresou skoc do prohlizeci smycky Vsechny programy pro posuzovani tridy daneho prikazu jsou postupne vykonany. Vsechny pozadovane separatory jsou tez posouzeny. 1B52 LD HL,(#5C74) ;Prechodny ukazatel na polozku v tabulce 1B55 LD A,(HL) ;parametru.Vyzvedni postupne vsechny polozky INC HL ;Posun ukazatel na polozky pro dalsi pruchod LD (#5C74),HL LD BC,#1B52 PUSH BC ;Uloz na zasobnik navratovou adr. SCAN-LOOP LD C,A ;Okopiruj polozku do C pro pozdejsi pouziti CP #20 ;Je-li polozka separator,skoc JR NC,#1B6F LD HL,#1C01 ;Bazova adresa tabulky prikazovych trid LD B,#00 ADD HL,BC ;Hledej v teto tabulce a vyzvedni doplnek LD C,(HL) ADD HL,BC ;Vypocti startovaci adresu pozadovaneho pod- PUSH HL ;programu pro urceni tridy prikazu a uschovej RST #18 ;ji na zasobnik.Pred neprimym skokem do rutiny DEC B ;pro zjistovani tridy prikazu predej prikazovy RET ;kod do registru A a nastav registr B na #FF Subrutina SEPARATOR ------------------- Hlaseni Nonsense in BASIC je vypsano,jestlize pozadovany separator neni pritomen.Ale povsimnete si,ze pri kontrole syntaxe neni toto hlaseni vytisknuto,pouze blikajici "?". 1B6F RST #18 ;Aktualni znak je vyzvednut a porovnan CP C ;s parametrem v tabulce.Ohlas chybu,kdyz se JP NZ,#1C8A ;neshoduji RST #20 ;Postup za spravny znak RET Subrutina STMT-RET ------------------ Po spravne interpretaci prikazu se program navraci na toto misto. 1B76 CALL #1F54 ;Po kazdem prikazu je otestovano tlacitko BREAK JR C,#1B7D ;Skoc,nebyl-li stisknut BREAK, 1B7B RST #08 ;jinak ohlas: L - BREAK into program DEFB #14 1B7D BIT 7,(IY+10) ;(NSPPC) Neni-li potreba zadny "skok",skoc JR NZ,#1BF4 LD HL,(#5C42) ;Vyzvedni cislo noveho radku a pokud BIT 7,H ;neobsluhujes dalsi prikaz v editacni oblasti, JR Z,#1B9E ;skoc Vstupni bod LINE-RUN -------------------- Tento vstupni bod je pouzivan,kdykoliv ma byt radek v editacni oblasti spusten prikazem RUN.V tomto pripade bude nastaven bit 7 ve FLAGS jako signal,ze se provadi RUN (a ne SYNTAX).Tento vstupni bod je tez pouzivan pri kontrole radku v editacni oblasti,ktery obsahuje vice nez jeden prikaz (bit 7 FLAGS = 0). 1B8A LD HL,#FFFE ;Radek v editacni oblasti je posuzovan jako LD (#5C45),HL ;radek -2 LD HL,(5C61) DEC HL ;HL ukazuje na koncovy bajt v editacni oblasti LD DE,(#5C59) ;a DE na bajt pred editacni oblasti DEC DE LD A,(#5C44) ;Vyzvedni cislo dalsiho prikazu,ktery ma byt JR #1BD1 ;zpracovan,nez skocis dopredu MONITOR ROM - ZX Spectrum - 60 - Subrutina "KONTROLA KONCE" -------------------------- Toto je velmi dulezita rutina,ktera je volana z mnoha mist monitoroveho programu pri kontrole syntaxe nebo editacniho radku.Ukolem teto rutiny je vypsat chybove hlaseni,jestlize nebyl nalezen konec prikazu a presunout se na dalsi prikaz,byla-li syntaxe spravna. 1BEE CALL #2530 ;Pokud nekontrolujes syntaxi,vrat se RET NZ POP BC ;Odhod adresy SCAN-LOOP a STMT-RET pred POP BC ;pokracovanim do STMT-NEXT Rutina "DALSI PRIKAZ" --------------------- Jestlize aktualni znak je CR (=ENTER),pak "dalsi prikaz" je na "dalsim radku". Je-li to ":",je "dalsi prikaz" na tom samem radku,ale jestlize je zde jakykoli jiny znak,pak se jedna o syntaktickou chybu. 1BF4 RST #18 ;Vyzvedni aktualni znak a jedna-li se o CR, CP #0D ;jdi na "dalsi radek" JR Z,#1BB3 CP #3A ;Jedna-li se o ":",jdi na dalsi prikaz JP Z,#1B28 JP #1C8A ;Jinak se jedna o syntaktickou chybu TABULKY TRID PRIKAZU -------------------- 1C01 0F CLASS-00,#1C10 * 1C07 7B CLASS-06,#1C82 1C02 1D CLASS-01,#1C1F * 1C08 8E CLASS-07,#1C96 1C03 4B CLASS-02,#1C4E * 1C09 71 CLASS-08,#1C7A 1C04 09 CLASS-03,#1C0D * 1C0A B4 CLASS-09,#1CBE 1C05 67 CLASS-04,#1C6C * 1C0B 81 CLASS-0A,#1C8C 1C06 0B CLASS-05,#1C11 * 1C0C CF CLASS-0B,#1CDB Prikazove tridy 00,03,05 ------------------------ Prikazy,ktere maji tridu 03 mohou,ale nemusi byt nasledovany cislem (napr. RUN a RUN 200). 1C0D CALL #1CDE ;Cislo je zjisteno,ale neni-li,pouzije se 0 Prikazy tridy 00 nesmi byt nasledovany operandem,(napr. COPY nebo CONTINUE). 1C10 CP A ;Nastav Z pro pozdejsi pouziti Prikazy tridy 05 smi byt nasledovany souborem polozek(napr.PRINT a PRINT "222") 1C11 POP BC ;Ve vsech pripadech odhod adresu SCAN-LOOP CALL Z,#1BEE ;U prikazu trid 00 a 05 se po kontrole syntaxe EX DE,HL ;pokracuje v posuzovani dalsiho prikazu.Do DE ;uschovej cislo radku Rutina "SKOK C-R" ----------------- Po posouzeni vsech trid prikazu a vsech oddelovacich znaku se provede skok do prislusne prikazove rutiny. 1C16 LD HL(#5C74) ;Vyzvedni ukazatel na polozku v tabulce para- LD C,(HL) ;metru a vyzvedni adresu pozadovane prikazove INC HL ;rutiny LD B,(HL) EX DE,HL PUSH BC ;Zamen ukazatele a proved neprimy skok RET ;do prikazove rutiny Prikazove tridy 01,02 A 04 -------------------------- Tyto prikazove tridy jsou pouzivany pro prikazy,ktere pracuji s promennymi LET,FOR & NEXT a neprimo take READ & INPUT.Prikaz tridy 01 je volan pri identifikaci promenne pro prikazy LET,READ & INPUT. 1C1F CALL #28B2 ;Urci zda promenna jiz byla nebo nebyla ;identifikovana Promenna v prideleni -------------------- Tento podprogram vytvari prislusne hodnoty pro systemove promenne DEST a STRLEN. 1C22 LD (IY+55),#00 ;Nastav FLAGX na #00 JR NC,#1C46 ;Skoc dopredu kdyz promenna uz existuje SET 1,(IY+55) ;(FLAGX) Signal: Nova promenna JR NZ,#1C46 ;Jestlize dochazi k pokusu uzit nedimenzovane 1C2E RST #08 ;pole ohlas: 2 - Variable not found DEFB #01 MONITOR ROM - ZX Spectrum - 62 - 1C82 CALL #24FB ;Ohodnot dalsi vyraz BIT 6,(IY+1) ;(FLAGS) Byl-li vysledek ciselny,vrat se, RET NZ ;jinak ohlas: C - Nonsense in BASIC 1C8A RST #08 DEFB #0B Vstupni bod EXPT-EXP (odpovida tride 0A) umoznuje ohodnoceni jednoducheho retezcoveho vyrazu. 1C8C CALL #24FB ;Ohodnot dalsi vyraz BIT 6,(IY+1) ;(FLAGS) Je-li indikovan retezec,vrat se RET Z JR #1C8A ;Jinak ohlas chybu Subrutina "NASTAVENI PERMANENTNICH BAREV" (= trida 07) ------------------------------------------------------ Tato rutina umoznuje nastaveni aktualnich prechodnych barev.Jakozto prikaz tri- dy 07 predstavuje ve skutecnosti prikazovou rutinu pro sest barevnych prikazu. 1C96 BIT 7,(IY+1) ;(FLAGS) Je testovana vlajka "syntaxe/run" RES 0,(IY+2) ;(TV-FLAG) Signal:hlavni obrazovka CALL NZ,#0D4D ;V pripade RUN uprav dle prechodnych barev, POP AF ;barvy obrazovky.Odhod navratovou adresu LD A,(#5C74) ;SCAN-LOOP.Vyzvedni nizsi bajt T-ADDR a odec- SUB #13 ;ti 13,abys dosahl rozsahu #D9 az #DE coz jsou CALL #21FC ;INK az OVER.Skoc dopredu k vymene barev dle CALL #1BEE ;basickych prikazu.Presun se na dalsi prikaz LD HL,(#5C8F) ;jestlize kontrolujes syntaxi.Nyni se prechodne LD (#5C8D),HL ;barvy stanou permanentnimi.A to jak ATTR-P LD HL,#5C91 ;tak MASK-P.Toto je P-FLAG a ten musi byt take LD A,(HL) ;musi byt take posouzen Nasledujici instrukce velmi rafinovane okopiruji liche bity na mista sudych bitu,coz ve skutecnosti zpusobi,ze permanentni barvy budou mit hodnoty prechodnych barev. RLCA ;Posun masku doleva a vysledek necht se projevi XOR (HL) ;pouze na lichych bitech tohoto bajtu AND #AA XOR (HL) LD (HL),A ;Obnov vysledek RET Prikazy tridy 09 ---------------- Tato rutina se pouziva pro prikazy PLOT,DRAW a CIRCLE,aby urcila konstantni hodnoty pro "FLASH 8,BRIGHT 8 a PAPER 8",ktere jsou nastaveny jeste predtim, nez budou posouzeny pripadne barevne polozky. 1CBE CALL #2530 ;Pri kontrole syntaxe,skoc JR Z,#1CD6 RES 0,(IY+2) ;(TV-FLAG) Signal:hlavni obrazovka CALL #0D4D ;Nastav prechodne barvy pro hlavni obrazovku LD HL,#5C90 ;Vyzvedni jeho hodnotu a vezmi z ni pouze cast LD A,(HL) ;odpovidajici nemaskovanemu INK OR #F8 ;Obnov hodnotu,ktera indikuje FLASH 8,INK 8 LD (HL),A ;(P-FLAG) a PAPER 8.Take zajisti,ze nebude RES 6,(IY+87) ;PAPER 9.Vyzvedni soucasny znak,pred obsluhou RST #18 ;dalsich barevnych polozek.Zpracuj mistne 1CD6 CALL #21E2 ;dominantni barevnou polozku.Nyni vyzvedni JR #1C7A ;prvni dva operandy pro PLOT, DRAW a CIRCLE Prikazy tridy 0B ---------------- Tato rutina se pouziva pro prikazy SAVE,LOAD,VERIFY a MERGE. 1CDB JP #0605 ;Skoc do kazetovych rutin Subrutina "VYZVEDNUTI CISLA" ---------------------------- Tato rutina zpusobi,ze nasledujici ciselny vyraz bude vyhodnocen,ale jestlize neexistuje,bude nahrazen nulou. 1CDE CP #0D ;Jedna-li se o konec radku,skoc JR Z,#1CE6 CP #3A ;Ale jde-li o konec prikazu,skoc na EXPT-1NUM JR NZ,#1C82 Nyni je pouzit kalkulator,aby ulozil nulu na zasobnik. 1CE6 CALL #2530 ;Neprovadej tuto operaci pri kontrole syntaxe RET Z RST #28 ;Pouzij kalkulator DEFB #A0 ;STK-NULA "Posledni hodnota" je nyni nula DEFB #38 ;konec vypoctu RET MONITOR ROM - ZX Spectrum - 64 - Nove hodnoty pro LIMIT a STEP jsou nyni secteny. 1D34 PUSH HL ;Je uschovan ukazatel RST #28 ; l,s DEFB #02 ;vymaz l DEFB #02 ;vymaz DEFB #38 ;konec vypoctu.DE stale ukazuje na "l" POP HL ;Ukazatel je obnoven a ukazatele zameneny EX DE,HL LD C,#0A ;Deset bajtu LIMITu a STEPu je presunuto LDIR Nyni se vstupuje s cislem "smyckovaciho" radku a prikazu. LD HL,(#5C45) ;Cislo aktualniho radku EX DE,HL ;Zamen registry pred pridanim cisla radku LD (HL),E ;k ridici promenne FOR INC HL LD (HL),D LD D,(IY+13) ;(SUBPPC) "Smyckovaci" je vzdy dalsim prikazem INC D ;at jiz existuje,nebo ne INC HL LD (HL),D Podprogram NEXT-LOOP se vola aby testoval moznost "prubehu" a jestlize je to mozne,provede se navrat.Jinak se identifikuje prikaz za smyckou FOR-NEXT. CALL #1DDA ;Je "prubeh" mozny? RET NC ;Jestlize ano,vrat se LD B,(IY+56) ;(STRLEN-LO) Vyzvedni nazev promenne LD HL,(#5C45) ;Kopiruj cislo aktualniho radku do NEW-PPC LD (#5C42),HL LD A,(#5C47) ;Vyzvedni cislo aktualniho prikazu a kompletuj NEG LD D,A ;Preved vysledek do D LD HL,(#5C5D) ;Vyzvedni hodnotu CH-ADD LD E,#F3 ;Bude se hledat "NEXT" Nyni se vzestupne prohledava programova oblast,dokud neni nalezen prvni NEXT nasledovany spravnou promennou. 1D64 PUSH BC ;Uschovej nazev promenne LD BC,(#5C55) ;Vyzvedni aktualni hodnotu NXTLIN.Programova CALL #1D86 ;oblast je prohledavana a BC se bude menit LD (#5C55),BC ;s kazdym novym radkem POP BC ;Obnov nazev promenne JR C,#1D84 ;Nebylo-li NEXT nalezeno,skoc na chybove RST #20 ;hlaseni jinak prejdi za nalezene NEXT OR #20 ;Akceptuj mala i velka pismena,testuj nazev CP B ;promenne a skoc dopredu v pripade shody.Opet JR Z,#1D7C ;posun CHADD a nejedna-li se o spravnou RST #20 ;promennou,skoc zpet JR #1D64 NEWPPC obsahuje cislo radku,ve kterem byl nalezen prikaz NEXT.Musi byt nalezena pozice prikazu v radku a ulozena v NSPPC. 1D7C RST #20 ;Posun CHADD.Pocitadlo prikazu v registru D LD A,#01 ;pocitalo prikazy od nuly a proto musi byt SUB D ;odecteno od jedne.Vysledek je uschovan LD (#5C44),A RET ;Vrat se do STMT-RET 1D84 RST #08 ;Ohlas: FOR without NEXT DEFB #11 Podprogram "LOOK PROG" ---------------------- Tento podprogram se pouziva k vyhledavani prikazu DATA,DEF FN nebo NEXT. Na vstupu je prislusny kod tokenu v registru E a HL ukazuje na zacatek prohledavane oblasti. 1D86 LD A,(HL) ;Vyzvedni aktualni znak.Je-li to ":" (coz CP #3A ;indikuje vyskyt vice prikazu v radku) skoc JR Z,#1DA3 Vstup do smycky, ktera prozkouma kazdy dalsi radek. 1D8B INC HL ;Vyzvedni vyssi bajt cisla radku a nejsou-li LD A,(HL) ;v programu dalsi radky,vrat se s CY=1 AND #C0 SCF RET NZ LD B,(HL) ;Cislo radku je vyzvednuto a predano do NEWPPC INC HL LD C,(HL) LD (#5C42),BC INC HL LD C,(HL) MONITOR ROM - ZX Spectrum - 66 - Rutina prikazu READ ------------------- Prikaz READ umoznuje nacitani seznamu DATA a ve skutecnosti je podobny serii prikazu LET.Systemova promenna X-PTR se vyuziva k uschove ukazatele na prikaz READ,zatimco CHADD slouzi ke krokovani seznamu DATA. 1DEC RST #20 ;Posun na dalsi znak a jeho vyzvednuti v A 1DED CALL #1C1F ;Zjisteni zdali promenna existuje a jeji CALL #2530 ;vyhledani.Pri kontrole syntaxe skok dopredu JR Z,#1E1E RST #18 ;Vyzvedni znak LD (#5C5F),HL ;Uschova CHADD v X-PTR LD HL,(#5C57) ;Vyzvedni ukazatel na seznam DATA,nacti dalsi LD A,(HL) ;znak a pokud nebyl nalezen novy prikaz DATA, CP #2C ;skoc JR Z,#1E0A LD E,#E4 ;Hleda se token DATA.Pri uspesnem nalezu,skoc CALL #1D86 JR NC,#1E0A 1E08 RST #08 ;Ohlas: Out of DATA DEFB #0D Pokracovani - vybirani hodnot ze seznamu DATA. 1E0A CALL #0077 ;Posunuj ukazatel po seznamu a nastav CHADD CALL #1C56 ;Vyzvedni hodnotu a pridel ji promenne RST #18 ;Vyzvedni aktualni hodnotu CHADD a uloz ji LD (#5C57),HL ;v DATADD.Vyzvedni ukazatel prikazu READ LD HL,(#5C5F) ;a vynuluj X-PTR-HI LD (IY+38),#00 CALL #0078 ;CHADD jeste jednou ukazuje na prikaz READ 1E1E RST #18 ;Vyzvedni aktualni znak a testuj na carku CP #2C JR Z,1DEC ;Je-li to carka,skoc zpet,protoze existuji CALL #1BEE ;dalsi polozky.Pri kontrole syntaxe se vrat RET ;pres CHECK-END anebo do STMT-RET Rutina prikazu DATA ------------------- Pri kontrole syntaxe je prikaz DATA testovan,zdali obsahuje serii platnych prikazu,oddelenych carkami.Ale pri behu programu se tento prikaz vynecha. 1E27 CALL #2530 ;Pokud nekontrolujes syntaxi,skoc JR NZ,#1E37 1E2C CALL #24FB ;Kontroluj dalsi vyraz a spravny oddelovac CP #2C CALL NZ,#1BEE ;Posun se na dalsi prikaz pokud nesouhlasi RST #20 ;Dalsi znak JR #1E2C ;Pokracuj ve smycce Pri behu programu se prikaz DATA prekroci. 1E37 LD A,#E4 ;Token DATA Podprogram vynechani -------------------- Na vstupu je v registru A kod prikazu,ktery ma byt vynechan.(DATA nebo DEF FN, podle momentalniho pouziti tohoto podprogramu). 1E39 LD B,A ;At obsahuje BC nejake dosti vysoke cislo CPDR ;Vzestupne hledani token LD DE,#0200 ;Nyni najdi nasledujici prikaz (D minus prvy) JP #198B Rutina prikazu RESTORE ---------------------- Operand pro RESTORE se povazuje za cislo radku a pokud neni uveden,dosadi se nula.Vstupni bod REST-RUN se pouzije za chodu. 1E42 CALL #1E99 ;Kompresuj operand do BC 1E45 LD H,B ;Preved vysledek do HL LD L,C CALL #196E ;Najdi adresu tohoto,nebo nasledujiciho radku DEC HL ;DATADD bude ukazovat na jednu pozici pred LD (#5C57),HL ;radek RET Rutina prikazu RANDOMIZE ------------------------ Operand je kompresovan do BC a ulozen do prislusne systemove promenne.Neni-li operand uveden,pouziji se hodnoty z FRAMES 1 a FRAMES 2. 1E4F CALL #1E99 ;Vyzvedni operand do BC a pokud se nejedna LD A,B ;nulovou hodnotu,skoc OR C JR NZ,#1E5A LD BC,(#5C78) ;Vyzvedni dva "nizsi" bajty FRAMES a uloz je 1E5A LD (#5C76),BC ;do systemove promenne SEED RET MONITOR ROM - ZX Spectrum - 68 - Rutina prikazu CLEAR -------------------- Rutina zpusobi vycisteni oblasti promennych,obrazovky a nastaveni RAMTOP. Nasledkem teto posledni operace je znovu nastaven zasobnik a tim take vycisten zasobnik GO SUB. 1EAC CALL #1E99 ;Vyzvedni operand a pouzij 0,neexistuje-li 1EAF LD A,B ;Pokud operand neni nulovy,skoc OR C JR NZ,#1EB7 ;(Pri volani z RUNu,ke skoku nedojde) LD BC,(#5CB2) ;Pouzij stavajici hodnotu RAMTOP 1EB7 PUSH BC ;Uschovej ji LD DE,(#5C4B) ;Zrus oblast promennych LD HL,(#5C59) DEC HL CALL #19E5 CALL #0D6B ;Vycisti obrazovku Hodnota v BC je testovana na pripustne minimum a maximum. LD HL,(#5C65) ;Aktualni hodnota zasobniku je zvysena LD DE,#0032 ;o 50 bajtu,coz bude predstavovat dolni limit ADD HL,DE POP DE SBC HL,DE JR NC,#1EDA ;RAMTOP je prilis nizky LD HL,(#5CB4) ;Je vyzvednuta hodnota P-RAMT a je testovana AND A ;proti RAMTOP SBC HL,DE JR NC,#1EDC ;Skoc dopredu,je-li hodnota prijatelna 1EDA RST #08 ;Ohlas: RAMTOP no good DEFB #15 Pokracuj operaci CLEAR. 1EDC EX DE,HL ;Skutecne nastaveni RAMTOP LD (#5CB2),HL POP DE ;Vyzvedni adresu STMT-RET a "chybovou" adresu POP BC LD (HL),#3E ;Vloz koncovy znak pro zasobnik GO SUB DEC HL ;Vynech jedno misto LD SP,HL ;Nastav ukazatel zasobniku na prazdny zasobnik PUSH BC ;GO SUB.Uloz "chybovou" adresu na zasobnik LD (#5C3D),SP ;a uschovej jeho adresu do ERR-SP.Zamen adresy EX DE,HL ;a proved neprimy navrat do STMT-RET JP (HL) Poznamka: Je-li CLEAR volan prikazem RUN,je treba najit dalsi radek skokem do STMT-RET,protoze hodnoty NEWPPC a NSPPC byly jiz zameneny. Rutina prikazu "GO SUB" ----------------------- Aktualni hodnota PPC a zvysena hodnota SUBPPC jsou ulozeny na zasobnik GO SUB. 1EED POP DE ;Vyzvedni navratovou adresu k uschovani v DE LD H,(IY+13) ;(SUBPPC) Vyzvedni cislo prikazu a inkrementuj INC H ;jej EX (SP),HL ;Zamen "chybovou adresu" s cislem prikazu INC SP ;a reklamuj tuto lokaci LD BC,(#5C45) ;Dale uloz cislo aktualniho radku PUSH BC ;Vrat "chybovou adresu" na zasobnik a nastav PUSH HL ;ERR-SP tak,aby na ni ukazoval LD (#5C3D),SP PUSH DE ;Vrat adresu STMT-RET CALL #1E67 ;Nastav NEWPPC & NSPPC na potrebne hodnoty LD BC,#0014 ;Priprav hodnotu na testovani prostoru Podprogram testovani prostoru ----------------------------- Provadi radu testu,je-li dostatecny prostor volne pameti pro vykonani provadeneho ukolu. 1F05 LD HL,(#5C65) ;Vezmi hodnotu STKEND a zvys ji o hodnotu v BC ADD HL,BC JR C,#1F15 ;Skoc na chybove hlaseni,doslo-li k preteceni EX DE,HL ;Dalsi pokus s prictenim 80 bajtu LD HL,#0050 ADD HL,DE JR C,#1F15 ;Skoc na chybove hlaseni,doslo-li k preteceni SBC HL,SP ;Testuj proti adrese zasobniku a vrat se, RET C ;pokud vyhovuje 1F15 LD L,#03 ;Toto je chyba za behu a proto se nikdy JP #0055 ;nepouzije chybovy znak (otaznik) MONITOR ROM - ZX Spectrum - 70 - 1F7D CP #28 ;Zavorka "(" musi nasledovat za nazvem promenne JR NZ,#1FBD ;Skok na chybu RST #20 ;Vyzvedni dalsi znak CP #29 ;Test na zavorku ")" JR Z,#1FA6 ;Skoc,jestlize funkce nema parametry Zde se vstupuje do smycky,ktera postupne osetri vsechny parametry. 1F86 CALL #2C8D ;Je aktualni znak v registru A pismeno? 1F89 JP NC,#1C8A ;Skok na chybu jestli ne EX DE,HL ;Uschovej ukazatel v DE RST #20 ;Vyzvedni dalsi znak CP #24 ;Nejedna-li se o $,skoc JR NZ,#1F94 EX DE,HL ;Uschovej novy ukazatel v DE RST #20 ;Vyzvedni dalsi znak 1F94 EX DE,HL ;Predej ukazatel na posledni pismeno nazvu LD BC,#0006 ;do HL a vytvor prostor 6 bajtu za timto CALL #1655 ;poslednim znakem nazvu INC HL ;Do prvni z novych lokaci uloz znak uvadejici INC HL ;FP cislo LD (HL),#0E CP #2C ;Neni-li aktualni znak carka,opust smycku, JR NZ,#1FA6 ;protoze nejsou dalsi parametry RST #20 ;Vyzvedni dalsi znak a skoc zpet pro dalsi JR #1F86 ;parametry Dale je posouzena definice funkce. 1FA6 CP #29 ;Kontrola ze zavorka ")" skutecne existuje JR NZ,#1FBD ;Skok na chybu RST #20 ;Vyzvedni dalsi znak a neni-li to rovnitko, CP #3D ;skoc na chybu JR NZ,#1FBD RST #20 ;Vyzvedni dalsi znak LD A,(#5C3B) ;Vyzvedni jeho typ (ciselna/retezcova PUSH AF ;promenna) a uschovej CALL #24FB ;Posud definici jako vyraz.Vyzvedni typ POP AF ;promenne a testuj je-li stejneho typu jako XOR (IY+1) ;(FLAGS) promenna nalezena pro definici AND #40 1FBD JP NZ,#1C8A ;Pokud je treba skoc na chybu.Vystup pres CALL #1BEE ;CHECK-END a tim posun na hodnoceni dalsiho ;prikazu Podprogram UNSTACK-Z -------------------- Tento podprogram je volan v mnoha pripadech k provedeni "drivejsiho" navratu z podprogramu pri kontrole syntaxe.Tim se zabrani nezadoucim tiskum a presouvani hodnot na zasobniku kalkulatoru. 1FC3 CALL #2530 ;Jde o kontrolu syntaxe? POP HL ;Vyzvedni navratovou adresu a ignoruj ji pri RET Z ;kontrole syntaxe JP (HL) ;Za behu programu proved obycejny navrat Rutiny prikazu LPRINT & PRINT ----------------------------- Otevre se prislusny kanal a potom se postupne zkoumaji jednotlive polozky, ktere maji byt vytisknuty. 1FC9 LD A,#03 ;Priprava na otevreni kanalu P JR #1FCF 1FCD LD A#02 ;Priprava na otevreni kanalu S 1FCF CALL #2530 ;Pokud nekontrolujes syntaxi,skoc na otevreni CALL NZ,#1601 ;kanalu CALL #0D4D ;Nastav prechodne barvy CALL #1FDF ;Volej tiskovou rutinu CALL #1BEE ;Pri kontrole syntaxe se posun na dalsi prikaz RET Tiskova rutina je volana z programu PRINT,LPRINT & INPUT. 1FDF RST #18 ;Vyzvedni prvni znak a jsi-li jiz na konci CALL #2045 ;seznamu polozek skoc dopredu JR Z,#1FF2 Nyni vstup do smycky ktera,obsluhuje pozicni znaky a tiskove polozky 1FE5 CALL #204E ;Obsluz vsechny nasledovne pozicni znaky JR Z,#1FE5 ;Obsluz jednoduche tiskove polozky CALL #1FFC ;Testuj jestli jsou dalsi polozky a tiskni CALL #204E ;vsechny az do konce JR Z,#1FE5 1FF2 CP #29 ;Je-li aktualni znak zavorka ")",vrat se RET Z ;Jinak postup do podprogramu CR MONITOR ROM - ZX Spectrum - 72 - 2061 CP #27 ;Testuj apostrof "'" a vrat se,pokud se RET NZ ;nejednalo o nektery z pozicnich znaku CALL #1FF5 ;Pokud nekontrolujes syntaxi,tiskni CR 2067 RST #20 ;Vyzvedni dalsi znak CALL #2045 ;Nejsi-li na konci tisku prikazu,skoc JR NZ,#206E POP BC ;Jinak se vrat do volajici rutiny 206E CP A ;Nebylo-li dosazeno konce prikazu, RET ;nastavi se Z flag=0 Podprogram "ZMENA PROUDU" ------------------------- Kdykoliv je treba posoudit,jestli uzivatel chce pouzit odlisny proud,vola se tento podprogram. 2070 CP #23 ;Testuj znak "#" a pokud neni,vrat se s CY=1 SCF RET NZ RST #20 ;Vyzvedni dalsi znak CALL #1C82 ;Parametr na zasobnik kalkulatoru.CY=0.Vrat AND A ;se pri kontrole syntaxe CALL #1FC3 CALL #1E94 ;Vyzvedni hodnotu do A CP #10 ;Pokud je vetsi nez #0F,skoc na chybove hlaseni JP NC,#160C CALL #1601 ;Otevri kanal pro dany proud.CY=0 AND A RET Rutina prikazu INPUT -------------------- Tato rutina umoznuje prideleni hodnot vstupujicich z klavesnice do dane promenne.Soucasne zajistuje,aby tiskova informace,ktera je vlozena do prikazu INPUT,byla vypsana v dolni casti. 2089 CALL #2530 ;Pri kontrole syntaxe skoc JR Z,#2096 LD A,#01 CALL #1601 ;Kanal K a jeho otevreni CALL #0D6E ;Smazani dolni casti obrazovky 2096 LD (#5C6B),#01 ;Nastav dolni cast na velikost jedne radky CALL #20C1 ;Volej obsluhu vlozenych tisku.Pri kontrole CALL #1BEE ;syntaxe postup na dalsi radek.Vyzvedni LD BC,(#5C88) ;aktualni tiskovou pozici a pokud se tato LD A,(#5C6B) ;nachazi nad dolni casti obrazovky,skoc CP B JR C,#20AD LD C,#21 ;Jinak nastav tiskovou pozici na nejvyssi radek LD B,A ;dolni casti obrazovky 20AD LD (#5C88),BC LD A,#19 ;Nyni nastav citac skrolovani SUB B LD (#5C8C),A RES 0,(IY+2) ;(TV-FLAG) Signal:hlavni obrazovka.Nastav sys- CALL #0DD9 ;temove promenne a proved vystup pres CLS-LOWER JP #0D6E Tato smycka se zabyva polozkami INPUT a PRINT. 20C1 CALL #204E ;Nejprve posuzuj pozicni znaky JR Z,#20C1 CP #28 ;Jestlize aktualni znak neni "(",skoc dopredu JR NZ,#20D8 RST #20 ;Vyzvedni dalsi znak CALL #1FDF ;Vytiskni polozky uvnitr zavorek RST #18 ;Vyzvedni znak a pokud to neni ")", CP #29 ;skoc na chybove hlaseni JP NZ,#1C8A RST #20 ;Vyzvedni dalsi znak a skoc na posouzeni JP #21B2 ;dalsich pripadnych polozek Nyni posuzuj,je-li pouzito INPUT LINE. 20D8 CP #CA ;Nejedna-li se o LINE,skoc JR NZ,#20ED RST #20 ;Vyzvedni dalsi znak CALL #1C1F ;Urceni cilove adresy pro promennou SET 7,(IY+55) ;(FLAGX) Signal: INPUT LINE BIT 6,(IY+19) ;(FLAGS) Nejde-li o retezcovou promennou,skoc JP NZ,#1C8A JR #20FA ;Skok na vypsani naznaku Zpracovani promennych INPUT. 20ED CALL #2C8D ;Neni-li aktualni znak pismeno,skoc zpet JP NC,#21AF ;do smycky CALL #1C1F ;Urceni,cilove adresy promenne RES 7,(IY+55) ;(FLAGX) Signal:Nejedna se o INPUT LINE MONITOR ROM - ZX Spectrum - 74 - Jsou posuzovany dalsi polozky. 21AF CALL #1FFC ;Osetri jakoukoliv tiskovou polozku 21B2 CALL #204E ;Osetri jakoukoliv pozicni polozku JP Z,#20C1 ;Pripadny skok na posouzeni dalsich polozek RET Podprogram "IN ASSIGN" ---------------------- Tento podprogram je volan dvakrat pro kazdy INPUT.Jednou pri "kontrole syntaxe" a jednou za behu programu. 21B9 LD HL,(#5C61) ;Nastav CH-ADD aby ukazovala na prvni misto LD (#5C5D),HL ;pracovniho prostoru RST #18 ;Vyzvedni znak CP #E2 ;Je to token STOP? JR Z,#21D0 ;Skoc,jestlize ano LD A,(#5C71) ;Jinak prirad promenne jeji hodnotu CALL #1C59 RST #18 ;Vyzvedni znak a pokud se jedna o CR, CP #0D RET Z 21CE RST #08 ;Ohlas: Nonsence in BASIC DEFB #0B Do tohoto bodu se skoci v pripade,ze INPUT zacina prikazem STOP. 21D0 CALL #2530 ;Ale pri kontole syntaxe nebude ohlasena RET Z ;"chyba" 21D4 RST #08 ;Ohlas: Stop in INPUT DEFB #10 Podprogram "IN-CHAN-K" ---------------------- Podprogram vraci Z flag=0,jedine kdyz se pouziva kanal K. 21D6 LD HL,(#5C51) ;Je vyzvednuta bazova adresa kanalovych INC HL ;kanalovych informaci a kod aktualniho INC HL ;kanalu je testovano proti znaku K INC HL INC HL LD A,(HL) CP #4B RET Rutiny "BAREVNYCH" polozek -------------------------- Tento set lze rozdelit na dve casti: a) Cast obsluhujici "implementovane" barevne informace. b) Cast obsluhujici systemove promenne ATTR-T,MASK-T,P-FLAG. a) Barevne informace budou zpracovany postupne.Vstupni bod je CO-TEMP-2. 21E1 RST #20 ;Vyzvedni dalsi znak 21E2 CALL #21F2 ;Posud, je-li tento znak vlozenou barevnou RET C ;informaci.Vrat se s CY=1 pokud neni RST #18 ;Vyzvedni aktualni znak CP #2C ;Je-li to carka,skoc JR Z,#21E1 CP #3B ;Je-li to strednik,skoc JR Z,#21E1 JP #1C8A ;Jinak ohlas chybu 21F2 CP #D9 ;Jestlize testovany kod neni v rozsahu #D9 RET C ;az #DD (INK az OVER),vracej se s CY=1 CP #DF CCF RET C PUSH AF ;Uschovej kode barevne informace a posun RST #20 ;ukazatel na parametr POP AF ;Obnov kod Kode barevne informace a jeho parametr jsou nyni vytisknuty volanim rutiny PRINT-OUT. 21FC SUB #C9 ;Kode token je snizeno na hodnotu ridiciho PUSH AF ;znaku (#10 az #15).Uschovej kod CALL #1C82 ;Predej parametr na zasobnik kalkulatoru POP AF ;Obnov kod a pokud kontrolujes syntaxi,vrat AND A ;se pomoci UNSTACK-Z CALL #1FC3 PUSH AF ;Uschovej kod CALL #1E94 ;Vyzvedni parametr a preved do D LD D,A POP AF ;Obnov kode a vytiskni jej RST #10 LD A,D ;Parametr do A a vytiskni jej RST #10 RET MONITOR ROM - ZX Spectrum - 76 - Nyni se zpracuje FLASH & BRIGHT. 2273 SBC A,A ;Pro BRIGHT bude Z flag=0 LD A,D ;Parametr je vyzvednut a rotovan RRCA LD B,#80 ;Priprav masku pro FLASH JR NZ,#227D ;Skoc dopredu jde-li o FLASH.Dalsi rotace RRCA ; a priprava masky pro BRIGHT LD B,#40 227D LD C,A ;Uschovej hodnotu v C LD A,D ;Vyzvedni parametr a testuj jeho rozsah CP #08 ;Povoleno je pouze #08,#01 a #02 JR Z,#2287 CP #02 JR NC,#2244 ;Skoc na chybove hlaseni 2287 LD A,C ;Obnov uschovanou hodnotu do A LD HL,#5C8F CALL #226C ;Proved zmenu ATTR-T LD A,C ;Obnov uschovanou hodnotu do A RRCA ;Rotuj,aby bit nastaveny pro FLASH/BRIGHT 8 RRCA ;presel na misto bitu 7 pro FLASH nebo bitu 6 RRCA ;pro BRIGHT JR #226C ;Vystup pres CO-CHANGE Rutina prikazu BORDER --------------------- Parametr prikazu BORDER je proveden instrukci OUT a uschovan v systemove promenne BORDCR. 2294 CALL #1E94 ;Vyzvedni parametr a testuj jeho rozsah CP #08 JR NC,#2244 ;Skok na chybu,je-li perametr vetsi nez 7 OUT (#FE),A ;Nastav barvu BORDERu RLCA ;Nasob parametr osmi RLCA RLCA BIT 5,A ;Je-li barva BORDER svetla,skoc(INK bude cerny) JR NZ,#22A6 XOR #07 ;Zmena barvy INK 22A6 LD (#5C4B),A ;Nastav systemovou promennou BORDCR a vrat se RET Podprogram "ADRESA OBRAZOVEHO BODU" ----------------------------------- Podprogram je pouzivan rutinami POINT a PLOT.Na vstupu obsahuje BC souradnice x,y.Na vystupu je v HL adresa bajtu obrazovky,ve kterem je dany "pixl" obsazen a registr A ukazuje na jeho pozici uvnitr tohoto bajtu. 22AA LD A,#AF ;Testuj,zda-li souradnice y neni vetsi nez 175 SUB B ;a jestlize ano,skoc na ohlaseni chyby JP C,#24F9 LD B,A ;B nyni obsahuje 175-y AND A ;A obsahuje bity 7 6 5 4 3 2 1 0 bajtu z reg. B RRA ;A obsahuje 00 a bity 7 6 5 4 3 2 1 SCF RRA ;A obsahuje 01 00 a bity 7 6 5 4 3 2 AND A RRA ;A obsahuje 01 00 00 a bity 7 6 5 4 3 XOR B AND #F8 ;A obsahuje 00 01 00 a bity 7 6 2 1 0 XOR B ;H bude obsahovat 64+8*INT(B/64)+(B mod 8) LD H,A ;coz je vyssi bajt adresy "pixlu" LD A,C ;A obsahuje bity 7 6 5 4 3 2 1 0 bajtu z reg. C RLCA RLCA RLCA ;A obsahuje bity 2 1 0 7 6 5 4 3 XOR B AND #C7 XOR B ;A obsahuje bity 2 1 5 4 3 5 4 3 RLCA ;A obsahuje bity 5 4 3 7 6 5 4 3 RLCA ;Takze L bude obsahovat LD L,A ;32*INT(B (B mod 64)/8)+INT(x/8) LD A,C ;A obsahuje (x mod 8) takze "pixl" je bit A-7 AND #07 ;uvnitr daneho bajtu RET Podprogram POINT ---------------- Podprogram je pouzivan rutinou prikazu POINT pri prohledavani.Na vstupu jsou souradnice ulozeny na zasobniku kalkulatoru a na vystupu je na zasobniku 1 pri barve "pixlu" INK,0 pri PAPER. 22CB CALL #2307 ;Souradnice y do registru B a x do C CALL #22AA ;Adresa "pixlu" do HL LD B,A ;B bude pocitat A+1 krat,aby se pozadovany bit INC B ;prevedl do bitu 0 LD A,(HL) MONITOR ROM - ZX Spectrum - 78 - 2320 RST #18 ;Vyzvedni aktualni znak a otestuj ho.Neni-li CP #2C ;to carka ohlas chybu JP NZ,#1C8A RST #20 ;Vyzvedni dalsi znak (polomer) a uloz ho CALL #1C82 ;na zasobnik kalkulatoru.Pri kontrole syntaxe CALL #1BEE ;prejdi na dalsi prikaz RST #28 ;Kalkulator DEFB #2A ;abs X,Y,Z DEFB #3D ;RE-STACK Tvar Z je preveden z INTEGERu na FP a ponechan na zasobniku proto je DEFB #38 ;konec vypoctu jeho exponent k dispozici LD A,(HL) ;Vezmi exponent polomeru CP #81 ;Testuj,jestli je mensi JR NC,233B ;nez 1.Jestlize ne,skoc RST #28 ; Je-li mensi, DEFB #02 ;vymaz vymaz ho ze zasobniku DEFB #38 ;konec vypoctu Zasobnik nyni obsahuje X,Y JR #22DC ;Narysuj bod na souradnicich X,Y Ad b) #233B az #2346 a volani CD-PRMS1.2*PI je ulozeno do pameti c.5 a je zavolano CD-PRMS1.Tento program ulozi do registru B pocet krivek,ktere jsou potrebne pro kruh viz. A=4*INT (PI*SQR Z/4)+4,coz je 4,8,12 ... az do maxima 32.Take uklada do pameti c.0 az c.4 hodnoty 2*PI/A,SIN(PI/A),0,COS(2*PI/A) a SIN(2*PI/A). 233B RST #28 DEFB #A3 ;stk-pi/2 X,Y,Z,PI/2 DEFB #38 ;konec vypoctu Nyni dochazi ke zmene LD (HL),#83 ;exponentu na #83,cimz dochazi ke zmene z PI/2 RST #28 ;na PI*2.X,Y,Z,2*PI DEFB #C5 ;ST-MEM-5 2*PI do MEM-5 DEFB #02 ;vymaz X,Y,Z DEFB #38 ;konec vypoctu CALL #247D ;Nastav pocatecni param. Ad c) #2347 az #2381:zbyvajici parametry a skok na DRAW.Testuje se,jestli je delka pocatecniho oblouku mensi nez jedna.Je-li tomu tak,provede se skok na proste narysovani bodu o souradnicich X,Y.Jinak jsou nastaveny tyto parametry: X+Z a Y-Z*SIN(PI/A) jako pocatecni a koncovy bod a okopirovany do COORDS.Nula a hodnota 2*Z*SIN(PI/A) jsou uschovany v MEM-1 a MEM-2 jako pocatecni prirustky.Smycka prikazu DRAW,ktera zajistuje rysovani oblouku,take zajisti,ze vsechny narysovane body zustanou na stejne kruznici a prirustkovy uhel bude 2*PI/A. 2347 PUSH BC ;Uschova pocitadla oblouku do B RST #28 ; X,Y,Z DEFB #31 ;zdvojeni X,Y,Z,Z DEFB #E1 ;get-mem-1 X,Y,Z,Z,SIN(PI/A) DEFB #04 ;nasobeni X,Y,Z,Z*SIN(PI/A) DEFB #38 ;konec vypoctu SIN(PI/A) je polovinou delky ; pocatecniho oblouku a tato hodnota LD A,(HL) ;je testovana,aby se zjistilo jestli je mensi CP #80 ;nez 0.5.Neni-li provede se skok JR NC,#235A RST #28 ; Jinak jsou Z a "polooblouk" vymazany DEFB #02 ;vymaz ze zasobniku kalkulatoru DEFB #02 ;vymaz DEFB #38 ;konec vypoctu POP BC ;Strojovy zasobnik je take vycisten a provede JP #22DC ;se skok na vytisteni jedineho bodu o sourad- 235A RST #28 ;nic. X,Y. X,Y,Z,Z*SIN(PI/A) DEFB #C2 ;ST-MEM-2 Z*SIN(PI/A) do MEM-2 DEFB #01 ;zamena X,Y,Z*SIN(PI/A),Z DEFB #C0 ;ST-MEM-0 X,Y,Z*SIN(PI/A),Z DEFB #02 ;vymaz X,Y,Z*SIN(PI/A) DEFB #03 ;odecitani X,Y-Z*SIN(PI/A) DEFB #01 ;zamena Y-Z*SIN(PI/A),X DEFB #E0 ;GET-MEM-0 Y-Z*SIN(PI/A),X,Z DEFB #0F ;scitani Y-Z*SIN(PI/A),X+Z DEFB #C0 ;ST-MEM-0 X+Z do MEM-0 DEFB #01 ;zamena X+Z,Y-Z*SIN(PI/A) DEFB #31 ;zdvojeni X+Z,Y-Z*SIN(PI/A),Y-Z*SIN(PI/A) DEFB #E0 ;GET-MEM-0 sa,sb,sb,sa DEFB #01 ;zamena sa,sb,sa,sb DEFB #31 ;zdvojeni sa,sb,sa,sb,sb DEFB #E0 ;GET-MEM-0 sa,sb,sa,sb,sb,sa DEFB #A0 ;STK-NULA sa,sb,sa,sb,sb,sa;0 DEFB #C1 ;ST-MEM-1 MEM-1 nastavena na nulu DEFB #02 ;vymaz sa,sb,sa,sb,sb,sa DEFB #38 ;konec vypoctu Zde "sa" znamena X+Z a "sb" znamena Y-Z*SIN(PI/A). MONITOR ROM - ZX Spectrum - 80 - Ad b) Pouhe volani CD-PRMS1.Tato subrutina uchova v registru B pocet kratsich oblouku,ktere jsou treba pro kompletni oblouk.Subrutina take uklada v MEM-0 az MEM-4 hodnoty G/A,SIN(G/2*A),0,COS(G/A),SIN(G/A). 23C1 CALL #247D ;Volani subrutiny Ad c) Nastavi se zbytek parametru jak je treba.Zasobnik bude obsahovat tyto ctyri polozky cteno shora: X0+X a Y0+Y jako koncovy bod posledniho oblouku, pak X0 a Y0 jako pocatecni bod prvniho oblouku. MEM-0 bude obsahovat X0 a MEM-5 Y0.MEM-1 a MEM-2 budou obsahovat pocatecni umisteni pro prvni oblouk U a V a MEM-3 a MEM-4 budou obsahovat COS(D/A) a SIN(G/A) pro potreby smycky rysujici oblouky.Formule pro vypocet U a V se da vysvetlit nasledovne:Misto aby se postupovalo po zaverecne tetive rekneme delky L,s prirustky X a Y,chceme postupovat po pocatecni tetive (ktera muze byt delsi) delky L*W,kde M=SIN(G/2*A)/SIN(G/2),s prirustky X*W a Y*W,ale pootocene o uhel (G/2-G/2*A), tedy s pravdivymy prirustky:U=Y*W*SIN (G/2-G/2*A)+X*W*COS (G/2-G/2*A) a V=Y*W*COS(G/2-G/2*A)-X*W*SIN(G/2-G/2*A).Tyto formulace mohou byt kontrolovany z diagramu,pri pouziti normalnich rozkladu pro COS(P-Q) a SIN(P-Q),kde Q=G/2-G/2*A. 23C4 PUSH BC ;Uloz pocitadlo oblouku na zasobniku RST #28 ; X,Y,SIN(G/2),Z DEFB #02 ;vymaz X,Y,SIN(G/2) DEFB #E1 ;GET-MEM-1 X,Y,SIN(G/2),SIN(G/2*A) DEFB #01 ;zamena X,Y,SIN(G/2*A),SIN(G/2) DEFB #05 ;deleni X,Y,SIN(G/2*A)/SIN(G/2)=W DEFB #C1 ;ST-MEM-1 W do MEM-1 DEFB #02 ;vymaz X,Y DEFB #01 ;zamena Y,X DEFB #31 ;zdvojeni Y,X,X DEFB #E1 ;GET-MEM-1 Y,X,X,W DEFB #04 ;nasobeni Y,X,X*W DEFB #C2 ;ST-MEM-2 X*W do MEM-2 DEFB #02 ;vymaz Y,X DEFB #01 ;zamena X,Y DEFB #31 ;zdvojeni X,Y,Y DEFB #E1 ;GET-MEM-1 X,Y,Y,W DEFB #04 ;nasobeni X,Y,Y*W DEFB #E2 ;GET-MEM-2 X,Y,Y*W,X*W DEFB #E5 ;GET-MEM-5 X,Y,Y*W,X*W,G DEFB #E0 ;GET-MEM-0 X,Y,Y*W,X*W,G,G/A DEFB #03 ;odcitani X,Y,Y*W,X*W,G-G/A DEFB #A2 ;STK-1/2 X,Y,Y*W,X*W,G-G/A,1/2 DEFB #04 ;nasobeni X,Y,Y*W,X*W,G/2-G/2*A=F DEFB #31 ;zdvojeni X,Y,Y*W,X*W,F,F DEFB #1F ;SIN X,Y,Y*W,X*W,F,SIN F DEFB #C5 ;ST-MEM-5 SIN F do MEM-5 DEFB #02 ;vymaz X,Y,Y*W,X*W,F DEFB #20 ;COS X,Y,Y*W,X*W,COS F DEFB #C0 ;ST-MEM-0 COS F do MEM-0 DEFB #02 ;vymaz X,Y,Y*W,X*W DEFB #C2 ;ST-MEM-2 X*W do MEM-2 DEFB #02 ;vymaz X,Y,Y*W DEFB #C1 ;ST-MEM-1 Y*W do MEM-1 DEFB #E5 ;GET-MEM-5 X,Y,Y*W,SIN F DEFB #04 ;nasobeni X,Y,Y*W*SIN F DEFB #E2 ;GET-MEM-2 X,Y,Y*W*SIN F,X*W DEFB #E0 ;GET-MEM-0 X,Y,Y*W*SIN F,X*W,COS F DEFB #04 ;nasobeni X,Y,Y*W*SIN F,X*W*COS F DEFB #0F ;scitani X,Y,Y*W*SIN F+X*W*COS F=U DEFB #E1 ;GET-MEM-1 X,Y,U,Y*W DEFB #01 ;zamena X,Y,Y*W,U DEFB #C1 ;ST-MEM-1 U do MEM-1 DEFB #02 ;vymaz X,Y,Y*W DEFB #E0 ;GET-MEM-0 X,Y,Y*W,COS F DEFB #04 ;nasobeni X,Y,Y*W*COS F DEFB #E2 ;GET-MEM-2 X,Y,Y*W*COS F,X*W DEFB #E5 ;GET-MEM-5 X,Y,Y*W*COS F,X*W,SIN F DEFB #04 ;nasobeni X,Y,Y*W*COS F,X*W*SIN F DEFB #03 ;odcitani X,Y,Y*W*COS F-X*W*SIN F=V DEFB #C2 ;ST-MEM-2 V do MEM-2 DEFB #2A ;ABS X,Y,V' (V'=ABS V) DEFB #E1 ;GET-MEM-1 X,Y,V',U DEFB #2A ;ABS X,Y,V',U' (U'=ABS U) DEFB #0F ;scitani X,Y,U'+ V' DEFB #02 ;vymaz X,Y DEFB #38 ;konec vypoctu DE nyni ukazuje na U'+V' LD A,(DE) ;Vem exponent U'+V' CP #81 ;Jestlize plati U'+V'<1,pak pouze uklid zasob- POP BC ;nik.Primka z bodu X0,Y0 do X0+X,Y0+Y JP C,#2477 ;Jinak pokracuj s parametry X,Y na zasobniku PUSH BC RST #28 DEFB #01 ;zamena Y,X DEFB #38 ;konec vypoctu LD A,(#5C7D) ;Dej X0 do A a tim dale na zasobnik CALL #2D28 MONITOR ROM - ZX Spectrum - 82 - LD A,(#5C5D) ;X-ova souradnice posledniho narysovaneho CALL #2D28 ;oblouku,rekneme Xz',je nyni okopirovana RST #28 ;na zasobnik DEFB #03 ;odcitani Y0+Y,X0+X-Xz' DEFB #01 ;zamena X0+X-Xz',Y0+Y DEFB #38 ;konec LD A,(#5C7E) ;Obdrzi se Y-ova souradnice CALL #2D28 RST #28 ; X0+X-Xz',Y0+Y,Yz' DEFB #03 ;odcitani X0+X-Xz',Y0+Y-Yz' DEFB #38 ;konec 2477 CALL #24B7 ;Zaverecny oblouk je narysovan tak,aby dosahl JP #0D4D ;bodu X0+1,Y0+Y,nebo uzavreni kruz.Nastav barvy Subrutina pro nastaveni parametru --------------------------------- Tato subrutina je vyuzivana jak prikazem CIRCLE,tak prikazem DRAW,aby jim nastavila pocatecni parametry.Prikaz CIRCLE ji vola s parametry X,Y a polomerem Z na vrcholu zasobniku,cteno shora.Prikaz DRAW ma sve X,Y,SIN(G/2) a Z,(jak je definovano v DRAW ad a),na vrcholu zasobniku.V nasledujicim komentari je obsah zasobnku ukazan pouze od Z dale.Subrutina vraci v registru B pocet oblouku,reg.A jiz byl popsan v prikazech CIRCLE a DRAW,a v MEM-0 az MEM-5 jsou hodnoty G/A,SIN(G/2*A),0,COS(G/A),SIN(G/A) a G. Pro kruznici se musi G rovnat hodnote 2*PI. 247D RST #28 ; Z DEFB #31 ;zdvojeni Z,Z DEFB #28 ;mocnina Z,SQR Z DEFB #34 ;stk-data Z,SQR Z,2 DEFB #32 ;exponent #82 DEFB #00 ;(#00,#00,#00) DEFB #01 ;zamena Z,2,SQR Z DEFB #05 ;deleni Z,2/SQR Z DEFB #E5 ;GET-MEM-5 Z,2/SQR Z,G DEFB #01 ;zamena Z,G,2/SQR Z DEFB #05 ;deleni Z,G*SQR Z/2 DEFB #2A ;ABS Z,G'*SQR Z/2 (G'=MOD G) DEFB #38 ;konec vypoctu Z,G'*SQR Z/2=A1 CALL #2DD5 ;Hodnota A1 je ulozena ze zasobniku do A je-li JR C,#2495 ;to mozno.Je-li A1>256,pouzij 252 AND #FC ;4*INT(A1/4) do A ADD A,#04 ;Pricti k poctu oblouku v A ctyri.Je-li to JR NC,#2497 ;stale mene nez 256,skoc 2495 LD A,#FC ;Zde pouzij 252 2497 PUSH AF ;Ted uschovej pocet oblouku a kopiruj tuto CALL #2D28 ;hodnotu take na zasobnik kalkulatoru RST #28 ; Z,A DEFB #E5 ;GET-MEM-5 Z,A,G DEFB #01 ;zamena Z,G,A DEFB #05 ;deleni Z,G/A DEFB #31 ;zdvojeni Z,G/A,G/A DEFB #1F ;SIN Z,G/A,SIN(G/A) DEFB #C4 ;ST-MEM-4 SIN(G/A) do MEM-4 DEFB #02 ;vymaz Z,G/A DEFB #31 ;zdvojeni Z,G/A,G/A DEFB #A2 ;STK-polovina Z,G/A,G/A,0.5 DEFB #04 ;nasobeni Z,G/A,G/2*A DEFB #1F ;SIN Z,G/A,SIN(G/2*A) DEFB #C1 ;ST-MEM-1 SIN(G/2*A) do mem-1. DEFB #01 ;zamena Z,SIN(G/2*A),G/A DEFB #C0 ;ST-MEM-0 G/A do MEM-0. DEFB #02 ;vymaz Z,SIN(G/2*A)=S DEFB #31 ;zdvojeni Z,S,S DEFB #04 ;nasobeni Z,S*S DEFB #31 ;zdvojeni Z,S*S,S*S DEFB #0F ;scitani Z,2*S*S DEFB #A1 ;STK-jedna Z,2*S*S,1 DEFB #03 ;odcitani Z,2*S*S-1 DEFB #1B ;negace Z,1-2*S*S=COS(G/A) DEFB #C3 ;ST-MEM-3 COS(G/A) do MEM-3. DEFB #02 ;vymaz Z DEFB #38 ;konec vypoctu POP BC ;Obnov pocet oblouku do B RET ;Konec Subrutina "NARYSUJ PRIMKU" -------------------------- Tento podprogram je volan prikazem DRAW k narysovani aproximace primky vedouci z bodu X0,Y0 (v COORDS) do bodu X0+X,Y0+Y,kde prirustky X a Y jsou ulozeny na vrcholu kalkulatoru.Podstatou teto metody je rozmistit co mozna nejvice horizontalnich nebo vertikalnich kroku mezi zakladni set diagonalnich kroku, s vyuzitim algoritmu,ktery rozmistuje vertikalni kroky co mozna nejrovnnomer- neji. 24B7 CALL #2307 ;ABS Y do B; ABS X do C; LD A,C ;SGN Y do D; SGN X do E; CP B ;Je-li ABS X vetsi nebo rovno ABS Y,skoc JR NC,#24C4 MONITOR ROM - ZX Spectrum - 84 - 24FB RST #18 ;Vyzvedni prvni znak LD B,#00 ;Cislo priority jde na zasobnik PUSH BC 24FF LD C,A ;Hlavni bod opetovneho vstupu LD HL,#2596 CALL #16DC ;Hledej v tabulce funkci,kdy kod je v C LD A,C ;Obnov kode do A JP NC,#2684 ;Skoc,nebylo-li kod nalezeno v tabulce LD B,#00 LD C,(HL) ;Pouzij polozku nalezenou v tabulce k vytvoreni ADD HL,BC ;pozadovane adresy a skoc na tuto adresu JP (HL) Nasleduji ctyri podprogramy,ktere jsou volany rutinami pro tabulku funkci. Prvni z nich s nazvem "scanning quote subrutine" ("testovani uvozovek") je pouzita rutinou S-QUOTE aby zjistila,jestli kazda retezcova uvozovka ma dalsi uvozovku do paru. 250F CALL #0074 ;Ukazuj na dalsi znak INC BC ;Zvys delku o jedna.Je to CR? CP #0D JP Z,#1C8A ;Ohlas chybu,jestlize ano CP #22 ;Existuje dalsi uvozovka? JR NZ,#250F ;Skoc zpet,jestlize ne CALL #0074 ;Ukazuj na dalsi znak a nastav Z flag jestlize CP #22 ;se jedna o dalsi uvozovku RET Dalsi podprogram ktery lze nazvat:"testovani dvou souradnic",je pouzivan programy S-SCREEN,S-ATTR a S-POINT aby se zajistilo,ze pozadovane souradnice budou udany v nalezite forme. 2522 RST #20 CP #28 ;Vyzvedni dalsi znak.Je to zavorka "(" ? JR NZ,#252D ;Ohlas chybu,jestlize ne CALL #1C79 ;Souradnice na zasobnik kalkulatoru RST #18 ;Vyzvedni aktualni znak CP #29 ;Je to zavorka ")" ? 252D JP NZ,#1C8A ;Ohlas chybu,jestlize ne Subrutina "SYNTAX-Z" -------------------- V tomto bode je vlozena subrutina SYNTAX-Z,ktera je z jinych casti programu volana 32 krat.A protoze instrukce BIT 7,(IY+1) ma oporti instrukci CALL o jeden bajt vice,usetri se na kazdem volani teto instrukce jeden bajt.Jedno- duchy test bitu 7 FLAGS nastavi Z flag na nulu pri behu programu a na jednicku pri kontrole syntaxe. 2530 BIT 7,(IY+1) ;Testuj bit 7 FLAGS RET Dalsi subrutina je testovaci podprogram SCREEN$,ktery je pouzivan z rutiny S-SCREEN$ pro nalezeni znaku na souradnicich radek X a sloupec Y obrazovky. Prohledava pouze znaky,na ktere je nastavena systemova promenna CHARS Poznamka: Bezne se jedna o znaky od #20 (mezera) do #7F.Uzivatel vsak muze zmenou systemove promenne CHARS testovat take dalsi znaky (vcetne uzivatelske grafiky). 2535 CALL #2307 ;X do C a Y do B,kde 0<=X<=23 a 0<=Y<=31 dekad. LD HL,(#5C36) ;CHARS+256 dekadicky vytvori v HL bazovou LD DE,#0100 ;adresu znakoveho souboru ADD HL,DE LD A,C ;X je okopirovano do A RRCA ;Cislo 32 dek.+X mod B+Y se formuje v A a je RRCA ;kopirovano do E RRCA AND #E0 ;Toto je nizsi bajt pozavane adresy obrazovky XOR B LD E,A ;X je opet okopirovana do A LD A,C AND #18 ;Nyni je zas dek.64+8*INT (X/8) ulozeno do D XOR #40 LD D,A ;DE nyni obsahuje pozadovanou adresu LD B,#60 ;na obrazovce.B spocita 96 znaku 25AF PUSH BC ;Uschovej pocet.Uschovej ukazatel obrazovky PUSH DE ;a ukazatel na znakovy soubor PUSH HL LD A,(DE) ;Vyzvedni prvni bitovy radek znaku z obrazovky XOR (HL) ;Testuj s radkem ze znakoveho souboru.Byla-li JR Z,#255A ;nalezena prima shoda,skoc INC A ;Nyni testuj shodu s inverznim znakem (z #FF JR NZ,#2573 ;vytvor v A #00).Skoc,nebyla-li ani tato shoda DEC A ;nalezena.Obnov #FF v A 255A LD C,A ;Inverzni status(#00 nebo #FF) do C. B pocita LD B,#07 ;dalsich 7 bitovych radku MONITOR ROM - ZX Spectrum - 86 - 25BE CALL #250F ;zovka neexistuje.Znovu volej pro treti uvo- JR Z,#25BE ;zovku a dale pro patou,sedmou atd.Testujes-li CALL #2530 ;syntaxi,skoc na reset bitu 6 FLAGS a pokracuj JR Z,#25D9 ;v prohledavani RST #30 ;Vytvor misto pro retezec a zaverecnou uvozovku POP HL ;Vyzvedni ukazatel na start a uloz ukazatel PUSH DE ;na prvni misto 25CB LD A,(HL) ;Vyzvedni znak z retezce,posun ukazatel INC HL ;na dalsi.Okopiruj posledni znak do pracovniho LD (DE),A ;prostoru a posun ukazatel na dalsi misto INC DE CP #22 ;Je posledni znak uvozovka?Jestlize ne,skok JR NZ,#25CB ;na prenos dalsi uvozovky.Je-li vsak dalsi LD A,(HL) ;znak take uvozovka,okopiruj az nasledujici INC HL CP #22 ;Jinak ukonci kopirovani JR Z,#25CB 25D9 DEC BC ;Vytvor v BC skutec delku Poznamka: Povsimnete si,ze prvni uvozovka nebyla zapocitana do delky.Koncova uvozovka ale byla a proto je nyni i tato vynechana.Prvni,treti,pata,...uvozovka uvnitr retezce byla pocitana,ale druha,ctvrta,sesta,...pocitany nebyly. POP DE ;Obnov start kopirovaneho retezce 25DB LD HL,#5C3B ;Toto je adesa FLAGS a tento vstupni bod se RES 6,(HL) ;pouziva,kdykoliv ma byt bit 6 FLAGS BIT 7,(HL) ;resetovan a parametry retezce ulozeny na za- CALL NZ,#2AB2 ;sobnik jestlize se provadi radek JP #2712 ;Skok na pokracovani prohledavani radku Poznamka: Povsimnete si,ze pri kopirovani retezcu do pracovniho prostoru kazdy par uvozovek uvnitr retezce ("") byl snizen na jedny uvozovky ("). 25E8 RST #20 ;Pri prohledavane zavorek vyzvedni dalsi znak CALL #24FB ;a vola rekurzivne SCANNING CP #29 ;Nebyla-li nalezena spravna zavorka bude JP NZ,#1C8A ;ohlasena chyba.Jinak se pokracuje RST #20 ;v prohledavani JP #2712 25F5 JP #27BD ;Rutina prohledavani funkci Tato rutina pro uzivatelem definovane funkce pokracuje do rutiny prohledevani funkci. 25F8 CALL #2530 ;Pokud se nekontroluje syntaxe,skoc na vypocet JR Z,#2625 ;nahodneho cisla LD BC,(#5C76) ;Vyzvedni aktualni hodnotu SEED a uloz ji CALL #2D2B ;na zasobnik kalkulatoru RST #28 ;Nyni pouzij kalkulator DEFB #A1 ;stk-jedna Posledni hodnotou je nyni SEED+1 DEFB #0F ;pricteni DEFB #34 ;stk-data Uloz na zasobnik cis. 75 (dekadicky) DEFB #37 ;exponent #87 DEFB #16 ;(#00,#00,#00) DEFB #04 ;nasobeni (SEED+1)*75 DEFB #34 ;stk-data Nyni jsou bajty expandovany,takze DEFB #80 ;(ctyri bajty) na zasobnik jde cislo 65537 DEFB #41 ;exponent #91 DEFB #00 ;#00,#80,(#00) DEFB #32 ;N-mod-M Del (SEED+1)*75 cislem 65537 abys DEFB #02 ;vymaz dosahl "zbytku" a "odpovedi".Vymaz DEFB #A1 ;stk-jedna odpoved.Posledni hodnotou je nyni DEFB #03 ;odecteni zbytek - 1.Zdvoj tuto posledni DEFB #31 ;zdvojeni hodnotu a ukonci vypocet DEFB #38 ;konec vypoctu CALL #2DA2 ;Uzij posledni hodnotu jako novy udaj pro SEED LD (#5C76),BC LD A,(HL) ;Vyzvedni exponent posledni hodnoty a je-li AND A ;nulovy,skoc JR Z,#2625 SUB #10 ;Sniz exponent,coz znamena:vydel hodnotou LD (HL),A ;65536,aby se dosahlo pozadov.rozsahu hodnot 2625 JR #2630 ;Odskoc pres rutinu PI Rutina "hledani PI":nalezne vyraz PI a pokud se nekontroluje syntaxe,ulozi na zasobnik hodnotu PI jako "posledni hodnotu". 2627 CALL #2530 ;Test na kontrolu syntaxe JR Z,#2630 ;Skoc,jestlize kontrolujes syntaxi RST #28 ;Pouzij kalkulator DEFB #A3 ;STK-PI/2 PI/2 je ulozeno na zasobnik kalkulatoru DEFB #38 ;konec jako "posledni hodnota" INC (HL) ;Exponent je inkrementovan cimz se dosahne 2630 RST #20 ;vysledku PI.Presun na dalsi znak JP #26C3 ;Skok dopredu MONITOR ROM - ZX Spectrum - 88 - Ciselny vysledek musi byt identifikovan,kdyz prichazi z RND,PI,ATTR,POINT nebo dekadickeho cisla,nastavenim bitu 6 ve FLAGS. 26C3 SET 6,(IY+1) ;Nastav signal: numericka hodnota JR #26DD ;Skoc Rutina hodnoceni promennych --------------------------- Pri identifikaci nazvu promenne a zavolani LOOK-VARS,kde byla zjistena exis- tence promenne v oblasti promennych nebo v programove oblasti (DEF FN pro uzi- vatelem definovane funkce FN),ulozi se nalezena ciselna hodnota na zasobnik kalkulatoru pomoci rutiny STACK-NUM.Retezcove pole vsak musi byt predano na zasobnik rutinou STK-VARS,nebo pri uzivatelem definovane funkci rutinou STK-F-ARG (ktera je volana z rutiny STK-VARS). 26C9 CALL #28B2 ;V pripade,ze promenna neexistuje,ohlas chybu JP C,#1C2E CALL Z,#2996 ;Jinak uloz parametry retezce a vrat adresu LD A,(#5C3B) ;ciselneho elementu.Vyzvedni FLAGS CP #C0 ;Testuj bit 6 a 7 soucasne,jeden nebo oba jsou JR C,#26DD ;vynulovany INC HL ;Ciselna hodnota musi byt ulozena na zasobnik CALL #33B4 ;Prenes tam cislo 26DD JR #2712 ;Skoc Znak je testovan na "-",cimz se identifikuje "unarni minus".Pred provedenim testu je reg. B nastaven na prioritu #09 a reg. C na hodnotu #D8,coz je kod teto operace. 26DF LD BC,#09DB ;Priorita #09,operacni kod #D8 CP #2D ;Je to "-" ? JR Z,#270D ;Skoc,kdyz ano Nyni se testuje znak na kod VAL$ s prioritou #10 a operacnim kodem #18. LD BC,#1018 ;Priorita #10,operacni kod #18 CP #AE ;Je to VAL$ ? JR Z,270D ;Skoc,kdyz ano Aktualni znak musi nyni predstavovat nekterou z funkci CODE az NOT s kody #AF az #C3. SUB #AF ;Rozsah funkci je zmenen z #AF az #C3 na #00 JP C,#1C8A ;az #14.Ohlas chybu,kdyz jsou oba mimo rozsah Funkce NOT je identifikovana a zpracovana oddelene od ostatnich. LD BC,#04F0 ;Priorita #04,operacni kod #F0 CP #14 ;Je to funkce NOT? JR Z,#270D ;Skoc,jestlize ano JP NC,#1C8A ;Testuj znovu rozsah Zbyvajici funkce maji prioritu 16.Operacni kod pro tyto funkce jsou nyni vypo- citana.Funkce,ktere operuji na retezcich potrebuji mit bit 6 nulovy a funkce, ktere operuji na vysledcich retezcu potrebuji mit bit 7 nulovy ve svych ope- racnich kodech. LD B,#10 ;Priorita 16 ADD A,#DC ;Rozsah je nyni #DC az #EF LD C,A ;Preved operacni kod do C CP #DF ;Oddel VAL a LEN,ktere operuji na vysledcich JR NC,#2707 ;pro dosazeni numerickych hodnot RES 6,C ;Oddel STR$ a CHR$,ktere operuji na cislech 2707 CP #EE ;a davaji retezcove vysledky JR C,#270D ;Poznac operacni kod.Ostatni operacni kody RES 7,C ;maji bit 6 a 7 = 1 Prioritni a operacni kod pro funkci,ktera se prave posuzuje,jsou nyni ulozena na strojovy zasobnik,kde se vytvari urcita posloupnost techto operaci. 270D PUSH BC ;Uloz na zasobnik prioritni a operacni kod, RST #20 ;nez se posunes na posouzeni dalsi casti JP #24FF ;vyrazu Zde pokracuje hodnoceni radku.Aktualni argument muze byt nasledovan "(",binar- nim operatorem,nebo je-li to konec vyrazu,pak znakem CR,oddelovacem nebo THEN. 2712 RST #18 ;Vyzvedni aktualni znak a skoc dopredu,neni-li 2713 CP #28 ;to "(", ktera indikuje vyraz se zavorkami JR NZ,#2723 Jestlize je to ciselna hodnota,potom vyraz v zavorkach je pravdivym podvyrazem a musi byt ohodnocen samostatne.Je-li vsak posledni hodnota retezec,potom vyr- az v zavorkach predstavuje element pole nebo cast retezce.Potom zavolanim sub- rutiny SLICING je tento vyraz upraven tak,jak je potreba. MONITOR ROM - ZX Spectrum - 90 - Kdykoliv je "aktualni operace" s vyssi prioritou,potom posledni a aktualni hodnoty jdou zpatky na zasobnik.Nicmene,kdyz aktualni operace pracuje s retezci,je operacni kod modifikovan,aby se signalizoval tento pozadavek. 2773 PUSH DE ;Posledni hodnoty jdou na zasobnik LD A,C ;Vyzvedni aktualni operacni kod BIT 6,(IY+1) ;(FLAGS) Jedna-li se o ciselny operand, JR NZ,#2790 ;neupravuj tento kod AND #3F ;Nuluj bit 6 a 7 ADD A,#08 ;Zvys kod o #08 a vrat ho v registru C LD C,A CP #10 ;Je to operace AND ? JR NZ,#2788 ;Skoc,jestlize ne SET 6,C ;AND vyzaduje ciselny operand JR #2790 ;Skoc dopredu 2788 JR C,#2761 ;Operace -,*,/,^,OR nelze provadet mezi retezci CP #17 ;Jedna se o "+" ? JR Z,#2790 ;Skoc jestlize ano SET 7,C ;Dalsi operace produkuji ciselny vysledek 2790 PUSH BC ;Aktualni hodnoty jdou na zasobnik RST #20 ;Posuzuj dalsi znak a skoc zpet do smycky JP #24FF TABULKA OPERATORU ----------------- (op.kod=operacni kod) lokace kod op.kod oper. lokace kod op.kod operator 2795 2B CF + 27A3 3C CD < 2797 2D C3 - 27A5 C7 C9 <= 2799 2A C4 * 27A7 C8 CA >= 279B 2F C5 / 27A9 C9 CB <> 279D 5E C6 ^ 27AB C5 C7 OR 279F 3D CE = 27AD C6 C8 AND 27A1 3E CC > 27AF 00 koncovy znak TABULKA PRIORIT --------------- lokace priorita operator lokace priorita operator 27B0 06 - 27B7 05 >= 27B1 08 * 27B8 05 <> 27B2 08 / 27B9 05 > 27B3 0A ^ 27BA 05 < 27B4 02 OR 27BB 05 = 27B5 03 AND 27BC 06 + 27B6 05 <= Subrutina HODNOCENI FUNKCI -------------------------- Tato subrutina je volana z rutiny "vyhodnoceni FN",aby ohodnotila funkce definovane uzivatelem v basickem radku.Podprogram lze rozdelit na ctyri casti: a) Kontrola syntaxe prikazu FN behem kontroly syntaxe b) Pri behu programu se provede hledani prikazu DEF FN v programove oblasti a porovnavaji se jmena funkci dokud se nenalezne shoda.Jinak je ohlasena chyba c) Jsou ohodnoceny argumenty funkce volanim podprogramu SCANNING d) Je ohodnocena samotna funkce (SCANNINGem,ktery zase vola LOOK-VARS a tim i "SF-ARGMTS") 27BD CALL #2530 ;Pokud se nekontroluje syntaxe,skoc na SF-RUN JR NZ,#27F7 RST #20 ;Vyzvedni prvni znak nazvu CALL #2C8D ;Neni-li alfanumericky,ohlas chybu JP NC,#1C8A RST #20 ;Vyzvedni dalsi znak CP #24 ;Je to "$" ? PUSH AF ;Uschovej Z flag na zasobnik a skoc nebyl-li JR NZ,#27D0 ;to "$".Jinak vyzvedni dalsi znak RST #20 27D0 CP #28 ;Nejedna-li se o zavorku,ohlas chybu JR NZ,#27E6 RST #20 ;Vyzvedni dalsi znak CP #29 ;Je to zavorka ")" ? JR Z,#27E9 ;Skoc jestlize ano,nebot nejsou zadne argumenty 27D9 CALL #24FB ;Volej SCANNING,ktery kontroluje syntaxi argu- RST #18 ;mentu a vlozi FP.Vyzvedni znak,ktery nasleduje CP #2C ;za argumentem.Neni-li to carka ",",skoc nebot JR NZ,#27E4 ;nejsou zadne argumenty RST #20 ;Prvni znak dalsiho argumentu JR #27D9 ;Zpatky do smycky k prozkoumani dalsiho argu- 27E4 CP #29 ;mentu.Je soucasny znak zavorka ")" ? 27E6 JP NZ,#1C8A ;Ohlas chybu,neni-li to zavorka ")" MONITOR ROM - ZX Spectrum - 92 - SBC HL,BC ;Zmensi STKEND o 5 a tak vymaz posledni hodnotu LD (#5C65),HL ;ze zasobniku.Okopiruj 5 bajtu do mista LDIR ;v DEF FN.HL ukazuje na dalsi kod EX DE,HL DEC HL ;Zajisti, aby HL ukazovalo na znak nad 5 bajty CALL #28AB CP #29 ;Je to ")" ? Skoc,kdyz ano,nebot nejsou dalsi JR Z,#2885 ;argumenty pro DEF FN PUSH HL ;Je to ",",uschovej tedy jeji ukazatel RST #18 ;Vyzvedni znak za poslednim argumentem prikazu CP #2C ;FN.Neni-li to carka,skoc,nebot jsou to pople- JR NZ,#288B ;tene argumenty pro FN a DEF FN RST #20 ;Posun CH-ADD na dalsi argument FN POP HL ;Vyzvedni ukazatel na "," v prikazu DEF FN CALL #28AB ;Posun HL na dalsi argument v DEF FN JR #2843 ;Skoc k posouzeni tohoto argumentu 2885 PUSH HL ;Uschovej ukazatel na ")" v DEF FN RST #18 ;Vyzvedni znak po poslednim argumentu v FN CP #29 ;Je to ")" ? Kdyz ano,skoc k ohodnoceni JR Z,#288D ;funkce,jinak ohlas: Q - Parameter error 288B RST #08 DEFB #19 d) Konecne je funkce ohodnocena volanim SCANNINGu,kdyz predtim DEFADD obsaho- vala adresu argumentu tak,jak se vyskytovala v prikazu DEF FN.Tim je zajisteno, ze pri zavolani LOOK-VARS budou nejprve prohledany tyto argumenty a pak teprve promenne. 288D POP DE ;Obnov ukazatel na ")" v DEF FN EX DE,HL ;Dej ho do HL a uschovej ho v CH-ADD LD (#5C5D),HL LD HL,(#5C0B) ;Vyzvedni starou hodnotu DEFADD a uloz ji EX (SP),HL ;na zasobnik a soucasne vyzvedni adresu DEF FN LD (#5C0B),HL ;a uloz ji do DEFADD PUSH DE ;Uschovej adresu ")" v prikazu FN RST #20 ;Posun CH-ADD na posledni ")" a "=" na zacatku RST #20 ;vyrazu pro DEF FN CALL #24FB ;Nyni ohodnot funkci POP HL ;Obnov adresu ")" v prikazu FN a uschovej ji LD (#5C5D),HL ;v CH-ADD.Obnov hodnotu DEFADD a uloz ji zpet POP HL LD (#5C0B),HL RST #20 ;Vyzvedni dalsi znak v basickem radku JP #2712 ;Skoc zpet do SCANNINGu Subrutina "FN-SKPOVR" (SKOKY VE FUNKCI) --------------------------------------- Tato subrutina se pouziva z rutin FN a STK-F-ARG,aby posouvala HL po prikazu DEF FN,aniz by byla CH-ADD zmenena,nebot tato ukazuje na prikaz FN. 28AB INC HL ;Ukazuj na dalsi kod v prikazu LD A,(HL) ;Dej ho do A a je-li to ridici znak nebo CP #21 ;mezera,preskoc ho JR C,#28AB RET ;Jinak se vrat Subrutina "PROHLEDEJ PROMENNE" ------------------------------ Tato subrutina se vola kdykoliv je potreba prohledavat oblast promennych,nebo argumentu DEF FN,jak je treba.Vstupuje se do ni se systemovou promennou CH-ADD nastavenou na prvni pismeno nazvu promenne,jejiz umisteni se hleda.Jmeno se bude nachazet v programove nebo pracovni oblasti.Nejprve bude v reg. C vytvo- ren oznacovaci bajt,jehoz povaha je zalozena na prvnim pismenu nazvu promenne. Bity 5 a 6 tohoto bajtu indikuji typ pouzite promenne.Reg. B je pouzivan jako bitova vlajka (flag). 28B2 SET 6,(IY+1) ;(FLAGS) Predpokladej ciselnou promennou RST #18 ;Vyzvedni prvni znak do A CALL #2C8D ;Je to pismeno? Ohlas chybu,jestlize ne JP NC,#1C8A PUSH HL ;Uschovej ukazatel na prvni znak AND #1F ;Preved bity 0-4 do reg. C LD C,A ;Bity 5-7 jsou vzdy nulove RST #20 ;Vyzvedni dalsi znak do A PUSH HL ;Uschovej jeho ukazatel CP #28 ;Je druhym znakem "(" ? JR Z,#28EF ;Oddel pole a cisla SET 6,C ;Nyni nastav bit 6 CP #24 ;Je druhym znakem "$" ? JR Z,#28DE ;Oddel vsechny retezce SET 5,C ;Nyni nastav bit 5 CALL #2C88 ;Jestlize delka nazvu promenne je pouze jeden JR NC,#28E3 ;znak,skoc MONITOR ROM - ZX Spectrum - 94 - A pri kontrole syntaxe skocis sem. 2934 POP DE ;Znic ukazatel na druhy znak RST #18 ;Vyzvedni aktualni znak CP #28 ;Je to zavorka "(" ? JR Z,#2943 ;Skoc,kdyz je SET 5,B ;Signal: nejedna se o pole JR #294B ;Skoc Sem prijdes po nalezeni polozky s odpovidajicim jmenem. 293E POP DE ;Odhod uschovany ukazatel na promennou 293F POP DE ;Znic ukazatel na 2.znak promenne POP DE ;Znic ukazatel na 1.znak promenne PUSH HL ;Uschovej ukazatel na posledni znak nazvu RST #18 ;promenne.Vyzvedni aktualni znak Ma-li jmeno promenne vice nez jeden znak,musi byt prevedeny i dalsi znaky. Poznamka: Zda se,ze to uz bylo udelano v casti V-CHAR. 2943 CALL #2C88 ;Je znak alfanumericky ? JR NC,#294B ;Byl-li nalezen konec nazvu promenne,skoc RST #20 ;Vyzvedni dalsi znak a jdi zpet na jeho test JR #2943 Nyni jsou nastaveny vystupni parametry. 294B POP HL ;HL ukazuje na posledni znak nazvu RL B ;Rotuj cely registr a otestuj jeho bit 6 BIT 6,B RET Vystupni parametry teto subrutiny mohou byt shrnuty nasledovne: Systemova pro- menna CH-ADD ukazuje na prvni misto za nazvem promenne v basickem radku.Pokud promenna nebyla nalezena: a) CY=1 b) Z flag je nastaven pri hledani pole c) Registrovy par HL ukazuje na prvni znak nazvu promenne tak,jak se vyskytuje v basickem radku Pokud promenna byla nalezena: a) CY=0 b) Z flag=1 jak pro jednoduche retezcove promenne,tak pro pole c) Registrovy par HL ukazuje na pismeno kratkeho jmena,nebo na posledni znak u vicepismennych nazvu,existujici polozky v oblasti promennych Ve vsech pripadech bity 5 a 6 registru C indikuji typ zpracovavane promenne. Bit 7 je komplementem "SYNTAX/RUN flag".Bity 0 - 4 budou obsahovat kod znaku nalezene promenne pouze tehdy,byl-li program v behu. Pokud byl podprogram volan pri kontrole syntaxe,bude se vzdy vracet s CY=0. Z flag bude nastaven na 1 pro pole,nebo na 0 pro vsechny promenne krome re- tezcovych nazvu nespravne nasledovanych zavorkou "(",coz nastavi Z flag na jedna,ale v pripade ze se bude provadet SAVE "jmeno" DATA a$(), bude se syntaxe povazovat za spravnou. Subrutina "ULOZ ARGUMENTY FUNKCI NA ZASOBNIK" --------------------------------------------- Subrutina je volana z LOOK-VARS,kdyz neni DEFADD-HI nula,aby v oblasti argu- mentu byl nalezen prikaz DEF FN,pred prohledanim programove oblasti.Byla-li promenna nalezena v prikazu DEF FN,budou parametry retezcove promenne ulozeny na zasobnik a bude dan signal:nevolej STK-VAR.Ale to uz zustava na programu SCANNING,ktery ulozi hodnoty ciselne promenne obvyklym zpusobem (viz adresa #26DA). 2951 LD HL,(#5C0B) ;Ukazuj na prvni znak oblasti argumentu LD A,(HL) ;a preved jej do A CP #29 ;Je to zavorka ")" ? Skoc k prohledani oblasti JP Z,#28EF ;promennych,jestlize ano.Vyzvedni dalsi argu- 295A LD A,(HL) ;ment ve smycce.Nastav bity 5 a 6 jako signal: OR #60 ;obycejna ciselna promenna LD B,A ;Okopiruj je do B INC HL ;Ukazuj na dalsi kod LD A,(HL) ;Vyzvedni jej do A CP #0E ;Je to #0E (zn.FP cisla) ? JR Z,#296B ;Jestlize ano,skoc(je to ciselna promenna) DEC HL ;Nastav HL aby ukazovalo na znacku "$" CALL #28AB ;a ne na mezeru nebo ridici znak INC HL ;HL nyni ukazuje na znacku FP cisla RES 5,B ;Nuluj bit 5 v B coz je signal:retezcova pro- 296B LD A,B ;menna.Vyzvedni nazev promenne do A CP C ;Je to ta,kterou hledame? JR Z,#2981 ;Jestli ano,skoc INC HL ;Nyni prekroc pet bajtu FP cisla nebo parametru INC HL ;retezce,aby mohl byt nalezen dalsi parametr INC HL INC HL INC HL MONITOR ROM - ZX Spectrum - 96 - Pro retezcove pole muze jiz tento index znamenat "rez",anebo je jeste dale v basickem radku. 29D8 CP #29 ;Je aktualni znak zavorka ")" ? JR Z,#2A48 ;Jestlize ano,skoc na kontrolu dalsiho indexu CP #CC ;Je aktualni znak TO ? JR NZ,#2A12 ;Ne-li,skoc ohlasit chybu 29E0 RST #18 ;Vyzvedni aktualni znak DEC HL ;Ukazuj na predchozi znak a nastav CH-ADD LD (#5C5D),HL JR #2A45 ;Skoc na hodnoceni "rezu" 29E7 LD HL,#0000 ;Zde je vstup do smycky.Nastav citac elementu 29EA PUSH HL ;na nulu.Kratce jej uschovej RST #20 ;Vyzvedni dalsi znak POP HL ;Obnov citac LD A,C ;Vyzvedni rozlisovaci bajt CP #C0 ;Pokud nekontrolujes syntaxi,skoc JR NZ,#29FB RST #18 ;Vyzvedni aktualni znak CP #29 ;Je aktualni znak zavorka ")" ? JR Z,#2A48 ;Citani elementu skonceno - skoc dopredu CP #CC ;Je aktualni znak TO ? JR Z,#29E0 ;Skoc zpet - jde o "rez" 29FB PUSH BC ;Uschovej pocet dimenzi a rozlisovaci bajt PUSH HL ;Uschovej citac elementu CALL #2AEE ;Vyzvedni velikost dimenze do DE EX (SP),HL ;Citac do HL a ukazatel na zasobnik EX DE,HL ;Zamena.Ohodnot dalsi index CALL #2ACC ;Je-li mimo rozsah,ohlas chybu.Dekrementuj JR C,#2A20 ;vysledek ohodnoceni,protoze citac ma pocitat DEC BC ;elementy vyskytujici se pred specifikovanym CALL #2AF4 ;elementem.Vynasob citac celikosti dimenze ADD HL,BC ;Pricti vysledek z INT-EXP1 k aktualnimu POP DE ;citaci.Vyzvedni ukazatel promenne POP BC ;Vyzvedni pocet dimenzi a rozlisovaci bajt DJNZ #29C3 ;Pokracuj v pruchodech smyckou dokud B=0 Nez se odlisi ciselna a retezcova pole,testuje se vlajka SYNTAX/RUN. BIT 7,C ;Kontrolujes-li syntaxi,skoc ohlasit chybu 2A12 JR NZ,#2A7A PUSH HL ;Uschovej citac BIT 6,C ;Jedna-li se o retezcova pole,skoc JR NZ,#2A2C Pri zpracovani retezcoveho pole musi byt aktualni znak zavorka ")". LD B,D ;Preved ukazatel promenne do BC LD C,E RST #18 ;Vyzvedni dalsi znak CP #29 ;Je aktualni znak zavorka ")" ? JR Z,2A22 ;Preskoc chybove hlaseni,jestlize ano 2A20 RST #08 ;Ohlas:Subscript out of range DEFB #02 Nyni muze byt vypoctena adresa skutecne FP formy. 2A22 RST #20 ;Vyzvedni dalsi znak POP HL ;Vyzvedni citac LD DE,#0005 ;Ciselny element ma delku 5 bajtu CALL #2AF4 ;Vypocti celkovy pocet bajtu pred pozadovanym ADD HL,BC ;elementem.HL nyni ukazuje pred pozadovany RET ;element.Vrat se s touto adresou Pri zpracovani retezcoveho pole je velikost elementu dana hodnotou "posledni dimenze".Jsou vypocteny prislusne parametry a predany na zasobnik kalkulatoru. 2A2C CALL #2AEE ;Vyzvedni rozmer posledni dimenze.Ukazatel EX (SP),HL ;promenne jde na zasobnik a citac do HL CALL #2AF4 ;Vynasob citac velikoti dimenze.Vyzvedni POP BC ;ukazatel promenne ADD HL,BC ;HL nyni ukazuje na jedno misto pred elmentem INC HL ;A nyni na zacatek elementu.Preved velikost LD B,D ;posledni dimenze do BC,coz bude delka LD C,E EX DE,HL ;Zacatek do DE CALL #2AB1 ;Parametry na zasobnik kalkulatoru Poznamka: Prvni parametr je nula,coz indikuje element pole a tedy signal: nemazat existujici element.Zapis indexu je mozny tremi zpusoby: A$(2,4 TO 8) nebo A$(2),(4 TO 8) anebo pokud se pozaduje cely retezec A$(2). RST #18 ;Vyzvedni aktualni znak CP #29 ;Je to zavorka ")" ? JR Z,#2A48 ;Skoc,jestlize ano CP #2C ;Je to carka "," ? JR NZ,#2A20 ;Skoc na ohlaseni chyby,jestlize ne MONITOR ROM - ZX Spectrum - 98 - Podprogram "STK-STORE" ---------------------- Tento podprogram predava hodnoty v registrech A B C D E na zasobnik kalkulato- ru.S kazdym zavolanim tohoto podprogramu se tedy zasobnik zvetsi o 5 bajtu. Podprogram se normalne pouziva k predani retezcovych parametru,ale je i vyuzi- van rutinami STACK-BC a LOG(2^A) k ukladani "malych integru" na zasobnik kal- kulatoru.Vsimnete si,ze pri ukladani parametru retezce prvni hodnota (prichazi v registru A),bude nulova jestlize retezec je soucasti pole nebo je rezem ne- jakeho delsiho retezce.Pro kompletni jednoduchy retezec bude hodnota #01.Tato vlajka se pouziva v prikazu LET,kde #01 signalizuje,ze stara kopie ma byt zni- cena. 2AB1 XOR A ;Signal:retezec jako cast pole nebo jeho rez 2AB2 RES 6,(IY+1) ;(FLAGS) Zajisti,ze vlajka indikuje retezcovy 2AB6 PUSH BC ;vysledek.Uschovej kratce BC CALL #33A9 ;Je zde misto pro pet bajtu? Nevracej se pokud POP BC ;zde neni toto misto.Obnov BC LD HL,(#5C65) ;Vyzvedni adresu 1.mista nad aktualnim LD (HL),A ;zasobnikem.Preved 1.bajt INC HL ;Postup LD (HL),E ;Preved 2.a 3.bajt,coz je u retezcu start INC HL LD (HL),D INC HL ;Postup LD (HL),C ;Preved 4.a 5.bajt,coz je u retezcu delka INC HL LD (HL),B ;Posun ukazatel tak,aby ukazoval nad zasobnik INC HL LD (#5C65),HL ;Uloz tuto adresu do STKEND a vrat se RET Subrutina "INT-EXP" ------------------- Tato subrutina vraci vysledek ohodnoceni "dalsiho vyrazu",jako napriklad hod- notu integer v registrovem paru BC.Take testuje vysledek proti limitujicim hodnotam predavanym v registrovem paru HL.CY se bude rovnat jedne jestlize doslo k chybe "out of range" (mimo rozsah).Registr A se pouziva jako "chybovy registr".Obsahuje #00 nedoslo-li k chybe a #FF doslo-li k chybe. 2ACC XOR A ;Nuluj chybovy registr 2ACD PUSH DE ;Uschovej registry DE,HL a take chybovy registr PUSH HL PUSH AF CALL #1C82 ;Hodnota dalsiho vyrazu je prenesena na zasob- POP AF ;nik kalkulatoru.Obnov chybovy registr CALL #2530 ;Pri kontrole syntaxe,skoc dopredu JR Z,#2AEB PUSH AF ;Uschovej opet chybovy registr CALL #1E99 ;Posledni hodnota je kompresovana do BC POP DE ;Chybovy registr do D LD A,B ;Dalsi vyraz,ktery dava nulu je vzdy chybovy OR C ;takze je-li tomu tak,skoc SCF JR Z,#2AE8 POP HL ;Udelej kopii limitu.Toto bude rozmer,limit PUSH HL ;pro DIM nebo delsi retezce AND A ;Nyni porovnej vysledek oproti tomuto limitu SBC HL,BC Stav CY a hodnota v registru jsou nyni manipulovany tak,aby daly prislusnou hodnotu pro chybovy registr. 2AE8 LD A,D ;Vyzvedni hodnotu "stare" chyby,vytvor "novou" SBC A,#00 ;chybu.#00 znamena,ze nedoslo k chybe.#FF nebo 2AEB POP HL ;mene je mimo rozsah.Obnov registry pred POP DE ;stry pred navratem.Chybovy registr je reg. A RET Subrutina DE,(DE+1) ------------------- Tato subrutina provadi pseudoinstrukci LD DE,(DE+1) a vraci HL jako ukazatel na misto adresovane hodnotou (DE+2). 2AEE EX DE,HL ;Pouzij HL pro konstrukci INC HL ;Ukazuj na "DE+1" LD E,(HL) ;Ve skutecnosti LD E,(DE+1) INC HL ;Ukazuj na "DE+2" LD D,(HL) ;Ve skutecnosti LD D,(DE+2) RET MONITOR ROM - ZX Spectrum - 100 - Znaky navic dlouheho nazvu jsou predany do oblasti promennych. 2B3E INC HL ;Ukazuj na kazdy znak "navic" LD A,(HL) ;Vyzvedni jej CP #21 ;Akceptuj znaky od #21 do #FF a ignoruj znaky JR C,#2B3E ;od #00 do #20 OR #20 INC DE ;Prevadej znaky postupne od druheho noveho LD (DE),A ;bajtu dale.Pokracuj znovu do smycky pro DJNZ #2B3E ;vsechny znaky"navic" Posledni znak dlouheho nazvu musi byt ORovan hodnotou #80. OR #80 ;Oznac znak jak je treba a prepis posledni kod LD (DE),A Prvni znak nazvu zpracovavane promenne je posouzen. LD A,#C0 ;Priprav se na oznaceni "dlouhy nazev" 2B4F LD HL,(#5C4D) ;Vyzvedni ukazatel na znak XOR (HL) ;A obsahuje #00 pro kratky nazev a #C0 pro OR #20 ;dlouhy nazev.Nastav bit 5 pro mala pismena POP HL ;Nyni odhod ukazatel Podprogram L-FIRST je nyni volan pro vlozeni "pismene" na prislusne misto. CALL #2BEA ;Vloz "pismeno".HL ukazuje na novy #80kovy bajt Posledni hodnota muze byt nyni prevedena do oblasti promennych.Vsimnete si,ze v tomto bode HL vzdy ukazuje na pozici za peti bajty,ktere jsou prideleny to- muto cislu.Instrukce RST #28 je pouzita k zavolani kalkulatoru a posledni hodnota je pak "vymazana",ale neprepsana. 2B59 PUSH HL ;Uschovej cilovy ukazatel RST #28 ;Kalkulator DEFB #02 ;vymaz Takto je posunut STKEND zpet o 5 bajtu DEFB #38 ;konec POP HL ;Obnov ukazatel LD BC,#0005 ;Necht cislo je dlouhe 5 bajtu AND A SBC HL,BC ;HL ukazuje na prvni z peti lokaci JR #2BA6 ;Skoc dopredu k provedeni skutecneho prevedeni Pri zjisteni,ze promenna jiz existuje,vstup do tohoto bodu.Nejprve otestuj bit 6 ve FLAGS,abys oddelil ciselne promenne od retezcovych nebo retezcova pole. 2B66 BIT 6,(IY+1) ;(FLAGS) Pri zpracovavani jakehokoliv druhu JR Z,#2B72 ;retezcove promenne skoc dopredu Pro ciselne promenne "nove" cislo prepise "stare" cislo.Takze HL musi ukazovat na misto za pet bajtu existujici polozky.Nyni ovsem HL ukazuje na misto pred temito peti bajty. LD DE,#0006 ;Pet bajtu pro cislo + jeden pro znak FP cisla ADD HL,DE ;Nyni HL ukazuje na misto "za" JR #2B59 ;Skoc dopredu k provedeni skutecneho prevedeni Parametry retezcove promenne jsou vyzvednuty a kompletni jednoduche retezce jsou oddeleny od kracenych retezcu a poli. 2B72 LD HL,(#5C4D) ;Vyzvedni start.Pozn.:tento radek je zbytecny LD BC,(#5C72) ;Vyzvedni delku.Pri zpracovani kompletniho BIT 0,(IY+55) ;(FLAGX) obycejneho retezce,skoc.Stary retezec JR NZ,#2BAF ;bude potreba vymazat pouze v tomto pripade Pri zpracovani rezu existujici retezcove promenne,nebo rezu nebo kompletni casti retezcoveho pole,prochazi program dvema fazemi.Nejprve se v pracovnim prostoru musi vytvorit novy retezec,ktery je podle potreby zkracen nebo pro- dlouzen a ve druhe fazi je pak tento retezec okopirovan na sve misto v oblasti promennych.Ovsem,pokud ma retezec nulovou delku,nedeje se nic. LD A,B ;Jedna-li se o nulovy retezec,vrat se.Jinak OR C ;vytvor pozadovany pocet mist v pracovnim RET Z ;prostoru PUSH HL ;Uschovej start (DEST) RST #30 ;Vytvor potrebne misto v pracovnim prostoru PUSH DE ;Uschovej ukazatel na prvni misto PUSH BC ;Uschovej delku pro pozdejsi pouziti LD D,H ;DE ukazuje na posledni misto LD E,L ;a HL ukazuje o bajt dale INC HL LD (HL),#20 ;Je vlozen kod mezery a po jeho okopirovani LDDR ;do vsech pozic ukazuje HL na prvni novy znak MONITOR ROM - ZX Spectrum - 102 - Subrutina "L-STRING" -------------------- Parametry noveho retezce jsou vyzvednuty.Pak se vytvori potrebny prostor a retezec je prenesen. 2BC6 PUSH AF ;Uschovej znak nazvu promenne CALL #2BF1 ;Vyzvedni start a delku noveho retezce EX DE,HL ;Preved start do HL ADD HL,BC ;HL at ukazuje jedno misto za retezec PUSH BC ;Uschovej delku DEC HL ;HL ukazuje na konec retezce LD (#5C4D),HL ;Kratce uschovej ukazatel DEST INC BC ;Pridej jeden bajt pro pismeno a dva bajty INC BC ;pro delku INC BC LD HL,(#5C59) ;HL ukazuje na #80-kovy bajt konce promennych DEC HL CALL #1655 ;Nyni vytvo prostor v oblasti promennych Poznamka:Ve skutecnosti je #80-kovy bajt posunut (s nim vsechny dulezite uka- zatele) tak,ze vznikne BC mist. LD HL,(#5C4D) ;Obnov ukazatel na konec noveho retezce POP BC ;Preved kopii delky retezce PUSH BC ;;Pridej jednu na delku,i v pripade,ze novy INC BC ;retezec ma delku 0 LDDR ;Pak kopiruj novy retezec plus jeden bajt EX DE,HL ;HL at ukazuje na vyssi bajt delky INC HL POP BC ;Vyzvedni delku LD (HL),B ;Vloz jeji vyssi a pak nizsi bajt DEC HL LD (HL),C ;Vyzvedni znak nazvu promenne POP AF Subrutina "L-FIRST" ------------------- Do tohoto podprogramu se vstupuje s jiz patricne oznacenym pismenem nazvu promenne v reg. A.Tento znak prepise stary #80-kovy bajt v oblasti promennych. Pri vystupu z tohoto podprogramu je registrovy par HL nastaven na novy #80-kovy bajt. 2BEA DEC HL ;At HL ukazuje na stary #80-kovy bajt LD (HL),A ;Uloz tam pismeno nazvu promenne LD HL,(#5C59) ;Necht HL ukazuje na novy #80-kovy bajt DEC HL RET ;Skonceno s nove deklarovanou promennou Subrutina "STK-FETCH" --------------------- Tento dulezity podprogram vyzvedne posledni hodnotu ze zasobniku kalkulatoru. Techto pet bajtu vyjadruje bud FP formu,"kratkou" nebo "dlouhou" formu,nebo to mohou byt parametry retezce. 2BF1 LD HL,(#5C65) ;Vyzvedni STKEND DEC HL ;Zpet o jedno misto LD B,(HL) ;5.hodnota DEC HL ;Zpet o jedno misto LD C,(HL) ;4.hodnota DEC HL ;Zpet o jedno misto LD D,(HL) ;3.hodnota DEC HL ;Zpet o jedno misto LD E,(HL) ;2.hodnota DEC HL ;Zpet o jedno misto LD A,(HL) ;1.hodnota LD (#5C65),HL ;Obnov hodnotu STKEND na novou hodnotu RET Rutina prikazu DIM ------------------ Tato rutina vytvari nova pole v oblasti promennych.Rutina zacina vyhledanim existujici promenne v oblasti promennych,aby se zjistilo,zda pole s timto nazvem jiz existuje a pripadne bylo toto pole zniceno pred vytvorenim pole noveho.Nove ciselne pole bude mit vsechny prvky nastaveny na nulu a nove re- tezcove pole bude vyplneno mezerami. 2C02 CALL #28B2 ;Prohledej oblast promennych 2C05 JP NZ,#1C8A ;Ohlas chybu C,pokud se nejedna o pole CALL #2530 JR NZ,#2C15 ;Pri behu programu skoc dopredu RES 6,C ;Testuj syntaxi ciselnych i retezcovych poli CALL #2996 ;Kontroluj syntaxi vyrazu v zavorkach a posu- CALL #1BEE ;zuj dalsi vyrazy,protoze syntaxe je v poradku MONITOR ROM - ZX Spectrum - 104 - LD (HL),#20 2C70 POP BC ;Vyzvedni celkovy pocet bajtu pole LDDR ;Vycisti pole + jedno misto navic 2C7F POP BC ;Nyni jsou vlozeny velikosti rozmeru.Vyzvedni LD (HL),B ;velikost rozmeru.Vloz vyssi a nizsi bajt DEC HL LD (HL),C DEC HL DEC A ;Dekrementuj citac dimenzi a opakuj operaci, JR NZ,#2C7F ;dokud nebyly posouzeny vsechny operace RET ;Jinak se vrat Subrutina "ALFANUNUM" --------------------- Je-li v registru A ulozen znak platne cislice nebo pismene,vraci tento podprogram CY flag nastaven na hodnotu jedna. 2C88 CALL #2D1B ;Test na cislici CCF ;CY bude jedna pro platnou cislici a v tom RET C ;pripade se vrat Subrutina "ALFA" ---------------- Je-li v registru A ulozen znak platneho pismene,vraci tento podprogram CY flag nastaven na hodnotu jedna. 2C8D CP #41 ;Testuj oproti #41 coz je kod pro pismeno "A" CCF ;Komplementuj CY a vrat se,nebyl-li to platny RET NC ;kod znaku.Testuj oproti #5B,coz je o jednu CP #5B ;vice nez kod pismene "Z" RET C ;Vrat se,jestlize se jedna o znak CP #61 ;Testuj oproti #61,coz je kod pro pismeno "a" CCF ;Komplementuj CY a vrat se,nebyl-li to platny RET NC ;kod znaku CP #7B ;Testuj oproti #7B,coz je o jednu vice nez kod RET ;pismene "z" Subrutina "DECIMAL TO FLOATING POINT" ------------------------------------- Soucasti kontroly syntaxe je prevadeni dekadickych cisel ulozenych v basickem radku na floating point formu.Tento podprogram nacte dekadicke cislo (cislici za cislici) a vysledek zpracovani ulozi na zasobnik kalkulatoru.Nejdrive je vsak obslouzen pripadny vyskyt prikazu BIN,ktery je nasledovan serii jednicek a nul. 2C9B CP #C4 ;Jedna se o znak BIN ? JR NZ,#2CB8 ;Jestlize ne,skoc LD DE,#0000 ;Nastav hodnotu vysledku na hodnotu 0 2CA2 RST #20 ;Vyzvedni dalsi znak SUB #31 ;Odecti znakovy kod pro jednicku ADC A,#00 ;Nula nyni dava nulu a CY dava jednicku JR NZ,#2CB3 ;Jakykoli jiny znak vyvola skok na BIN-END EX DE,HL ;a zkontroluje se znovu syntaxe.Vysledek do HL CCF ;Komplementuj CY ADC HL,HL ;Posun vysledek doleva s nactenim CY do bitu 0 JP C,#31AD ;Ohlas preteceni,je-li vysledek vetsi nez 65535 EX DE,HL ;Vrat vysledek do DE JR #2CA2 ;Skoc zpet na dalsi nulu nebo jednicku.Okopi- 2CB3 LD B,D ;ruj vysledek do BC pro ulozeni na zasobnik LD C,E JP #2D2B Pro ostatni cisla se nejdrive prevede cela cast a jestlize je dalsi znak deka- dicky,posoudi se i zlomkova cast. 2CB8 CP #2E ;Je prvni znak "." ? JR Z,#2CCB ;Jestlize ano,skoc CALL #2D3B ;Vytvor posledni hodnotu jako typ integer CP #2E ;Je dalsi znak "." ? JR NZ,#2CEB ;Jestlize ano,skoc nebot to muze byt exponent RST #20 ;Vyzvedni dalsi znak CALL #2D1B ;Jestlize to neni cislice,skoc (napr. 1.E4 je JR C,#2CEB ;povoleno) JR #2CD5 ;Skoc dopredu na obsluhu cislic za desetinnou 2CCB RST #20 ;teckou.Jestize cislo zacinalo desetinnou CALL #2D1B ;teckou,podivej se zda je nasledujici znak 2CCF JP C,#1C8A ;cislice.Neni-li tomu tak,ohlas chybu RST #28 ;Kalkulator uloz nulu jako celou cast techto cisel DEFB #A0 ;STK-nula DEFB #38 ;konec vypoctu 2CD5 RST #28 ;Kalkulator DEFB #A1 ;STK-jedna Nalezni FP formu dekadickeho cisla DEFB #C0 ;STK-MEM-0 jedna a uschovej ji v pametove DEFB #02 ;vymaz oblasti cislo nula DEFB #38 ;konec vypoctu MONITOR ROM - ZX Spectrum - 106 - CALL #2AB6 ;Nyni uloz cislo RST #28 ;HL necht ukazuje na STKEND-5 DEFB #38 ;konec vypoctu AND A ;Vynuluj CY flag RET Subrutina "INTEGER TO FLOATING POINT" ------------------------------------- Tato rutina prevede cislo z basickeho radku,tedy celou cast dekadickeho cisla nebo cisla radku,na zasobnik kalkulatoru jako posledni hodnotu v FP tvaru. Opakovane volani na CH-ADD+1 vyzvedne postupne vsechny cislice celociselne casti.Vystup se provede v pripade nalezeni nenumerickeho znaku. 2D3B PUSH AF ;Uschovej prvni cislici v A RST #28 ;Kalkulator DEFB #A0 ;STK-nula Posledni hodnota je nyni nula DEFB #38 ;konec vypoctu POP AF ;Obnov puvodni cislici Nyni se vstupuje do smycky.Predstavuje-li kod cislici,nalezne se jeji FP forma a ulozi se pod posledni polozku.Ta je potom vynasobena deseti a prictena k cislici,aby byla vytvorena nova posledni hodnota a ta pak prenesena opet na zacatek smycky. 2D40 CALL #2D22 ;Predstavuje-li kod cislici,uloz jeji FP formu RET C ;na zasobnik kalkulatoru.Jinak se vrat RST #28 ;Kalkulator Cislice jde pod posledni DEFB #01 ;zamena hodnotu.Je ulozeno cislo 10.Posledni DEFB #A4 ;STK-deset hodnota = posledni hodnota * 10 DEFB #04 ;nasobeni Posledni hodnota = posledni hodnota + DEFB #0F ;scitani + cislice DEFB #38 ;konec vypoctu CALL #0074 ;Dalsi znak jde do A JR #2D40 ;Skok zpet do smycky s timto znakem ARITMETICKE RUTINY ****************** E-FORMAT TO FLOATING POINT FORMAT --------------------------------- Doplnek: #3C "E-TO-FP" Tento podprogram prevadi cislo zapsane ve tvaru xEm,kde m je kladne nebo za- porne cele cislo,na zasobnik kalkulatoru tak,ze hodnota x je posledni hodnotou a hodnota m je v registru A.Metoda pouzivana k nalezeni absolutni hodnoty m, rekneme cisla p,je dana delenim nebo nasobenim cisla x hodnotou 10^p podle to- ho,je-li m kladne nebo zaporne.Pro dosazeni tohoto vysledku se postupuje na- sledovne: p je posouvano doprava dokud neni nulove a x je nasobeno nebo deleno hodnotou 10^(2^n) pro kazdy nastaveny bit hodnoty p.Jelikoz p nikdy nepresahne hodnotu vetsi nez 39,budou bity 6 a 7 hodnoty p normalne nulove. 2D4F RLCA ;Testuj znamenko m rotacemi bitu 7 do CY RRCA ;a zpet aniz by doslo ke zmene A JR NC,#2D55 ;Je-li m pozitivni,skoc CPL ;Neguj m v registru A bez poruseni CY INC A 2D55 PUSH AF ;Uscovej kratce registr A LD HL,#5C92 ;Adresa MEMBOT CALL #350B ;Znamenkovy bajt je nyni ulozen v 1.bajtu RST #28 ;MEM-0,#00~+,#01~-.Na zasobniku je hodnota x DEFB #A4 ;STK-deset x,10 DEFB #38 ;konec vypoctu x,10 POP AF ;Obnov m v registru A 2D60 SRL A ;Ve smycce posunuj dalsi bit m,ktery nastavi CY a Z JR NC ;jak treba.Je-li CY=0,skoc.Uschovej zbytek m a vlajky PUSH AF ;(flags).Na zasobniku je nyni x' coz je prechodna faze RST #28 ;nasobeni x*(10^m) a 10^(2^n),kde n=0,1,2,3,4,nebo 5 DEFB #C1 ;ST-MEM-1 10^(2^n) do MEM-1 DEFB #E0 ;GET-MEM-0 x',10^(2^n),(1/0) DEFB #00 ;skoc-pravda x',10^(2^n) DEFB #04 ;na E-DIVISN x',10^(2^n) DEFB #04 ;nasobeni x'*10^(2^n)=x'' DEFB #33 ;skoc x'' DEFB #02 ;na E-FETCH x'' 2D6D DEFB #05 ;deleni x'/10^(2^n)=x''(=x'*10^(2^n) nebo ; x'/10^(2^n) podle znamenka m 2D6E DEFB #E1 ;GET-MEM-1 x'',10^(2^n) DEFB #38 ;konec vypoctu x'',10^(2^n) POP AF ;Obnov zbytek m v reg. A a podminkove vlajky 2D71 JR Z,#2D7B ;Skoc,bylo-li m snizeno na nulu PUSH AF ;Uschovej zbytek m v registru A RST #28 ; x'',10^(2^n) DEFB #31 ;zdvojeni x'',10^(2^n),10^(2^n) DEFB #04 ;nasobeni x'',10^(2^(n+1)) DEFB #38 ;konec vypoctu x'',10^(2^(n+1)) POP AF ;Obnov zbytek m v reg. A JR #2D60 ;Skoc zpet pro vsechny bity hodnoty m MONITOR ROM - ZX Spectrum - 108 - EX DE,HL ;HL nyni ukazuje na cislo LD B,(HL) ;Kopiruj prvni bajt do B CALL #2D7F ;Kopiruj bajty 2,3 a 4 do C,D a E XOR A ;Vynuluj A SUB B ;CY je 0,pokud B je ruzne od nuly.Z je 1,pokud BIT 7,C ;je cislo kladne LD B,D ;Vyssi bajt do B LD C,E ;Nizsi bajt do C a do A LD A,E POP DE ;Obnov ukazatele POP HL RET Subrutina "LOG(2^A)" -------------------- Tento podprogram se vola z podprogramu PRINT-FP aby vypocital priblizny pocet cislic pred desetinnou teckou pro x (cislo,ktere ma byt vytisteno).Nejsou-li pred desetinnou teckou zadne cislice spocte priblizny pocet uvodnich nul za desetinnou teckou.Do podprogramu se vstupuje s cislem e' v registru A,coz je pravy exponent x,nebo e'-2 a pocita se z=LOG pri zakladu 10 z hodnoty (2^A). A se pak nastavi na hodnotu ABS INT (Z+0.5) jak je pozadovano.Pro tento ucel se pouzije FP-TO-A. 2DC1 LD D,A ;Hodnota A je ulozena ve tvaru: 00 00 A 00 00 RLA ;pro kladne A,nebo 00 FF A FF 00 pro zaporne A SBC A,A LD E,A ;Tyto bajty jsou nejprve ulozeny do A,E,D,C,B LD C,A ;a pozdeji na zasobnik kalkulatoru XOR A LD B,A CALL #2AB6 RST #28 ;Kalkulator DEFB #34 ;STK-data LOG 2 je nyni ulozen na zasobnik DEFB #EF ;exponent #7F DEFB #1A,#20,#9A,#85 Zasobnik obsahuje A a LOG 2*A*LOG 2, DEFB #04 ;nasobeni neboli LOG(2^A) DEFB #27 ;int INT LOG (2^A).Podprogram pokracuje DEFB #38 ;konec vypoctu do FP-TO-A k dokonceni vypoctu Subrutina "FLOATING POINT TO A" ------------------------------- Tento kratky,ale velice dulezity podprogram je volan v osmi pripadech pro ruz- ne ucely.Pouziva mimo jine,FP-TO-BC k prevedeni posledni hodnoty do registru A kdykoliv je to mozne.Proto take testuje velikost cisla a jestlize je toto cis- lo vetsi nez 255 je nastaven CY na hodnotu logicke jednicky.Jinak se vraci mo- dulo cisla zaokrouhlene na nejblizsi hodnotu v registru A.Z flag se pouziva k rozliseni kladneho nebo zaporneho cisla. 2DD5 CALL #2DA2 ;Kompresuj posledni hodnotu do BC RET C ;Bylo-li to mimo rozsah,vrat se PUSH AF ;Uschovej vysledek podminkovych vlajek DEC B ;a opet je chyba,neni-li v registru B nula INC B JR Z,#2DE1 ;Skoc,je-li vse OK POP AF ;Vyzvedni vysledek podminkovych vlajek SCF ;Signal,ze vysledek je mimo rozsah RET ;Konec-neuspesne 2DE1 POP AF ;Vyzvedni vysledek podminkovych vlajek RET ;Konec-uspesne Subrutina "VYPSANI FP CISLA" ---------------------------- Tento podprogram se vola rutinou prikazu PRINT na adrese #2039 a STR$ na adre- se #3630,ktere prevadeji cislo na retezec tak,jako kdyby byl vypsan.Tento pod- program vytiskne x,ktere je ulozeno jako posledni hodnota na zasobniku kalku- latoru.Tiskovy format nikdy nezabere vice nez ctrnact mist.Osm nejvyznamnejsich cislic x spravne zaokrouhlenych je uschovano v tiskovem bafru vytvorenem spe- cialne pro tento ucel v pametech zasobnikove pameti MEM-3 a MEM-4.Mala cisla numericky mensi nez jedna a cisla vetsi nez 2^27 jsou zpracovana samostatne. Mensi jsou nasobena hodnotou 10^n,kde n je priblizny pocet uvodnich nul za de- setinnou carkou zatimco vetsi cisla jsou delena hodnotou 10^(n-7),kde n je pri- blizny pocet cislic pred desetinnou carkou.Timto se vsechna cisla dostavaji do stredniho rozsahu a pocet cislic pozadovanych pred desetinnou carkou je ulozen v druhem bajtu pameti MEM-5.Nakonec je vse vytisknuto s pouzitim E-for- matu,jestlize bylo vice nez osm cislic pred desetinnou teckou nebo vice nez ctyri nuly za desetinnou teckou.Nasledujici basicky program ukazuje rozsah tiskovych formatu: 10 FOR a=-11 TO 12:PRINT SGN a*9^a:NEXT a a) Nejprve je osetreno znamenko cisla x:Je-li zaporne,podprogram skoci na PF-NEGATIVE,kde se pred hodnotu ABS x vytiskne znamenko minus.Je-li x nula, je vymazano ze zasobniku kalkulatoru,je vytistena nula a proveden navrat z podprogramu.Je-li x kladne,podprogram prave pokracuje. MONITOR ROM - ZX Spectrum - 110 - LD A,D CALL #2D4F ;Na zasobnik je ulozena hodnota y=f*10^n RST #28 ; i,y DEFB #31 ;zdvojeni i,y,y DEFB #27 ;int i,y,INT(y=i2) DEFB #C1 ;ST-MEM-1 i2 do MEM-1 DEFB #03 ;odecet i,y-i2 DEFB #E1 ;GET-MEM-1 i,y-i2,i2 DEFB #38 ;konec vypoctu i,f2,i2 (f2=y-i2) CALL #2DD5 ;i2 je prevedeno ze zasobniku do A PUSH HL ;Ukazatel na f2 je uschovan LD (#5CA1),A ;i2 je uschovano v prvnim bajtu MEM-3.Tedy DEC A ;cislice pro tisk.Ovsem je-li i2 nula,nebude RLA ;se pocitat jako cislice pro tisk.A je manipu- SBC A,A ;lovano tak,ze nula zpusobi nulu,ale nenulova INC A ;hodnota zpusobi jednicku LD HL,#5CAB ;Toto je 1.bajt MEM-5,kam je vlozena hodnota LD (HL),A ;nula nebo jedna (tedy pocet cislic pro tisk) INC HL ;a prictena k druhemu bajtu MEM-5,coz je ADD A,(HL) ;pocet cislic pred desetinnou carkou LD (HL),A ;Ukazatel na f2 je obnoven POP HL ;Skok na umisteni f2 do bafru (HL ukazuje JP #2ECF ;na f2,DE na i2) d) Cisla vetsi nez 2^27 jsou nasobena hodnotou 2^(-n+7),coz snizuje pocet cis- lic pred desetinnou carkou na osm a je proveden opetovny vstup do smycky v bo- de FP-LOOP. 2E56 SUB #80 ;E-#80=E' je skutecny exponent i CP #1C JR C,#2E6F ;Je-li E' mensi nez 28,skoc CALL #2DC1 ;V reg. A je vytvorena hodnota n a snizena SUB #07 ;na n-7 LD B,A LD HL,#5CAC ;Pak je okopirovana do B a prictena k druhemu ADD A,(HL) ;bajtu MEM-5,coz je pocet cislic pozadovany LD (HL),A ;pred desetinnou carkou pro tisk cisla x LD A,B ;Potom je i vynasobeno hodnotou 10^(-n+7) NEG ;a tim prevedeno pro stredni CALL #2D4F ;tiskovy rozsah.Skoc do smycky pro zpracovani JR #2E01 ;stredne velikeho cisla e) Cela cast hodnoty x je ulozena v tiskovem bafru,ktery je tvoren 10 bajty MEM-3 a MEM-4. 2E6F EX DE,HL ;DE ukazuje na i,HL na f. CALL #2FBA ;Mantisa i je D',E',D,E EXX ;Vyzvedni zrcadlove registry SET 7,D ;Pravdivy numericky bit 7 do D LD A,L ;Exponentovy bajt E cisla i do registru A EXX ;Zpet na hlavni registry SUB #80 ;Skutecny exponent do registru A LD B,A ;Tim se dosahne pozadovaneho poctu bitu V pripade,ze i je male cele cislo (mensi nez 65535),provede se opetovny vstup v tomto bode. 2E7B SLA E ;Mantisa i je nyni rotovana doleva a vsechny RL D ;bity posouvany do MEM-4 a kazdy bajt MEM-4 je EXX ;dekadicky upraven po kazdem posunu RL E RL D ;Vsechny ctyri bajty cisla i EXX ;Zpet na hlavni registry LD HL,#5CAA ;Adresa 5.bajtu MEM-4 do HL LD C,#05 ;Pocet 5-ti bajtu do C 2E8A LD A,(HL) ;Vyzvedni bajt z MEM-4 ADC A,A ;Posun jej doleva a priber i novy bit.Pak pro- DAA ;ved dekadickou korekci a vysledek opet uloz LD (HL),A ;do MEM-4.Ukazuj na dalsi bajt v MEM-4 DEC HL DEC C ;Sniz pocitadlo bajtu o jeden JR NZ,#2E8A ;Skoc pro kazdy bajt v MEM-4 DJNZ #2E7B ;Skoc pro kazdy bit hodnoty INT x Dekadicka korekce kazdeho bajtu MEM-4 dava dve desitkove cislice na bajt,cimz vznikne nejvice 9 cislic.Vznikle cislice budou nyni prevedeny,jedna na bajt, v pametech MEM-3 a MEM-4 pouzitim instrukce RLD. XOR A ;Registr A je vycisten,aby mohl prevzit LD HL,#5CA6 ;cislice.Zdrojova adresa 1.bajtu mem-4 LD DE,#5CA1 ;Cilova adresa 1.bajt MEM-3 LD B,#09 ;Existuje maximalne 9 cislic RLD ;Leva slabika MEM-4 je odhozena LD C,#FF ;Hodnota #FF v C je signal:uvodni nula,#00:bez 2EA1 RLD ;uvodni nuly.Leva slabika hodnoty v (HL) do A, JR NZ,#2EA9 ;prava slabika (HL) doleva.Skoc,jestlize cis- DEC C ;lice v A neni nulova.Test na uvodni nulu MONITOR ROM - ZX Spectrum - 112 - DEFB #02 ;vymaz DEFB #38 ;konec vypoctu EXX ;Kalkulatorovy doplnek,ktery byl uschovan POP HL ;na zasobniku je obnoven v zrcadlovem HL EXX h) Nyni muze byt cislo vytisteno.Nejdrive bude do C ulozen pocet tistenych cislic,mimo zaverecnych nul a B bude obsahovat pocet cislic pred desetinnou teckou. LD BC,(#5CAB) ;Citace jsou nastaveny LD HL,#5CA1 ;Adresa prvni cislice LD A,B ;Jestlize je vice nez 9 nebo mene nez -4 cislic CP #09 ;pred desetinnou teckou,je pouzit format E JR C,#2F46 ;Mene nez -4 pred desetinnou teckou znamena CP #FC ;vice nez ctyri nuly za desetinnou teckou JR C,#2F6C 2F46 AND A ;Jestlize nejsou zadna cisla pred desetinnou CALL Z,#15EF ;teckou,vytiskni pocatecni nulu Dalsi vstupni bod se pouziva k vytisteni cisla ve formatu E. 2F4A XOR A ;Nastav A na nulu SUB B ;Odecti B.Minus znamena,ze existuji cislice JR M,#2F52 ;pred desetinnou teckou a proto je vytiskni LD B,A ;A je nyni pouzito jako citac JR #2F5E ;Skoc dopredu k vytisteni casti za desetinnou 2F52 LD A,C ;teckou.Kopiruj pocet cislic,ktere maji byt AND A ;vytisteny,do A.Jestlize A je nula,pak jeste JR Z,#2F59 ;existuji zaverecne nuly,ktere je treba LD A,(HL) ;;vytisknout (skoc nebot B je nenulove) INC HL ;Vyzvedni cislici z tiskoveho bafru.Ukazuj DEC C ;na dalsi cislici.Dekrenentuj pocet o 1 2F59 CALL #15EF ;Vytiskni prislusnou cislici DJNZ #2F52 ;Skakej zpet,dokud B neni nulove 2F5E LD A,C ;Je treba vytisknout desetinnou tecku AND A ;Pokud ovsem C neni nulove RET Z ;V tom pripade se vrat,nebot je vse hotovo INC B ;Pricti jednicku do B (toto pricte desetinnou LD A,#2E ;tecku).Dej kod pro "." do A 2F64 RST #10 ;Vytiskni tecku LD A,#30 ;Vloz kod pro nulu DJNZ #2F64 ;Skoc zpet k vytisteni vsech potrebnych nul LD B,C ;Nastav citac pro vsechny zbyvajici cislice JR #2F52 ;Proved jejich vytisteni 2F6C LD D,B ;Pocet cislic je kopirovan do D a okamzite DEC B ;dekrementovan aby byl dan i exponent LD B,#01 ;Je zapotrebi jedna cislice pred desetinnou CALL #2F4A ;teckou pro E format.Cela cast cisla pred E LD A,#45 ;je nyni vytistena.Vloz kod pro E a vytiskni ho RST #10 LD C,D ;Exponent do C pro vytisteni a do A pro otesto- LD A,C ;vani.Je testovano znamenko a je-li kladne,skoc AND A JP P,#2F83 NEG ;Neguj A LD C,A ;Kopiruj A zpet do C pro tisk LD A,#2D ;Vloz kod pro minus a vytiskni znamenko JR #2F85 2F83 LD A,#2B ;Vloz kod pro "+" 2F85 RST #10 ;Nyni vytiskni znamenko ("+" nebo "-") LD B,#00 ;BC obsahuje exponent vytiskni ho JP #1A1B Subrutina "CA=10*A+C" --------------------- Tento podprogram je volan podprogramem PRINT-FP k vynasobeni kazdeho bajtu D,E,D',E' tak ze je vraci jako celociselnou cast vysledku v registru C. Na vstupu registr A obsahuje bajt,ktery ma byt nasoben deseti a registr obsa- huje CY z predchoziho bajtu.Pri navratu obsahuje A vysledny bajt a v registru C je logicka hodnota CY flag pro dalsi bajt. 2F8B PUSH DE ;Uschovej kterykoliv par DE (muze to byt totiz LD L,A ;D'E' nebo DE).Kopiruj nasobence do HL LD H,#00 LD E,L ;Okopiruj jej take do DE LD D,H ADD HL,HL ;Dvakrat zdvoj HL ADD HL,HL ADD HL,DE ;Pricti DE (coz uz 5*A) a nakonec zdvoj ADD HL,HL ;HL (10*A).Kopiruj C do DE (D je nulove LD E,C ;pro scitani).Nyni se HL rovna 10*A+C ADD HL,DE LD C,H ;H je kopirovano do C a L je kopirovano do A, LD A,L ;cimz je ukol hotov POP DE ;Obnov DE RET MONITOR ROM - ZX Spectrum - 114 - Subrutina "SHIFTOVANY SCITANEC" ------------------------------- Tento podprogram posunuje FP-cislo az o 32 mist doprava,cimz ho spravne nasta- vi do pozice potrebne pro scitani.Cislo s mensim exponentem jiz bylo takto o- setreno pred zavolanim tohoto podprogramu.Jakekoli preteceni doprava (do CY) je pricteno zpet k cislu.Je-li rozdil exponentu vetsi nez 32,nebo CY preteka na zacatek cisla,je toto cislo nastaveno na nulu tak,aby scitani nezmenilo druheho scitance. 2FDD AND A ;Pri nulovem rozdilu exponentu se vrat RET Z CP #21 ;Je-li rozdil exponentu vetsi nez #20,skoc JR NC,#2FF9 PUSH BC ;Kratce uschovej BC LD B,A ;Rozdil exponentu do B jako citac posunu 2FE5 EXX ;Prepni zrcadlove registry SRA L ;Posun aritmeticky do prava L' a zachovej RR D ;znamenkovy bit.Rotuj doprava s CY RR E ;registry DE',DE EXX ;Prepni zpet RR D ;Rotuj tak vsech 5 bajtu cisla doprava B-krat RR E DJNZ #2FE5 ;Skakej zpet do vynulovani B POP BC ;Obnov BC RET NC ;Hotovo nedoslo-li k preteceni CALL #3004 ;Pricti zpet CY RET NZ ;Vrat se,pokud CY neprepadlo hned zpet 2FF9 EXX ;Prepni zrcadlove registry XOR A ;Vynuluj A 2FFB LD L,#00 ;Nastav scitance na nulu DE',DE vcetne LD D,A ;znamenkoveho bajtu L' LD E,L EXX ;Pri zavolani z #3160 se vynuluji pouze ctyri LD DE,#0000 ;bajty RET Podprogram "ADD BACK" (zpetne pricteni) --------------------------------------- Podprogram pricita zpet k cislu kazde CY,ktere preteklo doprava a v extremnim pripade se CY vraci nalevo do cisla.Pokud je podprogram volan behem scitani, znamena tento extrem,ze mantisa byla posunuta o 32 mist doprava a scitanec bude nastaven na 0.Pri zavolani z podprogramu MULTIPLICATIO znamena tento ex- trem,ze exponent musi byt inkrementovan,coz muze zpusobit preteceni. 3004 INC E ;Pricti CY k poslednimu bajtu RET NZ ;Vrat se,nedoslo-li k preteceni doleva INC D ;Pokracuj na dalsi bajt RET NZ ;Vrat se,nedoslo-li k preteceni doleva EXX ;Pokracuj na dalsi bajt INC E ;Take jej inkrementuj JR NZ,#300D ;Skoc,nedoslo-li k preteceni doleva INC D ;Inkrementuj posledni bajt 300D EXX ;Obnov hlavni registry RET Operace "SUBTRACTION" (odecitani) --------------------------------- Doplnek: #03 "subtract" Tento podprogram jednoduse meni znamenko mensitele a pokracuje dale do ADDITION.Povsimnete si,ze HL ukazuje na mensence a DE na mensitele. 300F EX DE,HL ;Zamen ukazatele CALL #346E ;Zmen znamenko mensitele EX DE,HL ;Zamen ukazatele zpet a pokracuj do ADDITION Operace "ADDITION" (scitani) ---------------------------- Doplnek: #0F "addition" Prvni ze tri hlavnich aritmetickych podprogramu provadi scitani dvou cisel v FP-forme,kazde s ctyrbajtovou adresou a jednobajtovym exponentem.V techto trech podprogramech jsou dve cisla na vrcholu zasobniku sectena,nasobena nebo delena.Vysledkem je pak jedno cislo na vrcholu zasobniku,cili "posledni hod- nota".HL ukazuje na druhe cislo kalkulatoru, coz je budto scitanec,nasobenec nebo delenec.DE ukazuje na cislo na vrcholu zasobniku coz je scitanec,nasobitel nebo delitel.Po ukonceni podprogramu HL ukazuje na vysledek,coz je posledni hodnota,jejiz hodnota muze byt povazovana za STKEND-5.Ale podprogram scitani nejdrive testuje,zda nasledujici dve scitana cisla jsou "mala cela cisla". Je-li tomu tak,je jednoduse secteno HL a BC a vysledek je ulozen na zasobnik. Pred nebo po scitani neni provedena dvojkova komplementace,nebot cisla,ktera tuto komplementaci vyzaduji,jsou uz ulozena na zasobniku v potrebnem tvaru a pripravena ke scitani. 3014 LD A,(DE) ;Nejsou-li oba prvni bajty scitanych cisel OR (HL) ;nulove,skoc na plne scitani JR NZ,#303E MONITOR ROM - ZX Spectrum - 116 - LD A,H ;Secti H'L' a CY:tento mechanismus zajisti,ze ADC A,L ;bude zavolan jeden posun doprava,jestlize LD L,A ;soucet dvou kladnych cisel zpusobil preteceni RRA ;doleva,nebo soucet dvou zapornych cisel XOR L ;nezpusobil preteceni doleva EXX EX DE,HL ;Vysledek jde nyni do DE,DE' POP HL ;Vyzvedni ukazatel na exponent RRA ;Test na posun (HL' byl #00 pro kladna cisla JR NC,#307C ;a #FF pro zaporna cisla) LD A,#01 ;A je citac jednoho posunu doprava CALL #2FDD ;Zavolej posun INC (HL) ;Pricti 1 k exponentu JR Z,#309F ;Toto muze zpusobit aritmeticke preteceni 307C EXX ;Test na negativni vysledek LD A,L ;Vyzvedni znamenkovy bit z L' do A (coz dobre AND #80 ;indikuje znamenko vysledku).Uloz jej do druhe EXX ;ho bajtu vysledku na zasobniku kalkulatoru INC HL LD (HL),A DEC HL JR Z,#30A5 ;Byl-li nulovy,neprovadej dvojkovy doplnek LD A,E ;vysledku.Vyzvedni 1.bajt a neguj jej NEG CCF ;Komplementuj CY pro pokracujici negaci LD E,A ;a uschovej tento bajt LD A,D ;Vezmi dalsi bajt a proved dvojkovy doplnek CPL ADC A,#00 ;Pricti CY pro negaci LD D,A ;Uschovej tento bajt EXX LD A,E ;Vyzvedni dalsi bajt do A a do E CPL ;Proved komplementaci ADC A,#00 ;Pricti CY pro negaci LD E,A ;Uschovej bajt LD A,D ;Vyzvedni posledni bajt a komplementuj ho CPL ADC A,#00 ;Pricti CY pro negaci JR NC,#30A3 ;Pokud nedoslo k preteceni,je hotovo RRA ;Dej 0.5 do mantisy a pricti jednicku EXX ;k exponentu(to je treba tehdy,je-li vysledek INC (HL) ;souctu dvou zapornych cisel presny nasobek 2 309F JP Z,#31AD ;Ohlas chybu,je-li treba EXX 30A3 LD D,A ;Uschovej posledni bajt EXX 30A5 XOR A ;Vynuluj CY JP #3155 ;Vrat se pres TEST-NORM Podprogram "HL=HL*DE" --------------------- Podprogram je volan podprogramem "GET-HL*DE" a MULTIPLICATION aby provedl 16-ti bitove nasobeni.Kazde preteceni na 16.bitu se zpracuje po navratu z tohoto podprogramu. 30A9 PUSH BC ;Uschovej BC LD B,#10 ;Jde o 16.bitove nasobeni LD A,H ;A obsahuje vyssi bajt LD C,L ;C obsahuje nizsi bajt LD HL,#0000 ;Nastav vysledek na nulu 30B1 ADD HL,HL ;Zdvojeni vysledku JR C,#30BE ;Skok pri preteceni RL C ;Rotuj bit 7 registru C do CY RLA ;Rotuj CY do bitu 0 registru A a bit 7 do CY JR NC,#30BC ;Pri nulovem CY skoc ADD HL,DE ;Jinak pricti DE a skoc pri preteceni JR C,#30BE ;Dokud neprobehlo 16 pruchodu,pokracuj 30BC DJNZ #30B1 30BE POP BC ;Obnov BC RET Podprogram pripravy na nasobeni nebo deleni ------------------------------------------- Tento podprogram pripravuje FP-cislo pro nasobeni nebo deleni a vraci CY=1 bylo-li cislo nulove.Znamenko vysledku je v registru A a znamenkovy bit cisla je nahrazen skutecnym numerickym bitem s hodnotou 1. 30C0 CALL #34E9 ;Jestlize cislo je nulove vrat se s CY=1 RET C INC HL ;Ukazuj na znamenkovy bajt XOR (HL) ;Vyzvedni znamenko vysledku do A a soucasne SET 7,(HL) ;nuluj CY.Nastav pravdivy numericky bit DEC HL ;Opet ukazuj na exponent RET ;Vrat se s nulovym CY MONITOR ROM - ZX Spectrum - 118 - RR C ;Posledni bit,ktery zustane v CY vyvola RRA ;dalsi pricteni nasobence k vysledku DJNZ #3114 ;Proved 33-krat tuto smycku cimz se posoudi EX DE,HL ;vsechny bity.Prenes vysledek z H'L' do DE'DE EXX EX DE,HL EXX POP BC ;Secti oba exponenty.Obnov exponenty M1 a N1 POP HL ;Obnov ukazatel na exponentovy bajt LD A,B ;Vytvor soucet dvou exponentu v A a oprav CY ADD A,C ;tak,ze nebyl-li soucet nulovy,nech CY bit JR NZ,#313B AND A ;Jinak CY vynuluj 313B DEC A ;Priprav se na zvetseni exponentu o #80 CCF Zbytek podprogramu je spolecny jak pro nasobeni tak pro deleni. 313D RLA ;Techto par bajtu velmi rafinovane vytvari spravny exponentovy CCF ;bajt.Rotaci registru A doleva a doprava vznikne exponent(sku- RRA ;tecny exponent+#80) v registru A JP P,#3146 ;Je-li P flag nulovy,neni treba hlasit zadnou JR NC,31AD ;chybu.Ohlas preteceni,jestlize CY=0 AND A ;Vynuluj CY 3146 INC A ;Exponentovy bajt je kompletni JR NZ,#3151 ;Je-li A nulove,je potrebny dalsi test JR C,#3151 ;na preteceni EXX ;Je-li CY=0 a vysledek je jiz v normalni forme BIT 7,D ;(bit 7 je nastaven,pak doslo k preteceni, EXX ;ktere je nutno ohlasit.Ale kdyz bit 7 registru JR NZ,#31AD ;D=0,pak je vysledek v rozsahu,tj.pod hodnotou 3151 LD (HL),A ;2^127.Uloz exponentovy bajt EXX ;Predej paty bajt vysledku pro normalizacni LD A,B ;sekvenci,tedy preteceni z L EXX ;do B Zbytek tohoto podprogramu osetruje normalizaci a je spolecny pro vsechny aritmeticke rutiny. 3155 JR NC,#316C ;Je-li CY=0,normalizuj LD A,(HL) ;Jinak osetri podteceni (nulovy vysledek) nebo AND A ;temer podteceni (vysledek 2^-128).Vrat expo- 3159 LD A,#80 ;nent do A a testuj,je-li registr A nulovy JR Z,#315E ;(pro pripad 2^-128).Je-li to pravda,vytvor 315D XOR A ;2^-128 v pripade normalniho cisla,nebo produ- 315E EXX ;kuj nuly.Exponent musi byt nulovy (pro nulu) AND D ;nebo 1 (pro 2^-128).Obnov exponentovy bajt CALL #2FFB RLCA LD (HL),A JR C,#3195 ;Skoc v pripade 2^-128 INC HL ;Jinak do druheho bajtu vysledku na kalkulato- LD (HL),A ;rovem zasobniku vloz nulu a preved vysledek DEC HL JR 3195 Aktualni normalizacni operace. 316C LD B,#20 ;Normalizuj vysledek az 32 posuny doleva 316E EXX ;v D'E'D E s pridanim A dokud bit 7 v registru BIT 7,D ;D' neni nastaven na nulu EXX ;Registr A obsahuje nulu pro scitani a proto JR NZ,#3186 ;nedojde k zadne zmene presnosti RLCA ;A obsahuje 5.bajt z reg.B po nasobeni nebo RL E ;deleni,ale protoze se bere v uvahu vzdy jen 32 RL D ;bitu, nedojde k zadne zmene presnosti EXX ;Povsimnete si,ze A je rotovano kruhove RL E ;s odbockou pri preteceni ; eventualne nahodny RL D ;proces EXX DEC (HL) ;Pri kazdem posunu je dekrementovan exponent JR Z,#3159 ;Je-li exponent nulovy,je cislo 2^-129 zaokrou- DJNZ #316E ;hleno na 2^-128.32krat zpet do smycky.Nebyl-li JR #315D ;bit 7 registru D nikdy 1,je cely vysledek nula Ukonci normalizaci posouzenim CY. 3186 RLA ;Po normalizaci pricti zpet jakekoliv JR NC,#3195 ;zaverecne CY,ktere vstoupilo do A CALL #3004 ;Nepretekali CY hned zpet,skoc dopredu JR NZ,#3195 EXX ;V opacnem pripade nastav mantisu na 0.5 LD D,#80 ;a inkrementuj exponent.Tato akce muze vest EXX ;k aritmetickemu preteceni INC (HL) JR Z,#31AD MONITOR ROM - ZX Spectrum - 120 - 31F2 AND A ;Proved pouhe odecteni bez obnoveni a pokracuj SBC HL,DE ;na nastaveni CY,protoze ztraceny bit delence EXX ;musi byt obnoven a uzit pro podil.Jednicka SBC HL,DE ;pro podil B' C' C A EXX 31F9 SCF ;Inkrementace citace pro kazdy pruchod smyckou, 31FA INC B ;ktera je provedena 32-krat pro vsechny bity JP M,#31D2 ;Uschovej 33.bit pro zvysenou presnost (aktu- PUSH AF ;alni CY).Jeste jeden zkusebni odecet JR Z,#31E2 ;pro kazdy 34.bit !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Poznamka: Skok je proveden do spatneho mista. 34.bit se nikdy neziska,pokud se nebude posouvat delenec.Proto napr. dulezite vysledky jako 1/10 a 1/1000 nejsou zaokrouhleny tak,jak by mely byt.Zaokrouhleni se nikdy neprovede,pokud zalezi na 34.bitu.Skok mel byt na #31DB DIV-34TH,tedy bajt #3200 mel obsaho- vat misto hodnoty #DA hodnotu #E1. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! LD E,A ;Nyni presun ctyri bajty tvorici mantisu LD D,C ;vysledku z B' C' C A do DE' DE EXX LD E,C LD D,B POP AF ;Potom uloz 34. 33. bit do B',aby byly pozdeji RR B ;pri normalizaci vyzvednuty POP AF RR B EXX POP BC ;Obnov exponentove bajty M1 a N1.Obnov ukaza- POP HL ;tel na vysledek.Vloz do A rozdil mezi dvema LD A,B ;exponentovymi bajty s nastavenim CY v pripade SUB C ;potreby.Vystup pres DIVN-EXPT JP #313D Odriznuti desetinne casti cisla ------------------------------- Doplnek: #3A "truncate" Podprogram vraci vysledek po odriznuti desetinne casti cisla x jako posledni hodnotu na zasobniku kalkulatoru.Napriklad I(2.4)=2 a take I(-2.4)=-2.Podpro- gram se okamzite vraci v tom pripade,kdy x je ve forme "maleho" celeho cisla. Nula je pouzita jako vysledek,jestlize exponentovy bajt je mensi nez #81(nebot ABS x=-1.Jestlize x je "male" cele cislo,nebo exponentovy bajt je vetsi nez #A0,pak je x vraceno ve sve puvodni forme.V ostatnich pripadech je nastaven spravny pocet bajtu cisla x na nulu a v pripade potreby je dalsi bajt rozdelen maskou. 3214 LD A,(HL) ;Vyzvedni exponent do A,je-li nula,vrat se, AND A ;nebot x je jiz "male" cele cislo RET Z CP #81 JR NC,#3221 ;Je-li exponent mensi nez #81,skoc LD (HL),#00 ;Jinak nastav exponent na nulu LD A,#20 ;Uloz 32 do registru A JR #3272 ;Za pomoci NIL-BYTES vynuluj vsechny bajty 3221 CP #91 ;cisla.Jestlize se exponent nerovna #91,skoc 3223 JR NZ,#323F !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Dalsich 26 bajtu je zde proto,aby otestovalo,zda x nahodou neni rovno cislu -65536 (#:91 80 00 00 00).V pripade pozitivniho vysledku porovnani jsou tyto bajty prepsany na tvar #:00 FF 00 00 00.A to je CHYBA!Jak jiz bylo receno okolo adresy #303B,nemuze system SPECTRA takove cislo zpracovat.Zde je vlastne pro- vedeno INT (-65536) a jako vysledek je vytvorena hodnota -1.To je skoda,protoze kdyby se s cislem nic nedelalo,bylo by vse v perfektnim poradku.Jednoduchou napravou by bylo vynechani 28 bajtu od adresy #3223 do adresy #323E. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 3225 INC HL ;HL ukazuje na 4.bajt x,kde konci 17 bitu INC HL ;celociselne casti cisla x za prvnim bitem INC HL LD A,#80 ;Prvni bit je vyzvednut s pouzitim masky #80 AND (HL) ;Tento a predchozich pet bitu je spolecne DEC HL ;testovano na nulu OR (HL) DEC HL ;HL ukazuje na druhy bajt cisla x.Test konci, JR NZ,#3233 ;nebyla-li nalezena nula LD A,#80 ;Jinak testuj hodnotu -65536: Sled cisel #: XOR (HL) ;91 80 00 00 00 ponecha Z flag nastaven 3233 DEC HL ;HL ukazuje na prvni bajt cisla x JR NZ,#326C ;Je-li Z flag nulovy,provede se skok LD (HL),A ;Prvni bajt je nastaven na nulu a HL ukazuje INC HL ;na druhy bajt LD (HL),#FF ;Druhy bajt bude #FF a HL opet ukazuje na prvni DEC HL ;bajt.Je vynulovano koncovych 24 bitu pomoci LD A,#18 ;NIL-BYTES,kde se dokonci stvoreni sledu JR #3272 ;00 FF 00 00 00 MONITOR ROM - ZX Spectrum - 122 - PUSH DE ;Uschovej ukazatel z DE CALL #2D7F ;Vyzvedni znamenko do C a cislo do DE XOR A ;Vycisti registr A INC HL ;Ukazuj na 5.misto LD (HL),A ;Nastav 5.bajt na nulu DEC HL ;Ukazuj na 4.misto LD (HL),A ;Nastav 4.bajt na nulu.Bajty 2 a 3 budou LD B,#91 ;obsahovat mantisu.Nastav B na hodnotu 145 LD A,D ;pro exponent,tedy az 16 bitu cisla.Jestlize AND A ;je D nulove bude potreba maximalne 8 bitu JR NZ,#32B1 ;Je zapotrebi vice nez 8 bitu OR E ;Je otestovano take E LD B,D ;Nuluj B (=nulovy exponent v pripade,ze E je JR Z,#32BD ;take nula).Je-li E skutecne nulove skoc LD D,E ;Prenes E do D (D bylo nulove,ale E ne) LD E,B ;Nastav E na nulu LD B,#89 ;Dej do B exponent 137 - ne vice nez 8 bitu 32B1 EX DE,HL ;Ukazatel do DE,cislo do HL 32B2 DEC B ;Dekrementuj exponent pri kazdem posunu ADD HL,HL ;Posun cislo doprava o jednu pozici JR NC,#32B2 ;Dokud CY=0 skakej zpet do smycky RRC C ;Dej znamenkovy bit do CY a vloz jej na sve RR H ;misto do cisla,ktere je prave posunuto RR L ;o jedno misto EX DE,HL ;Ukazatel na ctvrty bajt zpet do HL 32BD DEC HL ;Ukazuj na 3.misto LD (HL),E ;Uschovej 3.bajt DEC HL ;Ukazuj na 2.misto LD (HL),D ;Uschovej 2.bajt DEC HL ;Ukazuj na prvni misto LD (HL),B ;Uschovej exponentovy bajt POP DE ;Obnov puvodni ukazatel v DE RET FLOATING POINT KALKULATOR ************************* TABULKA KONSTANT ---------------- Tato prvni tabulka obsahuje pet uzitecnych a casto pouzivanych cisel: nula, jedna,polovina,pi/2 a deset.Cisla jsou ulozena ve stazenem tvaru,ktery je expandovan podprogramem STACK LITERALS na pozadovany tvar floating-point (=FP tvar). data konstanta expandovany tvar 32C5 STK-ZERO DEFB #00 nula 00 00 00 00 00 DEFB #B0 DEFB #00 32C8 STK-ONE DEFB #40 jedna 00 00 01 00 00 DEFB #B0 DEFB #00 DEFB #01 32CC STK-HALF DEFB #30 polovina 80 00 00 00 00 DEFB #00 32CE STK-PI/2 DEFB #F1 polovina pi 81 49 0F DA A2 DEFB #49 DEFB #0F DEFB #DA DEFB #A2 32D3 STK-TEN DEFB #40 deset 00 00 0A 00 00 DEFB #B0 DEFB #00 DEFB #0A MONITOR ROM - ZX Spectrum - 124 - 336C PUSH HL ;literaly nasledujici za volaci instrukci AND A ;Prepni zrcadlove registry a vyzvedni literal JP P,#3380 ;pro tuto smycku.HL' ukazuje na dalsi literal LD D,A ;a je kratce uschovano na zasobniku.Tento bod AND #60 ;je pouzivan pro podprogram SINGLE CALCULATION RRCA ;k nalezeni pozadovane rutiny.Testuj registr A RRCA ;a oddel jednoduche literaly od viceucelovych RRCA ;Skoc s literaly #00-#3D.Uschovej literal v D RRCA ;Pokracuj pouze s bity 5 a 6 a ctyrmi posuny ADD A,#7C ;z nich udelej bity 1 a 2.Pozadovane doplnky LD L,A ;jsou #3D-#41 a L obsahuje pozadovany doplnek LD A,D ;Vytvor parametr tak,ze pouzijes bity AND #1F ;1,2,3 a 4 z puvodniho literalu JR #338E ;Najdi adresu pozadovaneho podprogramu 3380 CP #18 ;Pri odskoku proved binarni operaci JR NC,#338C EXX ;Vsechny podprogramy,ktere jsou binarnimi LD BC,#FFFB ;operacemi vyzaduji,aby HL ukazovalo na prvni LD D,H ;opereand a DE na druhy ("posledni hodnotu") LD E,L ;tak jak jsou na zasobniku kalkulatoru ADD HL,BC EXX 338C RLCA ;Protoze kazda polozka v tabulce je dvoubajto- LD L,A ;va,je vytvoreny doplnek zdvojnasoben 338E LD DE,#32D7 ;Bazova adresa tabulky LD H,#00 ;Adresa pozadovane polozky v tabulce je vytvo- ADD HL,DE ;rena v HL a adresa pozadovaneho podprogramu LD E,(HL) ;je vyzvednuta do DE INC HL LD D,(HL) ;Adresa opetovneho vstupu je ulozena na zasob- LD HL,#3365 ;nik pod adresu pozadovaneho podprogramu EX (SP),HL PUSH DE EXX ;Prepni hlavni registry.BREG je ulozena do B, LD BC,(#5C66) ;cimz se vraci doplnek jedine operace.Nyni je 33A1 RET ;proveden neprimy skok do pozadovaneho podpr. Podprogram "DELETE" ------------------- Doplnek: #02 "DELETE" Tento podprogram obsahuje pouze instrukci RET.Literal #02 zpusobi,ze tento podprogram je povazovan za binarni operaci.Proto se do nej vstupuje s prvnim cislem adresovanym HL a druhym cislem adresovanym DE a vytvoreny vysledek bude opet adresovan registrovym parem HL.Instrukce RET tedy zpusobi,ze prvni cislo je povazovano za "posledni hodnotu" a druhe cislo je vymazano.Druhe cislo sa- mozrejme neni vymazano z pameti,ale stava se pouze neaktivnim a pravdepodobne bude brzy prepsano. Podprogram "SINGLE OPERATION" ----------------------------- Doplnek:#3B "FP-CALC-2" Tento podprogram je volan z podprogramu SCANNING na adrese #2757 a pouziva se k provedeni jednoduche aritmeticke operace.Doplnek uvazovane operace se preda- va kalkulatoru v registru B,odkud je predan do systemove promenne BREG.Vysled- kem provedeni tohoto podprogramu je zejmena provedeni skoku do prislusneho podprogramu pro jedinou operaci. 33A2 POP AF ;Odhod navratovou adresu,preved doplnek do A LD A,(#5C67) ;Prepni na zrcadlove registry EXX ;Nalezni pozadovanou adresu,uloz ji JR #336C ;na zasobnik a proved prislusnou operaci Podprogram "TEST 5-SPACES" -------------------------- Podprogram testuje,zda je v pameti dostatek mista pro pet bajtu FP cisla,ktere ma byt pridano na zasobnik kalkulatoru 33A9 PUSH DE ;Kratce uschovej DE a HL PUSH HL LD BC,#0005 ;Test bude na 5 bajtu CALL #1F05 ;Proved test POP HL ;Obnov HL a DE POP DE RET Podprogram "STACK NUMBER" ------------------------- Tento podprogram je volan z prikazu BEEP a podprogramu SCANNING dvakrat,aby okopiroval STKEND do DE,prenesl FP cislo na zasobnik kalkulatoru a opet nasta- vil STKEND na hodnotu v DE.Pro skutecny presun je pouzit podprogram MOVE-FP. 33B4 LD DE,(#5C65) ;Okopiruj STKEND do DE jako cilovou adresu CALL #33C0 LD (#5C65),DE ;Presun cislo.Obnov hodnotu STKEND RET MONITOR ROM - ZX Spectrum - 126 - LD DE,#0000 ;Mrtva adresa.Proved imaginarni ulozeni CALL #33C8 ;expandovane konstanty POP DE ;Obnov ukazatel vysledku a parametr POP AF DEC A ;Pocitej smycky a posud dalsi hodnoty citace JR #33F8 Podprogram "MEMORY LOCATION" ---------------------------- Podprogram nalezne bazovou adresu kazdych peti bajtu v pametove oblasti kalku- latoru,na kterou nebo z ktere ma byt preneseno FP cislo do nebo ze zasobniku kalkulatoru.Tato operace se provede petinasobnym prictenim parametru dodaneho v bazove adrese pro oblast,jejiz adresa je v reg. paru HL.Povsimnete si,ze pri zpracovani promenne FOR-NEXT jsou ukazatele zameneny tak,aby promenna byla povazovana za oblast kalkulatoru (viz. #1D20). 3406 LD C,A ;Kopiruj parametr do C RLCA ;Zdvoj parametr RLCA ;Zdvoj vysledek.Pricti hodnotu parametru,coz ADD A,C ;da petinasobek puvodni hodnoty LD C,A ;Preved vysledek do BC LD B,#00 ;Vytvor novou bazovou adresu ADD HL,BC RET Podprogram "GET FROM MEMORY AREA" --------------------------------- Doplnky: #E0 az #E5 "GET-MEM-0" az "GET-MEM-5" Podprogram je volan pouzitim literalu #E0 az #E5 a parametry odvozene z techto literalu jsou v reg. A.Podprogram vola MEMORY LOCATION k ulozeni pozadovane zdrojove adresy do HL a MOVE A FLOATING POINT NUMBER k okopitovani prislusnych peti bajtu z pameti kalkulatoru na vrchol zasobniku kalkulatoru k vytvoreni nove "posledni hodnoty". 340F PUSH DE ;Uschovej ukazatel vysledku LD HL,(#5C68) ;Vyzvedni ukazatel na aktualni pametovou oblast CALL #3406 ;Bazova adresa je nalezena CALL #33C0 ;Pet bajtu je preneseno POP HL ;Ukazatel vysledku nastaven RET Podprogram "STACK A KONSTANT" ----------------------------- Doplnky: #A0 az #A4 "STK-nula","STK-jedna","STK-1/2","STK-pi/2", "STK-deset" Tento podprogram pouziva SKIP KONSTANTS k nalezeni bazove adresy pozadovane konstanty z tabulky konstant a potom STACK LITERALS,aby se dosahlo expandovane formy konstanty jako "posledni hodnoty" na zasobniku kalkulatoru. 341B LD H,D ;Nastav HL jako ukazatel vysledku LD L,E EXX ;Prepni na zrcadlove registry PUSH HL ;Uschovej adresu dalsiho literalu LD HL,#32C5 ;Bazova adresa tabulky konstant EXX ;Prepni zpet CALL #33F7 ;Nalezni pozadovanou bazovou adresu CALL #33C8 ;Expanduj konstantu EXX POP HL ;Obnov ukazatel na dalsi literal EXX RET Podprogram "STORE IN MEMORY AREA" --------------------------------- Doplnek: #C0 az #C5 "ST-MEM-0" az "ST-MEM-5" Tento podprogram se vola pouzitim literalu #C0 az #C5 a parametry odvozene z techto literalu jsou v reg. A.Podprogram je velmi podobny podprogramu GET FROM MEMORY,ale zdrojove a cilove ukazatele jsou zameneny. 342D PUSH HL ;Uschovej ukazatel vysledku EX DE,HL ;Zdroj kratce do DE LD HL,(#5C68) ;Vyzvedni ukazatel na aktualni pametovou oblast CALL #3406 ;Je nalezena bazova adresa EX DE,HL ;Je zamenen zdrojovy a cilovy ukazatel CALL #33C0 ;Prenes pet bajtu EX DE,HL ;STKEND do DE POP HL ;Ukazatel vysledku do HL RET Povsimnete si,ze ukazatel HL a DE zustavaji tak,jak byly,ukazujice na STKEND-5 a STKEND,takze posledni hodnota na zasobniku kalkulatoru.Je-li to treba,muze byt vyrazena pouzitim "delete". MONITOR ROM - ZX Spectrum - 128 - 4) Odecteni cisla B(N-2): Smycka ponechava B(N) na zasobniku a pozadovany vy- sledek je dan hodnotou B(N)-B(N-2). DEFB #E1 ;GET-MEM-1 B(N),B(N-2) DEFB #03 ;odecet B(N)-B(N-2) DEFB #38 ;konec vypoctu RET Funkce "ABSOLUTE MAGNITUDE" --------------------------- Doplnek: #A2 "ABS" Tento podprogram provede unarni operaci tim,ze zajisti,aby znamenkovy bit byl vynulovan."Mala cela cisla" mohou byt posouzena oddelene.Vetsinu prace vykona rutina "unarni minus". 346A LD B,#FF ;B je nastaveno na #FF JR #3474 ;Proved unarni minus Operace "UNARY MINUS" --------------------- Doplnek: #1B "NEGATE" Tento podprogram provede unarni operaci tim,ze zmeni znamenko posledni hodnoty na zasobniku kalkulatoru.0 zustava nezmenena.FP cisla jsou zpracovana tak,ze jejich znamenkovy bit je pro "ABS" nulovan nebo pro "NEGATE" preklopen."Mala cela cisla" maji vynulovano znamenko pro "ABS" nebo zmeneno pro "NEGATE". 346E CALL #34E9 ;Je-li cislo 0,vrat se a bajty 00 00 00 00 00 RET C ;zust. nezmeneny.B je nastaveno na #00-negate LD B,#00 Zde je vstup pro "ABS": 3474 LD A,(HL) ;Jestize prvni bajt je 0,provede se zpracovani AND A ;"maleho celeho cisla". JR Z,#3483 INC HL ;Ukazuj na druhy bajt LD A,B ;Vyzvedni #FF pro "ABS" a #00 pro "NEGATE" AND #80 ;Zmen na #80 pro "ABS" a #00 pro "negate" OR (HL) ;Toto nastavi bit 7 pro "ABS",ale nic se nez- RLA ;meni pro "NEGATE".Nyni je zmenen bit 7,coz CCF ;zpusobi,ze bit 7 2.bajtu je nulovan pro "ABS" RRA ;a zmenen pro "NEGATE" LD (HL),A ;Novy bajt je ulozen DEC HL ;HL opet ukazuje na 1.bajt RET V pripade celeho cisla dochazi k podobne operaci se znamenkem. 3483 PUSH DE ;Uschovej STKEND v DE a ukazatel na cislo v HL PUSH HL CALL #2D7F ;Vyzvedni znamenko do C a cislo do DE POP HL ;Obnov ukazatel na cislo v HL LD A,B ;Vloz #FF pro "ABS" a #00 pro "NEGATE" OR C ;#FF pro "ABS",zadna zmena pro "NEGATE" CPL ;#00 pro "ABS" a zmeneny bajt pro "NEGATE" LD C,A ;uschovej v C CALL #2D8E ;Uschovej vysledek na zasobniku a vrat STKEND POP DE ;do DE RET Funkce "SIGNUM" (znamenko) -------------------------- Doplnek: #29 "SGN" Tento podprogram provadi funkci SGN X.To znamena,ze vraci posledni hodnotu 1 kdyz X>0,0 kdyz X=0 a -1 kdyz X<1. 2492 CALL #34E9 ;Je-li X nula,vrat se s posledni hodnotou nula RET C PUSH DE ;Uschovej ukazatel na STKEND LD DE,#0001 ;Vloz do DE 1 INC HL ;Ukazuj na dalsi bajt X RL (HL) ;Rotuj bit 7 do CY a ukazuj na puvodni adresu DEC HL SBC A,A ;C bude obsahovat #00 pro (+) a #FF pro (-) X LD C,A CALL #2D8E ;Uloz 1 nebo -1 podle potreby POP DE ;Obnov ukazatel na STKEND RET Funkce "IN" ----------- Doplnek: #2C "IN" Tento podprogram provadi funkci IN X.Provede vstup na urovni procesoru z portu X,jehoz hodnota je v BC a provede instrukci IN A,(C). 34A5 CALL #1E99 ;"Posledni hodnota" je kompresovana do BC IN A,(C) ;Signal je prijat JR #34B0 ;Ulozeni vysledku na zasobnik kalkulatoru MONITOR ROM - ZX Spectrum - 130 - Operace "GREATHER THAN ZERO" (vetsi nez nula) --------------------------------------------- Doplnek: #37 "GREATHER-0" Podprogram vraci jako "posledni hodnotu" cislo 1,byla-li aktualni "posledni hodnota" vetsi nez nula,jinak vraci cislo 0.Je take vyuzivan jinymi podprogra- my pri skoku "pri plus". 34F9 CALL #34E9 ;Je posledni hodnota 0 ? RET C ;Vrat se jestlize ano LD A,#FF ;Proved LESS THAN ZERO,ale signalizuj,ze je JR #3507 ;treba provest opacnou akci Funkce "NOT" ------------ Doplnek: #30 "NOT" Podprogram vraci jako "posledni hodnotu" cislo 1 jestlize byla aktualni po- sledni hodnota nulova.Jinak vraci cislo 0.Je take vyuzivan jinymi podprogramy pro "skok pri nule". 3501 CALL #34E9 ;CY bude 1 jedine kdyz posledni hodnota JR #350B ;byla 0,coz uz je spravny vysledek Operace "LESS THAN ZERO" (mensi nez nula) ----------------------------------------- Doplnek: #36 "LESS-0" Podprogram vraci jako "posledni hodnotu" cislo 1,byla-li aktualni "posledni hodnota" mensi nez nula,jinak vraci cislo 0.Je take vyuzivan jinymi podpro- gramy pri skoku "pri minus". 3506 XOR A ;Vynuluj registr A.Ukazuj na znamenkovy bajt 3507 INC HL XOR (HL) ;CY=0 pro kladna cisla.CY=1 pro zaporna cisla DEC HL ;Pri vstupu z GREATHER-0 jde do CY opacne RLCA ;znamenko Podprogram "ZERO OR ONE" (nula nebo jedna) ------------------------------------------ Tento podprogram nastavi posledni hodnotu na nulu jestlize CY=0 nebo na jed- nicku jestlize CY=1.Pri zavolani z "E-TO-FP" vytvari tuto nulu nebo jednicku v MEM-0. 350B PUSH HL ;Uschovej ukazatel na vysledek LD A,#00 ;Vynuluj A bez poruseni CY LD (HL),A ;Nastav 1.bajt na nulu INC HL ;Ukazuj na dalsi bajt LD (HL),A ;Nastav 2.bajt na nulu INC HL ;Ukazuj na 3.bajt RLA ;Rotuj CY do A, takze A bude 1,bylo-li CY=1, LD (HL),A ;jinak A bude 0.Nastav treti bajt na tuto RRA ;hodnotu a zajisti opet nulove A INC HL ;Ukazuj na 4.bajt LD (HL),A ;Nastav jej na nulu INC HL ;Ukazuj na 5.bajt LD (HL),A ;Nastav jej na nulu POP HL ;Obnov ukazatel vysledku RET Operace "OR" ------------ Doplnek: #07 "OR" Podprogram provadi binarni operaci "X OR Y" a vraci X,jestlize Y bylo nulove a jinak hodnotu jedna. 351B EX DE,HL ;HL ukazuje na Y,tedy druhe cislo CALL #34E9 ;Testuj jestli je Y nula EX DE,HL ;Obnov ukazatele RET C ;Jestlize Y bylo nulove,vrat se.X je nyni pos- SCF ;ledni hodnotou.Nastav CY a nastav "posledni JR #350B ;hodnotu" na 1 Operace "NUMBER AND NUMBER" --------------------------- Doplnek: #08 "NO & NO" Podprogram provadi binarni operaci "X AND Y" a vraci X jestlize Y neni nula v ostatnich pripadech hodnotu nula. 3524 EX DE,HL ;HL ukazuje na Y,DE na X CALL #34E9 ;Testuj zda Y je nulove EX DE,HL ;Zamen ukazatele zpet RET NC ;Vrat se s X jako posledni hodnotou,nebylo-li AND A ;Y nula JR #350B ;Nuluj CY a nastav posledni hodnotu na nulu MONITOR ROM - ZX Spectrum - 132 - 358C POP AF ;Tyto tri testy davaji spravne vysledky pro PUSH AF ;vsech 12 porovnavani CALL C,#3501 POP AF ;Pocatecni CY je nastaveno na 1 pro "<>" a "=" PUSH AF ;a vysledne CY je nastaveno pro ">","<" a "=" CALL NC,#34F9 POP AF RRCA CALL NC,#3501 RET Operace "STRING CONCATENATION" ------------------------------ Doplnek: #17 "STRS-ADD" Tento podprogram provadi binarni operaci A$+B$.Parametry obou retezcu jsou vy- zvednuty a je vypoctena celkova delka.V pracovnim prostoru je vytvoreno misto pro oba retezce,ktere jsou pak do nej prekopirovany.Vysledkem je proto vytvo- reni prechodne promenne A$+B$,ktera se nachazi v pracovnim prostoru. 359C CALL #2BF1 ;Parametry 2.retezce jsou vyzvednuty a ulozeny PUSH DE PUSH BC CALL #2BF1 ;Parametry 1.retezce jsou vyzvednuty POP HL ;Delky jsou nyni v registrech HL a BC PUSH HL PUSH DE ;Parametry 1.retezce jsou uschovany PUSH BC ADD HL,BC ;Je vypoctena celkova delka obou retezcu LD B,H ;a ulozena do BC.Je vytvoren pracovni prostor LD C,L RST #30 CALL #2AB2 ;Parametry noveho retezce jsou predany POP BC ;na zasobnik kalkulatoru POP HL ;Jsou obnoveny parametry 1.retezce a pokud LD A,B ;neni nulovy,je okopirovan do pracovniho OR C ;prostoru JR Z,#35B7 LDIR ;Identicka procedura nasleduje pro 2.retezec, 35B7 POP BC ;cimz se dosahne vysledku A$+B$ POP HL LD A,B OR C JR Z,#35BF LDIR Podprogram "STK-PNTRS" ---------------------- Podprogram vraci HL jako ukazatel na prvni bajt posledni hodnoty tedy STKEND-5 a DE ukazuje 1 misto za tuto hodnotu,tedy STKEND. 35BF LD HL,(#5C65) ;Vyzvedni aktualni hodnotu STKEND LD DE,#FFFB ;Nastav DE na -5 PUSH HL ;Uschovej STKEND ADD HL,DE ;Vypocti STKEND-5 POP DE ;Vyzvedni STKEND do DE RET Funkce "CHR$" ------------- Doplnek: #2F "CHR$" Podprogram zpracuje funkci CHR$ X a vytvori prislusny znak v pracovnim prostoru. 35C9 CALL #2DD5 ;Posledni hodnota do A JR C,#35DC ;Je-li X>255,ohlas chybu JR NZ,#35DC ;Je-li X zaporne cislo,ohlas chybu PUSH AF ;Uschovej X a vytvor jedno misto v pracovnim LD BC,#0001 ;prostoru RST #30 POP AF ;Vyzvedni X a vloz jej do mista v pracovnim LD (DE),A ;prostoru CALL #2AB2 ;Uloz parametry tohoto retezce na zasobnik EX DE,HL ;kalkulatoru RET ;Zamen ukazatele a vrat se 35DC RST #08 ;Ohlas:Integer out of range DEFB #0A Funkce "VAL" & "VAL$" --------------------- Doplnek: #1D "VAL" a #18 "VAL$" Podprogram provadi funkce VAL X$ a VAL$ X$.Pri obsluze VAL X$ se provede ci- selne ohodnoceni vyrazu a vysledek se ulozi jako posledni hodnota na zasobnik kalkulatoru.Pri obsluze VAL$ X$ se provede retezcove ohodnoceni vyrazu a para- metry retezce se ulozi jako posledni hodnota na zasobniku.Doplnek vstupuje v B. MONITOR ROM - ZX Spectrum - 134 - FUNKCE "CODE" ------------- Doplnek: #1C "CODE" Podprogram provede funkci CODE A$ a vraci kod prvniho znaku retezce A$ nebo 0, pokud byl retezec A$ nulovy. 3669 CALL #2BF1 ;Vyzvedni parametry retezce LD A,B ;Testuj delku a pokud je nulova,skoc OR C JR Z,#3671 LD A,(DE) ;Vyzvedni kod prvniho znaku a pred navratem 3671 JP #2D28 ;jej uloz na zasobnik kalkulatoru FUNKCE "LEN" ------------ Doplnek: #1E "LEN" Podprogram provede funkci LEN A$ a vraci delku retezce jako posledni hodnotu na zasobniku kalkulatoru. 3674 CALL #2BF1 ;Vyzvedni parametry retezce a proved navrat JP #2D2B ;pres STACK-BC,ktery ulozi posledni hodnotu Podprogram "DECREASE THE COUNTER" --------------------------------- Doplnek: #35 "DEC-JR-NZ" Podprogram je vyuzivan pouze rutinou SERIES GENERATOR a ve skutecnosti prova- di instrukci DJNZ,ale citacem je promenna BREG a ne registr B. 367A EXX ;Prepni na zrcadlove registry PUSH HL ;a uschovej ukazatel na dalsi literal LD HL,#5C67 ;HL ukazuje na BREG a dekrementuj ho DEC (HL) POP HL ;Obnov ukazatel na dalsi literal JR NZ,#3687 ;Skoc pri nenulovem BREG INC HL ;Prekroc dalsi literal EXX ;Prepni na hlavni registry RET Podprogram "JUMP" ----------------- Doplnek: #33 "JUMP" Podprogram provede nepodmineny skok pri zavolani literalem #33.Je vyuzivan podprogramy DECREASE THE COUNTER a JUMP ON TRUE. 3686 EXX ;Prepni na zrcadlove registry 3687 LD E,(HL) ;Vyzvedni delku skoku do E' LD A,E ;V reg. A se vytvori #00 pro kladna a #FF pro RLA ;zaporna cisla a je prevedena do D' SBC A,A LD D,A ADD HL,DE ;H'L' obsahuje cilovou adresu EXX ;Prepni na hlavni registry RET Podprogram "JUMP ON TRUE" ------------------------- Doplnek: #00 "JUMP TRUE" Podprogram provede podmineny skok,jestlize "posledni hodnota" na zasobniku kalkulatoru je pravdiva.Jeji adresa je v DE. 368F INC DE ;Posun ukazatel na 3.bajt cisla,ktery je bud 0 INC DE ;nebo 1 a vyzvedni jej do A LD A,(DE) DEC DE ;Opet ukazuj na prvni bajt DEC DE ;Je treti bajt nula? AND A ;Proved skok,kdyz neni nulovy (=pravda) JR NZ,#3686 EXX ;Prepni na zrcadlove registry INC HL ;Prekroc literal udavajici delku skoku EXX ;Prepni na hlavni registry RET Podprogram "END-CALC" --------------------- Doplnek: #38 "END-CALC" Podprogram ukonci operaci RST #28 369B POP AF ;Zahod adresu zpetnych navratu do kalkulatoru EXX ;Prepni na zrcadlove registry EX (SP),HL ;Uloz adresu z H'L' na zasobnik EXX ;Prepni na hlavni registry RET ;Skoc na drivejsi adresu z H'L' MONITOR ROM - ZX Spectrum - 136 - DEFB #A1 ;STK-jedna 2*W,1 DEFB #03 ;odecitani 2*W-1=Z DEFB #88 ;serie-08 Z 1. DEFB #13 ;exponent #63 DEFB #36,(#00,#00,#00) 2. DEFB #58 ;exponent #68 DEFB #65,#66,(#00,#00) 3. DEFB #9D ;exponent #6D DEFB #78,#65,#40,(00) 4. DEFB #A2 ;exponent #72 DEFB #60,#32,#C9,(#00) 5. DEFB #E7 ;exponent #77 DEFB #21,#F7,#AF,#24 6. DEFB #EB ;exponent #7B DEFB #2F,#B0,#B0,#14 7. DEFB #EE ;exponent #7E DEFB #7E,#BB,#94,#58 8. DEFB #F1 ;exponent #81 DEFB #3A,#7E,#F8,#CF 2^w DEFB #E3 ;GET-MEM-3 2^W,N DEFB #38 ;konec vypoctu CALL #2DD5 ;Do registru A je vlozena absolutni hodnota N mod 256 JR NZ,#3705 ;Skoc dopredu pri zapornem N JR C,#3703 ;Ohlas chybu je-li ABS N > 256 (#FF) ADD A,(HL) ;Pricti ABS N k exponentu JR NC,#370C ;Skoc,je-li e>255 3703 RST #08 ;Ohlas:Number to big DEFB #05 3705 JR C,#370E ;Vysledek ma byt nula,jestlize N<255 (dec) SUB (HL) ;Odecti ABS N od exponentu,protoze N bylo JR NC,#370E ;zaporne.Vysledek bude nula pro e<0 NEG ;Minus e je zmeneno na plus e 370C LD (HL),A ;Vloz exponent e RET 370E RST #28 ;Pouzij kalkulator a vloz exponent e=0 DEFB #02 ;vymaz DEFB #A0 ;STK-nula DEFB #38 ;konec vypoctu RET Funkce prirozeneho logaritmu ---------------------------- Doplnek: #25 "LN" Tento podprogram provadi funkci LN X a je druhym ze ctyr podprogramu,ktere pouzivaji podprogram "SERIES GENERATOR" k vytvareni Cebysevovych polynomu. Aproximace LN X je nalezena nasledovne: a) Testuje se X a je ohlasena chyba C,pokud X neni kladne. b) Dale je X rozdeleno na exponent e' a mantisu X'=X/(2^e'),kde X'>=0.5, ale X<1 c) Jsou formovany pozadovane hodnoty y1 nebo y2.Jestlize X>0.8 pak y1 = e'*LN2,jinak y2 = (e'-1)*LN2 d) Jestlize X'>0.8,pak je na zasobnik ulozena hodnota X'-1,jinak 2*X'- 1. e) Jestlize X'>0.8,pak bude argument z = 2.5*X'-3,jinak z = 5*X'-3.Ve vsech pripadech pak musi platit,ze -1<=z<=1 (coz je podminka pro konvergenci rady) f) K vytvoreni pozadovane funkce se pouzije podprogram "SERIES GENERATOR" g) Nakonec se uzije obycejne nasobeni a scitani a LN X se vraci jako posledni hodnota na zasobniku kalkulatoru 3713 RST #28 ;Proved krok a) x DEFB #3D ;RE-STACK x (v plne FP forme) DEFB #31 ;zdvojeni x,x DEFB #37 ;>0 x (1/0) DEFB #00 ;skok-pravda x DEFB #04 ;na 371C,VALID x DEFB #38 ;konec vypoctu 371A RST #08 ;Ohlas: Invalid argument DEFB #09 371C DEFB #A0 ;STK-nula x,0 - proved krok b) DEFB #02 ;vymaz x DEFB #38 ;konec vypoctu x LD A,(HL) ;Exponent e jde do registru A LD (HL),#80 ;X snizeno na X' CALL #2D28 ;Na zasobniku je: X',e RST #28 ; x',e DEFB #34 ;STK-data x',e,128 (dekadicky) DEFB #38 ;exponent #88 x',e DEFB #00,(#00,#00,#00) DEFB #03 ;odecitani x',e DEFB #01 ;zamena e',x' - proved krok c) DEFB #31 ;zdvojeni e',x',x' DEFB #34 ;STK-data e',x',x',0.8 (dekadicky) DEFB #F0 ;exponent #80 DEFB #4C,#CC,#CC,#CD MONITOR ROM - ZX Spectrum - 138 - 3783 RST #28 ; x DEFB #3D ;RE-STACK x DEFB #34 ;STK-data x,1/2(2*pi) DEFB #EE ;exponent #7E DEFB #22,#F9,#83,#6E DEFB #04 ;nasobeni x/(2*pi) DEFB #31 ;zdvojeni x/(2*pi),x/(2*pi) DEFB #A2 ;STK-polovina x/(2*pi),x/(2*pi),+0.5 DEFB #0F ;scitani x/(2*pi),x/(2*pi),+0.5 DEFB #27 ;INT 1C46 x/(2*pi),INT(x/(2*pi),+0.5) DEFB #03 ;odecitani 174C x/(2*pi),INT(x/(2*pi),+0.5)=y Poznamka: pricteni 0.5 a provedeni INT zaokrouhli vysledek na nejblizsi cele cislo. DEFB #31 ;zdvojeni y,y DEFB #0F ;scitani 2*y DEFB #31 ;zdvojeni 2*y,2*y DEFB #0F ;scitani 4*y DEFB #31 ;zdvojeni 4*y,4*y DEFB #2A ;ABS 4*y,ABS(4*y) DEFB #A1 ;STK-jedna 4*y,ABS(4*y),1 DEFB #03 ;odecitani 4*y,ABS(4*y)-1=z DEFB #31 ;zdvojeni 4*y,z,z DEFB #37 ;>0 4*y,z,(1/0) DEFB #C0 ;ST-MEM-0 MEM-0 obsahuje vysledek testu DEFB #00 ;skok-pravda 4*y,z DEFB #04 ;na 37A1,ZPLUS 4*y,z DEFB #02 ;vymaz 4*y DEFB #38 ;konec vypoctu 4*y=v ( ad a) ) RET Po provedeni skoku pokracuj zde. 37A1 DEFB #A1 ;STK-jedna 4*y,z,1 DEFB #03 ;odecitani 4*y,z-1 DEFB #01 ;zamena z-1,4*y DEFB #36 ;<0 Z-1,(1/0) DEFB #00 ;skok-pravda z-1 DEFB #02 ;na 37A8,YNEG z-1 DEFB #1B ;negace 1-z 37A8 DEFB #38 ;konec vypoctu 1-z=v ( ad b) ) RET ; z-1=v ( ad c) ) Funkce "COS" ------------ Doplnek: #20 "COS" Podprogram vraci posledni hodnotu jako aproximaci COS X.Pouziva vyraz: COS X=SIN(PI*W/2),kde -1<=W<=1.Pri derivaci podle X pouziva podprogram vysle- dek testu z predchoziho podprogramu.Tento je ulozen v MEM-0.Podprogram pokra- cuje skokem do podprogramu SINE v bode C-ENT a vraci posledni hodnotu COS X. 37AA RST #28 ; X DEFB #39 ;GET-argument V DEFB #2A ;ABS ABS V DEFB #A1 ;STK-jedna ABS V,1 DEFB #03 ;odecitani ABS V-1 DEFB #E0 ;GET-MEM-0 ABS V-1,(1/0) DEFB #00 ;skok-pravda ABS V-1 DEFB #06 ;na #37B7,C-ENT ABS V-1=W DEFB #1B ;negace 1-ABS V DEFB #33 ;skok 1-ABS V DEFB #03 ;na #37B7,C-ENT 1-ABS V=W Funkce "SINUS" -------------- Doplnek: #1F "SIN" Podprogram je tretim ze ctyr,ktere pouzivaji podprogram "SERIES GENERATOR" k vytvareni Cebysevovych polynomu.Aproximace SIN X je nalezena nasledovne: a) Argument X je redukovan a v tomto pripade se provede primo W=V.Povsimnete si,ze -1<=W<=1 (pro konvergenci rady) b) Je vytvoren argument Z,takovy ze Z=2*W*W-1 c) Pouzije se "SERIES GENERATOR" k ziskani (SIN(PI*W/2))/W d) Konecne prostym nasobenim se ziska hodnota SIN X 37B5 RST #28 ; X DEFB #39 ;GET-argument W - proved krok a) 37B7 DEFB #31 ;zdvojeni W,W - proved krok b) DEFB #31 ;zdvojeni W,W,W DEFB #04 ;nasobeni W,W*W DEFB #31 ;zdvojeni W,W*W,W*W DEFB #0F ;scitani W,2*W*W DEFB #A1 ;stk-jedna W,2*W*W,1 DEFB #03 ;odecitani W,2*W*W-1=Z DEFB #86 ;serie-06 W,Z - proved krok c) MONITOR ROM - ZX Spectrum - 140 - 1. DEFB #10 ;exponent #60 DEFB #B2,(#00,#00,#00) 2. DEFB #13 ;exponent #63 DEFB #0E,(#00,#00,#00) 3. DEFB #55 ;exponent #65 DEFB #E4,#8D,(#00,#00) 4. DEFB #58 ;exponent #68 DEFB #39,#BC,(#00,#00) 5. DEFB #5B ;exponent #6B DEFB #98,#FD,(#00,#00) 6. DEFB #9E ;exponent #6E DEFB #00,#36,#75,(#00) 7. DEFB #A0 ;exponent #70 DEFB #DB,#E8,#B4,(#00) 8. DEFB #63 ;exponent #73 DEFB #42,#C4,(#00,#00) 9. DEFB #E6 ;exponent #76 DEFB #B5,#09,#36,#BE 10. DEFB #E9 ;exponent #79 DEFB #36,#73,#1B,#5D 11. DEFB #EC ;exponent #7C DEFB #D8,#DE,#63,#BE 12. DEFB #F0 ;exponent #80 DEFB #61,#A1,#B3,#0C Po poslednim pruchodu smyckou je posledni hodnota: a.) ATN X/X b.) ATN (-1/X)/(-1/X) c.) ATN (-1/X)/(-1/X) DEFB #04 ;nasobeni a.) W,ATN X - proved krok d) ; b.) W,ATN(-1/X) ; c.) W,ATN(-1/X) DEFB #0F ;scitani ATN X DEFB #38 ;konec vypoctu RET ;Posledni hodnota na zasobniku kalkulatoru je ATN X Funkce "ARCSIN" --------------- Doplnek: #22 "ASN" Podprogram vraci realne cislo mezi -PI/2 a PI/2,ktere se rovna hodnote uhlu v radianech jehoz SIN je X.Jestlize Y=ASN X,potom X=SIN Y.Podprogram pouziva trigonometrickou identitu: TAN(Y/2) = SIN Y/1(1+COS Y) 3833 RST #28 ; X DEFB #31 ;zdvojeni X,X DEFB #31 ;zdvojeni X,X,X DEFB #04 ;nasobeni X,X*X DEFB #A1 ;STK-jedna X,X*X,1 DEFB #03 ;odcitani X,X*X-1 DEFB #1B ;negace X,1-X*X DEFB #28 ;SQR X,SQR(1-X*X) DEFB #A1 ;STK-jedna X,SQR(1-X*X),1 DEFB #0F ;scitani X,1+SQR(1-X*X) DEFB #05 ;deleni X/(1+SQR(1-X*X))=TAN (Y/2) DEFB #24 ;ATN Y/2 DEFB #31 ;zdvojeni Y/2,Y/2 DEFB #0F ;scitani Y=ASN X DEFB #38 ;konec vypoctu RET ;Posledni hodnota na zasobniku kalkulatoru je ASN X Funkce "ARCCOS" --------------- Doplnek: #23 "ACS" Podprogram provede ACS X a vraci realne cislo od nuly do PI vcetne,ktere je rovno velikosti uhlu v radianech jehoz COS je X. 3843 RST #28 ; X DEFB #22 ;ASN ASN X DEFB #A3 ;STK-PI/2 ASN X,PI/2 DEFB #03 ;odecitani ASN X-PI/2 DEFB #1B ;negace PI/2-ASN X = ACS X DEFB #38 ;konec vypoctu RET MONITOR ROM - ZX Spectrum - 142 - Seznam navesti monitoru serazeny podle adres ******************************************** 0000 START 0605 SAVE-ETC 0BC1 PR-ALL-5 0008 ERROR-1 0621 SA-SPACE 0BD3 PR-ALL-6 0010 PRINT-A-1 0629 SA-BLANK 0BDB PO-ATTR 0018 GET-CHAR 0642 REPORT-F 0BFA PO-ATTR-1 001C TEST-CHAR 0644 SA-NULL 0C08 PO-ATTR-2 0020 NEXT-CHAR 064B SA-NAME 0C0A PO-MSG 0028 FP-CALC 0652 SA-DATA 0C10 PO-TOKENS 0030 BC-SPACES 0670 REPORT-2 0C14 PO-TABLE 0038 MASK-INT 0672 SA-V-OLD 0C22 PO-EACH 0048 KEY-INT 0685 SA-V-NEW 0C35 PO-TRSP 0053 ERROR-2 068F SA-V-TYPE 0C3B PO-SAVE 0055 ERROR-3 0692 SA-DATA-1 0C41 PO-SEARCH 0066 RESET 06A0 SA-SCR$ 0C44 PO-STEP 0070 NO-RESET 06C3 SA-CODE 0C55 PO-SCR 0074 CH-ADD+1 06E1 SA-CODE-1 0C86 REPORT-5 0078 TEMP-PIR2 06F0 SA-CODE-2 0C88 PO-SCR-2 007D SKIP-OVER 06F5 SA-CODE-3 0CD2 PO-SCR-3 0090 SKIPS 06F9 SA-CODE-4 0CF0 PO-SCR-3A 028E KEY-SCAN 0710 SA-TYPE-3 0D00 REPORT-D 0296 KEY-LINE 0716 SA-LINE 0D02 PO-SCR-4 029F KEY-3KEYS 0723 SA-LINE-1 0D1C PO-SCR-4A 02A1 KEY-BITS 073A SA-TYPE-0 0D2D PO-SCR-4B 02AB KEY-DONE 075A SA-ALL 0D4D TEMPS 02BF KEYBOARD 0767 LD-LOOK-H 0D5B TEMPS-1 02C6 K-ST-LOOP 078A LD-TYPE 0D65 TEMPS-2 02D1 K-CH-SET 07A6 LD-NAME 0D6B CLS 02F1 K-NEW 07AD LD-CH-PR 0D6E CLS-LOWER 0308 K-END 07CB VR-CONTRL 0D87 CLS-1 0310 K-REPEAT 07E9 VR-CONT-1 0D89 CLS-2 031E K-TEST 07F4 VR-CONT-2 0D8E CLS-3 032C K-MAIN 0800 VR-CONT-3 0D94 CL-CHAN 0333 K-DECODE 0802 LD-BLOCK 0DA0 CL-CHAN-A 0341 K-E-LET 0806 REPORT-R 0DAF CL-ALL 034A K-LOOK-UP 0808 LD-CONTRL 0DD9 CL-SET 034F K-KLC-LET 0819 LD-CONT-1 0DEE CL-SET-1 0364 K-TOKENS 0825 LD-CONT-2 0DF4 CL-SET-2 0367 K-DIGIT 082E LD-DATA 0DFE CL-SC-ALL 0382 K-8-&-9 084C LD-DATA-1 0E00 CL-SCROLL 0389 K-GRA-DGT 0873 LD-PROG 0E05 CL-SCR-1 039D K-KLC-DGT 08AD LD-PROG-1 0E0D CL-SCR-2 03B2 K-@-CHAR 08B6 ME-CONTRL 0E19 CL-SCR-3 03B5 BEEPER 08D2 ME-NEW-LP 0E44 CL-LINE 03D1 BE-IX+3 08D7 ME-OLD-LP 0E4A CL-LINE-1 03D3 BE-IX+1 08DF ME-OLD-L1 0E4D CL-LINE-2 03D6 BE-H&L-LP 08EB ME-NEW-L2 0E80 CL-LINE-3 03F2 BE-AGAIN 08F0 ME-VAR-LP 0E88 CL-ATTR 03F6 BE-END 08F9 ME-OLD-VP 0E9B CL-ADDR 03F8 BEEP 0901 ME-OLD-V1 0EAC COPY 0425 BE-I-OK 0909 ME-OLD-V2 0EB2 COPY-1 0427 BE-OCTAVE 0912 ME-OLD-V3 0EC9 COPY-2 046C REPORT-B 091E ME-OLD-V4 0ECD COPY-BUFF 04C2 SA-BYTES 0921 ME-VAR-L1 0ED3 COPY-3 04D0 SA-FLAG 0923 ME-VAR-L2 0EDA COPY-END 04D8 SA-LEADER 092C ME-ENTER 0EDF CLEAR-PRB 04EA SA-SYNC-1 093E ME-ENT-1 0EE7 PRB-BYTES 04F2 SA-SYNC-2 0955 ME-ENT-2 0EF4 COPY-LINE 04FE SA-LOOP 0958 ME-ENT-3 0EFD COPY-L-1 0505 SA-LOOP-P 0970 SA-CONTRL 0F0C COPY-L-2 0507 SA-START 0991 SA-1-SEC 0F14 COPY-L-3 050E SA-PARITY 09F4 PRINT-OUT 0F18 COPY-L-4 0511 SA-BIT-2 0A23 PO-BACK-1 0F1E COPY-L-5 0514 SA-BIT-1 0A38 PO-BACK-2 0F2C EDITOR 051A SA-SET 0A3A PO-BACK-3 0F30 ED-AGAIN 0525 SA-8-BITS 0A3D PO-RIGHT 0F38 ED-LOOP 053C SA-DELAY 0A4F PO-ENTER 0F6C ED-CONTR 053F SA/LD-RET 0A5F PO-COMMA 0F81 ADD-CHAR 0552 REPORT-D 0A69 PO-QUEST 0F8B ADD-CH-1 0554 SA/LD-END 0A6D PO-TV-2 0F92 ED-KEYS 0556 LD/BYTES 0A75 PO-2-OPER 0FA9 ED-EDIT 056B LD-BREAK 0A7A PO-1-OPER 0FF3 ED-DOWN 0574 LD-WAIT 0A7D PO-TV-1 1001 ED-STOP 0580 LD-LEADER 0A80 PO-CHANGE 1007 ED-LEFT 058F LD-SYNC 0A87 PO-CONT 100C ED-RIGHT 05A9 LD-LOOP 0AAC PO-AT-ERR 1011 ED-CUR 05B3 LD-FLAG 0ABF PO-AT-SET 1015 ED-DELETE 05BD LD-VERIFY 0AC2 PO-TAB 101E ED-IGNORE 05C2 LD-NEXT 0AD0 PO-SPACE 1024 ED-ENTER 05C4 LD-DEC 0AD9 PO-ABLE 1026 ED-END 05C8 LD-MARKER 0ADC PO-STORE 1031 ED-EDGE 05CA LD-8-BITS 0AF0 PO-ST-E 103E ED-EDGE-1 05E3 LD-EDGE-2 0AFC PO-ST-PR 1051 ED-EDGE-2 05E7 LD-EDGE-1 0BB6 PR-ALL-3 1059 ED-UP 05ED LD-SAMPLE 0BB7 PR-ALL-4 106E ED-LIST MONITOR ROM - ZX Spectrum - 144 - 1D03 FOR 2089 INPUT 2535 S-SCRN$-S 1D10 F-USE-1 2096 INPUT-1 25AF S-SCRN-LP 1D16 F-REORDER 20AD INPUT-2 255A S-SC-MTCH 1D34 F-L&S 20C1 IN-ITEM-1 255D S-SC-ROWS 1D64 F-LOOP 20D8 IN-ITEM-2 2573 S-SCR-NXT 1D7C F-FOUND 20ED IN-ITEM-3 257D S-SCR-STO 1D84 REPORT-I 20FA IN-PROMPT 2580 S-ATTR-S 1D86 LOOK-PROG 211A IN-PR-1 25AF S-U-PLUS 1D8B LOOL-P-1 211C IN-PR-2 25B3 S-QUOTE 1DA3 LOOK-P-2 2129 IN-PR-3 25BE S-Q-AGAIN 1DAB NEXT 213A IN-VAR-1 25CB S-Q-COPY 1DD8 REPORT-1 2148 IN-VAR-2 25D9 S-Q-PRMS 1DDA NEXT-LOOP 215E IN-VAR-3 25DB S-STRING 1DE2 NEXT-1 2161 IN-VAR-4 25E8 S-BRACKET 1DE9 NEXT-2 2174 IN-VARS-5 25F5 S-FN 1DEC READ-3 219B IN-VARS-6 25F8 S-RND 1DED READ 21AF IN-NEXT-1 2625 S-RND-END 1E08 REPORT-E 21B2 IN-NEXT-2 2627 S-PI 1E0A READ-1 21B9 IN-ASSIGN 2630 S-PI-END 1E1E READ-2 21CE REPORT-C 2634 S-INKEY$ 1E27 DATA 21D0 IN-STOP 2660 S-IK$-STK 1E2C DATA-1 21D4 REPORT-H 2665 S-INK$-EN 1E37 DATA-2 21D6 IN-CHAN-K 2668 S-SCREEN$ 1E39 PASS-BY 21E1 CO-TEMP-1 2672 S-ATTR 1E42 RESTORE 21E2 CO-TEMP-2 267B S-POINT 1E45 REST-RUN 21F2 CO-TEMP-3 2684 S-ALPHNUM 1E4F RANDOMIZE 21FC CO-TEMP-4 268D S-DECIMAL 1E5A RAND-1 2211 CO-TEMP-5 26B5 S-STK-DEC 1E5F CONTINUE 2228 CO-TEMP-6 26B6 S-SD-SKIP 1E67 GO-TO 2234 CO-TEMP-7 26C3 S-NUMERIC 1E73 GO-TO-2 223E CO-TEMP-8 26C9 S-LETTER 1E7A OUT 2244 REPORT-K 26DD S-CONT-1 1E80 POKE 2246 CO-TEMP-9 26DF S-NEGATE 1E85 TWO-PARAM 2257 CO-TEMP-A 2707 S-NO-TO-$ 1E8E TWO-P-1 2258 CO-TEMP-B 270D S-PUSH-PO 1E94 FIND-INT1 226C CO-CHANGE 2712 S-CONT-2 1E99 FIND-INT2 2273 CO-TEMP-C 2713 S-CONT-3 1E9C FIND-I-1 227D CO-TEMP-D 2723 S-OPERTR 1E9F REPORT-B 2287 CO-TEMP-E 2734 S-LOOP 1EA1 RUN 2294 BORDER 274C S-STK-LST 1EAC CLEAR 22A6 BORDER-1 275B S-SYNTEST 1EAF CLEAR-RUN 22AA PIXEL-ADD 2761 S-RPORT-C 1EB7 CLEAR-1 22CB POINT-SUB 2764 S-RUNTEST 1EDA REPORT-M 22D4 POINT-LP 2770 S-LOOPEND 1EDC CLEAR-2 22DC PLOT 2773 S-TIGHTER 1EED GO-SUB 22E5 PLOT-SUB 2788 S-NOT-AND 1F05 TEST-ROOM 22F0 PLOT-LOOP 2790 S-NEXT 1F15 REPORT-4 22FD PL-TST-IN 27BD S-FN-SBRN 1F1A FREE-MEM 2303 PLOT-END 27D0 SF-BRKT-1 1F23 RETURN 2307 STK-TO-BC 27D9 SF-ARGMTS 1F36 REPORT-7 2314 STK-TO-A 27E4 SF-BRKT-2 1F3A PAUSE 2320 CIRCLE 27E6 SF-RPRT-C 1F3D PAUSE-1 233B C-R-GRE-1 27E9 SF-FLAG-6 1F49 PAUSE-2 2347 PUSH 27F4 SF-SYN-EN 1F4F PAUSE-END 235A C-ARC-GE1 27F7 SF-RUN 1F54 BREAK-KEY 2382 DRAW 2802 SF-ARGMT1 1F60 DEF-FN 238D DR-3-PRMS 2808 SF-FND-DF 1F6A DEF-FN-1 23A3 DR-SIN-NZ 2812 REPORT-P 1F7D DEF-FN-2 23C1 DR-PRMS 2814 SF-CP-DEF 1F86 DEF-FN-3 23C4 PUSH 2825 SF-NOT-FD 1F89 DEF-FN-4 2420 DRW-STEPS 2831 SF-VALUES 1F94 DEF-FN-5 2425 ARC-LOOP 2843 SF-ARG-LP 1FA6 DEF-FN-6 2439 ARC-START 2852 SF-ARG-VL 1FBD DEF-FN-7 245F ARC-END 2885 SF-R-BR-2 1FC3 UNSTACK-Z 2477 LINE-DRAW 288B REPORT-Q 1FC9 LPRINT 247D CD-PRMS-1 288D SF-VALUE 1FCD PRINT 2495 USE-252 28AB FN-SKPOVR 1FCF PRINT-1 2497 DRAW-SAVE 28B2 LOOK-VARS 1FDF PRINT-2 24B7 DRAW-LINE 28D4 V-CHAR 1FE5 PRINT-3 24C4 DL-X-GE-Y 28DE V-STR-VAR 1FF2 PRINT-4 24CB DL-LARGER 28E3 V-TEST-FN 1FF5 PRINT-CR 24CE DL-L-LOOP 28EF V-RUN/SYN 1FFC PR-ITEM-1 24D4 D-L-DIAG 28FD V-RUN 200E PR-ITEM-2 24DB D-L-HR-VT 2900 V-EACH 201E PR-AT-TAB 24DF DL-STEP 2912 V-MATCHES 2024 PR-ITEM-3 24EC D-L-PLOT 2913 V-SPACES 203C PR-STRING 24F7 D-L-RANGE 2929 V-GET-PTR 2045 PR-END-Z 24F9 REPORT-B 292A V-NEXT 2048 PR-ST-END 24FB SCANNING 2932 V-80-BYTE 204E PR-POSN-1 24FF S-LOOP-1 2934 V-SYNTAX 2061 PR-POSN-2 250F S-QUOTE-S 293E V-FOUND-1 2067 PR-POSN-3 2522 S-2-COORD 293F V-FOUND-2 206E PR-POSN-4 252D S-RPORT-C 2943 V-PASS 2070 STR-ALTER 2530 SYNTAX-Z 294B V-END MONITOR ROM - ZX Spectrum - 146 - 3501 NOT 35DC REPORT-B 370E RSLT-ZERO 3506 LESS-0 35DE VAL 3713 LN 3507 SIGN-TO-C 360C V-RPORT-C 371A REPORT-A 350B FP-0/1 361F STR$ 371C VALID 351B OR 3645 READ-IN 373D GRE.8 3524 NO 365F R-I-STORE 3783 GET-ARGT 352D STR-&-NO 3669 CODE 37A1 ZPLUS 353B NO-L-EQL 3671 STK-CODE 37A8 YNEG 3543 EX-OR-NOT 3674 LEN 37AA COS 354E NU-OR-STR 367A DEC-JR-NZ 37B5 SIN 3559 STRINGS 3686 JUMP 37B7 C-ENT 3564 BYTE-COMP 3687 JUMP-2 37DA TAN 356B SECND-LOW 368F JUMP-TRUE 37E2 ATN 3572 BOTH-NULL 369B END-CALC 37F8 SMALL 3575 SEC-PLUS 36A0 N-MOD-M 37FA CASES 3585 FRST-LESS 36AF INT 3833 ASN 3588 STR-TEST 36B7 X-NEG 3843 ACS 358C END-TESTS 36C2 EXIT 384A SQR 359C STRS-ADD 36C4 EXP 3851 TO-POWER 35B7 OTHER-STR 3703 REPORT-6 385D XISO 35BF STK-PNTRS 3705 N-NEGTV 386A ONE 35C9 CHR$ 370C RESULT-OK 386C LAST MONITOR ROM - ZX Spectrum - 148 - APPENDIX ******** BASIC PROGRAMS FOR THE MAIN SERIES ---------------------------------- The following BASIC programs have been included as they give a good illustra- tion of how Chebyshev polynomials are used to produce the approximations to the functions SIN,EXP,LN and ATN. The series generator: This subroutine is called by all the "function" programs 500 REM SERIES GENERATOR,ENTER 510 REM USING THE COUNTER BREG 520 REM AND ARRAY-A HOLDING THE 530 REM CONSTANTS. 540 REM FIRST VALUE IN Z. 550 LET M0=2*Z 560 LET M2=0 570 LET T=0 580 FOR I=BREG TO 1 STEP -1 590 LET M1=M2 600 LET U=T*M0-M2+A(BREG+1-I) 610 LET M2=T 620 LET T=U 630 NEXT I 640 LET T=T-M1 650 RETURN 660 REM LAST VALUE IN T. In the above subroutine the variable are: Z - the entry value T - the exit value M0 - MEM-0 M1 - MEM-1 M2 - MEM-2 I - the counter for BREG U - a temporary variable for T A(1) to A(BREG) - the constants BREG - the number of constants to be used. To see how the Chebyshev polynomials are generated,record on paper the values of U,M1,M2 and T through the lines 550 to 630,passing,say,6 times through the loop,and keeping the algebraic expressions for A(1) to A(6) without substitu- ting numerical values.Then record T-M1.The multipliers of the constants A(1) to A(6) will then be the required Chebyshev polynomials.More precisely,the multiplier of A(1) will be 2*T ind.5(Z),for A(2) it will be 2*T ind.4(Z) and so on to 2*T ind.1(Z) for A(5) and finally T ind.0(Z) for A(6). Note that T ind.0(Z)=1, T ind.1(Z)=Z and, for n>=2, T ind.n(Z)=2*Z*T ind.n-1(Z)-T ind.n-2(Z). SIN X ----- 10 REM DEMONSTRATION FOR SIN X 20 REM USING THE 'SERIES GENERATOR' 30 DIM A(69) 40 LET A(1)=-.000000003 50 LET A(2)=0.000000592 60 LET A(3)=-.000068294 70 LET A(4)=0.004559008 80 LET A(5)=-.142630785 90 LET A(6)=1.276278962 100 PRINT 110 PRINT "ENTER START VALUE IN DEGREES" 120 INPUT C 130 CLS 140 LET C=C-10 150 PRINT "BASIC PROGRAM","ROM PROGRAM" 160 PRINT "-------------","-----------" 170 PRINT 180 FOR J=1 TO 4 190 LET C=C+10 200 LET Y=C/360-INT (C/360+.5) 210 LET W=4*Y 220 IF W > 1 THEN LET W=2-W 230 IF W < -1 THEN LET W=W-2 240 LET Z=2*W*W-1 250 LET BREG=6 260 REM USE "SERIES GENERATOR" 270 GO SUB 550 280 PRINT TAB 6;"SIN";C;" DEGREES" 290 PRINT 300 PRINT T*W,SIN (PI*C/180) 310 PRINT 320 NEXT J 330 GO TO 100 MONITOR ROM - ZX Spectrum - 150 - LN X ---- 10 REM DEMONSTRATION FOR LN X 20 REM USING THE 'SERIES GENERATOR' 30 LET D=0 (This makes D the first variable) 40 DIM A(12) 50 LET A(1)=-.0000000003 60 LET A(2)=0.0000000020 70 LET A(3)=-.0000000127 80 LET A(4)=0.0000000823 90 LET A(5)=-.0000005389 100 LET A(6)=0.0000035828 110 LET A(7)=-.0000243013 120 LET A(8)=0.0001693953 130 LET A(9)=-.0012282837 140 LET A(10)=0.0094766116 150 LET A(11)=-.0818414567 160 LET A(12)=0.9302292213 170 PRINT 180 PRINT "ENTER START VALUE" 190 INPUT C 200 CLS 210 PRINT "BASIC PROGRAM","ROM PROGRAM" 220 PRINT "-------------","-----------" 230 PRINT 240 LET C=SQR C 250 FOR J=1 TO 4 260 LET C=C*C 270 IF C=0 THEN STOP (STOP with 'invalid argument') 280 LET D=C 290 LET V=PEEK 23627+256*PEEK23628+1 300 LET N=PEEK V-128 (N holds e') 310 POKE V,128 320 IF D <= 0.8 THEN GO TO 360 (D holds X') 330 LET S=D-1 340 LET Z=2.5*D-3 350 GO TO 390 360 LET N=N-1 370 LET S=2*D-1 380 LETZ=5*D-3 390 LET R=N*0.6931471806 (R holds N*LN 2) 400 LET BREG=12 410 REM USE 'SERIES GENERATOR' 420 GO SUB 550 430 PRINT TAB 8;"LN ";C 440 PRINT 450 PRINT S*T+R,LN C 460 PRINT 470 NEXT J 480 GO TO 170 NOTES: I. When C is entered this program calculates and prints LN C,LN (C**2), LN (C**4) and LN (C**8).It also prints the values obtained by using the ROM program.For a specimen of results,try entering these values: 1.1;0.9;300;0.004;1E5 (for overflow) and 1E-5 (STOP as 'invalid argument'). II. The constants A(1) to A(12) in lines 50 to 160 can be obtained by integrating 5*LN(4* (X+1)/5)/(4*X-1) over the interval U=0 to PI,after first multiplying by COS(N*U) for each constant(i.e. for N=1,2,...,12) and substituting COS U=2*X-1.Each result should then be divided by PI. MONITOR ROM - ZX Spectrum - 152 - The expansion for LN X and ATN X,given algebraically, will be: (2048*Z^11-5632*Z^9+5632*Z^7-2464*Z^5+440*Z^3-22*Z)*A(1) + (1024*Z^10-2560*Z^8+2240*Z^6-800*Z^4+100*Z^2-2)*A(2) + (512BZ^9-1152*Z^7+864*Z^5-240+Z^3+18*Z)*A(3) + (256BZ^8-512*Z^6+320*Z^4-64*Z^2+2)*A(4) + (128*Z^7-224*Z^5+112*Z^3-14*Z)*A(5) + (64*Z^6-96*Z^4+36*Z^2-2)*A(6) + (32*Z^5-40*Z^3+10*Z)*A(7) + (16*Z^4-16Z^2+2)*A(8) + (8*Z^3-6*Z)*A(9) + (4*Z^2-2)*A(10) + (2*Z)*A(11) + A(12) THE 'DRAW' ALGORITHM -------------------- The following BASIC program illustrates the essential parts of the DRAW opera- tion whe being used to produce a straight line.The program in its present form only allows for lines where X>Y. 10 REM DRAW 255,175 PROGRAM 20 REM SET ORIGIN 30 LET PLOTx=0: LET PLOTy=0 40 REM SET LIMITS 50 LET X=255: LET Y=175 60 REM SET INCREMENT, i 70 LET I=X/2 80 REM ENTER LOOP 90 FOR B=X TO 1 STEP -1 100 LET A=Y+i 110 IF X>A THEN GOTO 160 120 REM UP A PIXEL ON THIS PASS 130 LET A=A-X 140 LET PLOTy=PLOTy+1 150 REM RESET INCREMENT, i 160 LET i=A 170 REM ALWAIS ALONG ONE PIXEL 180 LET PLOTx=PLOTx+1 190 REM NOW MAKE A PLOT 200 PLOT PLOTx,PLOTy 210 NEXT B A complete algorithm is to found in the following program,as a subroutine that will 'DRAW A LINE' from the last position to X,Y. THE 'CIRCLE' ALGORITHM ---------------------- The following BASIC program illustrates how the CIRCLE command produces its circles.Initially the number of arcs requied is calculated.Then a set of para- meters is prepared in the 'memory area' and the 'calculator stack'.The arcs are then drawn by repeated calls to the line drawing subroutine that on each call draws a single line from the 'last position' to the position 'X,Y'.Note: In the ROM program there is a final 'closing' line but this feature has not been included here. 10 REM A CIRCLE PROGRAM 20 LET X=127: LET Y=87: LET Z=87 30 REM How many arcs ? 40 LET ARCS=4*INT (INT (ABS (PI*SQR Z )+0.5)/4)+4 50 REM Set up memory area; M0-M5 60 LET M0=X+Z 70 LET M1=0 80 LET M2=2*Z*SIN (PI/ARCS) 90 LET M3=1-2*(SIN (PI/ARCS)^2 100 LET M4=SIN (2*PI/ARCS) 110 LET M5=2*PI 120 REM Set up stack; Sa-Sd 130 LET Sa=X+Z 140 LET Sb=Y-Z*SIN (PI/ARCS) 150 LET Sc=Sa 160 LET Sd-Sb 170 REM Initialise COORDS 180 POKE 23677,Sa: POKE 23678,Sb 190 LET M0=Sd 200 REM 'DRAW THE ARCS' 210 LET M0=M0+M2 220 LET Sc=Sc+M1 230 LET X=Sc-PEEK 23677 240 LET Y=M0-PEEK 23678 250 GOSUB 510 260 LET ARCS=ARCS-1: IF ARCS=0 THEN STOP 270 LET MM1=M1 280 LET M1=M1*M3-M2*M4 290 LET M2=MM1*M4+M2*M3 300 GOTO 210 MONITOR ROM - ZX Spectrum - 154 - 3032 PUSH AF ;Save the sign byte in A INC A ;Make any FF in A into 00 OR E ;Test all 3 bytes now for zero OR D JR NZ,3040 ;(ADD-STORE) Jump if not -65536 POP AF ;Clear the stack LD (HL),#80 ;Enter 80 hex into second byte DEC HL ;Point to the first byte LD (HL),#91 ;Enter 91 hex into the first byte JR 3049 ;(ADD-RSTOR) Jump to set the pointer and exit 3040 POP AF ;(ADD-STORE) Restore the sign byte in A LD (HL),A ;Store it on the stack INC HL ;Point to the next location LD (HL),E ;Store the low byte of the result INC HL ;Point to the next location LD (HL),D ;Store the high byte of the result DEC HL ;Move the pointer back to DEC HL ;address the first byte of the result DEC HL 3049 POP DE ;(ADD-RSTOR) Restore STKEND to DE RET ;Finished 6. The above amendment (i.e. 15 extra bytes) with the ommssion of bytes 3223 to 323E inclusive from 'truncate' should solve the problems.It would be nice to be able to test this.The calls of INT-STORE should not lead to 00 FF 00 00 00 being stacked.In 'multiply' the number will lead to overflow if it occurs,since 65536 will set the carry flag; so 'long' multiplication will be used.As noted at 30E5,the 5 bytes starting there could probably be omitted if the above amendments were made.'Negate' avoids stacking 00 FF 00 00 00 by treating zero separately and returning it unaltered.Truncate deals separately with -65536,as noted above.SGN stores only 1 and -1. MONITOR ROM - ZX Spectrum - 156 - 1007 Cursor left editing (kurzor vlevo pri editaci) 36 100C Cursor right editing (kurzor doprava pri editaci) 36 1015 DELETE editing (vymaz pri editaci) 36 101E ED-IGNORE 36 1024 ENTER editing (ENTER pri editaci) 36 1031 ED-EDGE 36 1059 Cursor up editing (kurzor nahoru pri editaci) 37 1076 ED-SYMBOL 37 107F ED-ERROR 37 1097 CLEAR-SP 37 10A8 Keyboard input (klavesovy vstup) 37 111D Lower screen copying (kopirovani dolni casti obrazovky) 38 1190 SET-HL 39 11A7 REMOVE-FP 39 THE EXECUTIVE ROUTINES (Provadeci programy) ------------------------------------------- 11B7 NEW command 39 11CB Main entry (Initialisation) (hlavni vstup) 39 11DA RAM-CHECK 39 12A2 Main execution loop (hlavni provadeci smycka) 41 1391 Report messages (chybova hlaseni) 42 155D MAIN-ADD 43 15AF Initial channel information (inicializacni kanalove informace) 43 15C6 Initial stream data (iniciacni proudova data) 44 15D4 WAIT-KEY (cekej na stisk klavesy) 44 15E6 INPUT-AD 44 15EF Main printing (hlavni vypis) 44 1601 CHAN-OPEN (otevreni kanalu) 44 1615 CHAN-FLAG 45 162D Channel code look-up table (tabulka kanalovych kodu) 45 1634 Channel K flag (vlajka kanalu) 45 1642 Channel S flag (vlajka kanalu) 45 164D Channel P flag (vlajka kanalu) 45 1652 ONE-SPACE (jedno misto) 45 1655 MAKE-ROOM (vytvoreni prostoru) 45 1664 POINTERS (systemove ukazatele) 45 168F Collect a line number (vyzvednuti cisla radku) 46 169E RESERVE 46 16B0 SET-MIN 46 16D4 Reclaim the edit-line (zruseni editacniho radku) 47 16DB INDEXER 47 16E5 CLOSE # command 47 1716 CLOSE stream look table (tabulka pro uzavirani proudu) 47 171E Stream data (proudova data) 48 1736 OPEN # command 48 177A OPEN stream look-up table (tabulka pro otevirani proudu) 49 1793 CAT,ERASE,FORMAT, & MOVE commands 49 1795 LIST & LLIST commands 49 1795 AUTO-LIST 49 17F5 LLIST 50 17F9 LIST 50 1855 Print a whole BASIC line (vytisteni celeho basickeho radku) 50 18B6 NUMBER 51 18C1 Print a flashing character (vytisknuti blikajiciho znaku) 51 18E1 Print the cursor (vytisknuti kurzoru) 51 190F LN-FETCH 52 1925 Printing characters in a BASIC line(tisk znaku basickeho radku) 52 196E LINE-ADDR (adresa radku) 53 1980 Compare line numbers (porovnani cisel radku) 53 1988 Find each statement (hledani jednotlivych prikazu) 53 19B8 NEXT-ONE (dalsi) 54 19DD Difference (rozdil) 54 19E5 Reclaiming (zruseni) 54 19FB E-LINE-NO 54 1A1B Report and line number printing (vypis hlaseni a cisla radku) 55 BASIC LINE AND COMMAND INTERPRETATION (Interpretace basickych radku a prikazu) ------------------------------------------------------------------------------ 1A48 Syntax tables (tabulky syntaxe) 55 1B17 Main parser (BASIC interpreter) 57 1B28 Statement loop (prikazova smycka) 57 1B52 SCAN-LOOP (vyhodnocovaci smycka) 58 1B6F SEPARATOR (oddelovac) 58 1B76 STMT-RET 58 1B8A LINE-RUN 58 1B9E LINE-NEW 59 1BB2 REM command 59 1BB3 LINE-END 59 1BBF LINE-USE 59 1BD1 NEXT-LINE 59 1BEE CHECK-END 60 1BF4 STMT-NEXT 60 MONITOR ROM - ZX Spectrum - 158 - 2C02 DIM command 102 2C88 ALPHANUM 104 2C8D ALPHA 104 2C9B Decimal to floating-point 104 2D1B NUMERIC 105 2D22 STK-DIGIT (uloz cislo) 105 2D28 STACK-A (uloz A) 105 2D2B STACK-BC (uloz BC) 105 2D3B Integer to floating-point 106 THE ARITMETIC ROUTINES (Aritmeticke programy) --------------------------------------------- 2D4F E-format to floating-point 106 2D7F INT-FETCH 107 2D8E INT-STORE 107 2DA2 Floating-point to BC 107 2DC1 LOG (2^A) 108 2DD5 Floating-point to A 108 2DE3 Print a floating-point number (vytiskni FP cislo) 108 2F8B CA=10*A+C 112 2F9B Prepare to add (priprava na scitani) 113 2FBA Fetch two numbers (vyzvedni dve cisla) 113 2FDD Shift addend (posun scitanec) 114 3004 ADD-BACK (pricti zpet) 114 300F Subtraction (#03) (odcitani) 114 3014 Addition (#0F) (scitani) 114 30A9 HL=HL*DE 116 30C0 Prepare to multiply or divide(priprava na nasobeni nebo deleni) 116 30CA Multiplication (#04) (nasobeni) 117 31AF Division (#05) (deleni) 119 3214 Integer truncation towards zero (#3A) (celociselne zaokrouhleni smerem k nule) 120 3293 RE-STACK TWO 121 3297 RE-STACK (#3D) 121 THE FLOATING-POINT CALKULATOR (Kalkulator s pohyblivou desetinnou teckou) ------------------------------------------------------------------------- 32C5 Table of constants (tabulka konstant) 122 32D7 Table of addresses (tabulka adres) 123 335B CALCULATE 123 33A1 Delete (#02) 124 33A2 Single operation (#3B) 124 33A9 Test 5-spaces 124 33B4 Stack number (uloz cislo) 124 33C0 Move a floating-point number (#31) 125 33C6 Stack literals (#34) 125 33F7 Skip constants (preskoceni konstant) 125 3406 Memory location (pametove misto) 126 340F Get from memory area (#E0 etc.) (vyzvednuti z pametove oblasti) 126 341B Stack a constant (#A0 etc.) (ulozeni konstanty) 126 342D Store in memory area (#C0 etc.) (ulozeni v pametove oblasti) 126 343C EXCHANGE (#01) 127 3449 Series generator (#86 etc.) 127 346A Absolute magnitude (#2A) 128 346E Unary minus (#1B) 128 3492 Signum (#29) 128 34A5 IN (#2C) 128 34AC PEEK (#2B) 129 34B3 USR number (#2D) 129 34BC USR string (#19) 129 34E9 TEST-ZERO (test na nulu) 129 34F9 Greater than zero (#37) (>0) 130 3501 NOT (#30) 130 3506 Less than zero (#36) (<0) 130 350B Zero or one (nula nebo jedna) 130 351B OR (#07) 130 3524 Number AND number (#08) 130 352D String AND number (#10) 131 353B Comparison (#09-#0E, #11-#16) 131 359C String concatenation (#17) 132 35B7 STK-PNTRS 132 35C9 CHR$ (#2F) 132 35DE VAL and VAL$ (#1D,#18) 132 361F STR$ (#2E) 133 3645 Read-in (#1A) 133 3669 CODE (#1C) 134 3674 LEN (#1E) 134 367A Decrease the counter (#35) (dekrementuj citac) 134 3686 Jump (#33) (skok) 134 368F Jump on true (#00) (skok, je-li vyraz pravdivy) 134 369B END-CALC (#38) (konec vypoctu) 134 36A0 Modulus (#32) 135 36AF INT (#27) 135 36C4 Exponential (#26) 135