e kodov ASCII nabor operatorov IF...THEN srazu nachinaet proveryat' kakaya klavisha byla nazhata, otsylaya programmu na sootvetstvuyushchuyu proce- duru. V sluchae 2-bajtnyh kodov upravlenie peredaetsya otdel'noj procedure. V etoj procedure funkciya RIGHT$ ubiraet levyj simvol, kotoryj prosto raven nulyu i tol'ko otmechaet rasshirennyj kod. Zatem ispol'zuetsya funkciya ASC dlya preobrazovaniya stroki iz sim- vol'noj formy v chislovuyu. I, nakonec, vtoraya seriya operatorov IF...THEN proveryaet poluchivsheesya chislo na sootvetstvuyushchie Alt-A, Alt-B i t.d. 100 C$ = INKEY$:IF C$="" THEN 100 'ozhidaem nazhatiya klavishi 110 IF LEN(C$)=2 THEN 500 'esli rassh. kod - na 500 120 IF C$="a" OR C$="A" THEN GOSUB 1100 'eto A? 130 IF C$="b" OR C$="B" THEN GOSUB 1200 'eto B? 140 IF C$="c" OR C$="C" THEN GOSUB 1300 'eto C? . . 500 C$=RIGHT$(C$,1) 'poluchaem vtoroj bajt rassh. koda 510 C=ASC(C$) 'preobrazuem ego v chislo 520 IF C=30 THEN GOSUB 2100 'eto Alt-A? 530 IF C=48 THEN GOSUB 2200 'Alt-B? 540 IF C=46 THEN GOSUB 2300 'Alt-C? Otmetim, chto v stroke 120 (i posleduyushchih) mozhno takzhe ispol'zo- vat' chislovye znacheniya kodov ASCII: 120 IF C=97 OR C=65 THEN GOSUB 1100 Konechno nado snachala preobrazovat' C$ v formu celogo chisla, kak eto sdelano v stroke 510. V programmah, v kotoryh trebuetsya dlin- naya cepochka takih operatorov, mozhno sekonomit' mesto, izmenyaya C takim obrazom, chtoby ona vsegda sootvetstvovala libo verhnemu, libo nizhnemu registru. Snachala nuzhno tol'ko proverit', chto kod ASCII C$ nahoditsya v pravil'nom diapazone. Zatem ustanovit', men'she li etot kod 91, togda my imeem delo s simvolom verhnego registra. Esli eto tak, to nado dlya perevoda v nizhnij registr dobavit' 32. V protivnom sluchae, ostavit' vse kak est'. Posle etogo budet dostatochno bolee korotkogo operatora, takogo kak IF C=97 THEN ... Vot kod etoj procedury: 500 C=ASC(C$) 'poluchaem ASCII kod simvola 510 IF NOT ((C>64 AND C<91)OR(C>96 AND C<123)) THEN ... 520 IF C<91 THEN C=C+32 'privodim vse k nizhnemu registru 530 IF C=97 THEN ... '... nachinaem proverku znachenij Srednij uroven'. Funkcii 7 i 8 preryvaniya 21H ozhidayut vvoda simvola, esli bufer klaviatury pust, a kogda on poyavlyaetsya, to ne vyvoditsya na ekran. Pri etom funkciya 8 opredelyaet Ctrl-Break (i iniciiruet proceduru obrabotki Ctrl-Break[3.2.8]), a funkciya 7 ne reagiruet na nego. V oboih sluchayah simvol vozvrashchaetsya v AL. Kogda AL soderzhit ASCII 0, to poluchen rasshirennyj kod. Povtorite preryvanie i v AL poya- vitsya vtoroj bajt rasshirennogo koda. ;---poluchaem vvedennyj simvol MOV AH,7 ;nomer funkcii INT 21H ;ozhidaem vvod simvola CMP AL,0 ;proverka na rasshirennyj kod JE EXTENDED_CODE ;esli da, to na osobuyu proceduru . ;inache, kod simvola v AL ;---procedura obrabotki rasshirennyh kodov EXTENDED_CODE: INT 21H ;berem vtoroj bajt koda CMP AL,75 ;proveryaem na "strelku-vlevo" JNE C_R ;esli net, to sled. proverka JMP CURSOR_LEFT;esli da, to na proceduru C_R: CMP AL,77 ;sravnivaem dal'she i t.d. BIOS obespechivaet proceduru, kotoraya predostavlyaet te zhe voz- mozhnosti, chto i funkcii MS DOS. Pomestite 0 v AH i vyzovite pre- ryvanie 16H. Funkciya ozhidaet vvoda simvola i vozvrashchaet ego v AL. V etom sluchae i rasshirennye kody obrabatyvayutsya za odno preryva- nie. Esli v AL soderzhitsya 0, to v AH budet soderzhat'sya nomer rasshirennogo koda. Pri eto ne obrabatyvaetsya Ctrl-Break. ;---zhdem nazhatiya klavishi MOV AH,0 ;nomer funkcii ozhidaniya vvoda INT 16H ;poluchaem vvedennyj kod CMP AL,0 ;proverka na rasshirennyj kod JE EXTENDED_CODE ;esli da, to na spec. proceduru . ;inache simvol v AL ;---procedura obrabotki rasshirennogo koda EXTENDED_CODE: CMP AH,75 ;berem rasshirennyj kod iz AH ;i t.d. 3.1.4 Ozhidanie nazhatiya klavishi i eho na ekran. Pri vvode dannyh i teksta, eho vvodimyh simvolov obychno vy- daetsya na ekran. Pri etom takie simvoly kak vozvrat karetki ili zaboj perevodyatsya v sootvetstvuyushchie peremeshcheniya kursora, a ne izobrazhayutsya kak ASCII simvoly dlya etih kodov. Vydacha eha prois- hodit v toj pozicii, gde predvaritel'no byl ustanovlen kursor i tekst avtomaticheski perenositsya na sleduyushchuyu stroku pri dostizhe- nii konca tekushchej. Perenos na sleduyushchuyu stroku ne trebuet spe- cial'nogo koda, poskol'ku simvoly pomeshchayutsya v sleduyushchuyu poziciyu bufernoj pamyati displeya, kotoraya predstavlyaet iz sebya odnu dlin- nuyu stroku, vklyuchayushchuyu vse 25 strok displeya. Vysokij uroven'. V Bejsike nado perehvatit' vvedennyj simvol s pomoshch'yu operato- ra INKEY$, kak pokazano v [3.1.3]. Zatem ego nado vyvesti na ekran, prezhde chem poluchat' takim zhe sposobom sleduyushchij. Dlya vyvo- da mozhno ispol'zovat' libo operator PRINT, libo operatorom POKE pryamo pomestit' simvol v videobufer, ispol'zuya otobrazhenie v pamyat', kak pokazano v [4.3.1] (bufer nachinaetsya s segmenta pamya- ti &HB000 dlya monohromnogo adaptera i s &HB800 - dlya cvetnogo adaptera). Pri ispol'zovanii PRINT ne zabud'te postavit' v konce dvoetochie, inache budet avtomaticheski dobavlen kod vozvrata karet- ki. Nizhe privedeny primery ispol'zovaniya oboih metodov. Pri etom ne provoditsya nikakogo analiza na upravlyayushchie simvoly. Vvodimye simvoly formiruyutsya v vide stroki dannyh v peremennoj KEYSTROKE$. 100 ' metod ispol'zuyushchij PRINT 110 LOCATE 10,40 'ustanovka kursora v poziciyu 10,40 120 KEYSTROKE$="" 'ochistka peremennoj 130 C$=INKEY$:IF C$="" THEN 130 'ozhidanie vvoda simvola 140 KEYSTROKE$=KEYSTROKE$ + C$ 'zapis' ego v peremennuyu 150 PRINT C$; 'pechat' simvola 160 GOTO 130 'priem sleduyushchego simvola 100 ' metod ispol'zuyushchij POKE 110 DEF SEG = &HB000 'ustanovka segmenta na videobufer 120 POINTER = 1678 'ukazatel' na poziciyu 10,40 130 KEYSTROKE$="" 'ochistka peremennoj 140 C$=INKEY$:IF C$="" THEN 140 'ozhidanie vvoda simvola 150 KEYSTROKE$=KEYSTROKE$ + C$ 'zapis' ego v peremennuyu 160 POKE POINTER,ASC(C$) 'pomeshchenie simvola v videobufer 170 POINTER=POINTER + 2 'sdvig ukazatelya na sleduyushchij simvol 180 GOTO 140 'priem sleduyushchego simvola Srednij uroven'. Funkciya 1 preryvaniya 21H ozhidaet vvoda simvola, esli bufer klaviatury pust, a zatem vyvodit ego na ekran v tekushchuyu poziciyu kursora. Obrabatyvaetsya Ctrl-Break, poetomu mozhet vypolnyat'sya procedura obrabotki Ctrl-Break [3.2.8]. Vvedennyj simvol vozvra- shchaetsya v AL. Pri vvode rasshirennogo koda AL soderzhit ASCII 0. Dlya polucheniya v AL vtorogo bajta rasshirennogo koda nado povtorit' preryvanie. ;---poluchenie vvedennogo simvola MOV AH,1 ;nomer funkcii INT 21H ;ozhidaem nazhatiya klavishi CMP AL,0 ;rasshirennyj kod? JE EXTENDED_CODE ;esli da, to na spec. proceduru . ;inache simvol nahoditsya v AL ;---procedura obrabotki rasshirennyh kodov INT 21H ;poluchaem v AL nomer koda CMP AL,77 ;proverka na "kursor-vpravo" JNE C_R ;esli net, proverka sleduyushchego JMP CURSOR_RIGHT ;esli da, to na proceduru C_R: CMP AL,75 ;... i t.d. |ta funkciya polnost'yu ignoriruet klavishu <ESC>. Klavisha tabu- lyacii interpretiruetsya normal'no. Klavisha zaboj sdvigaet kursor na odnu poziciyu vlevo, no simvol, nahodyashchijsya v etoj pozicii ne stiraetsya. Klavisha <Enter> vyzyvaet peremeshchenie kursora v pervuyu poziciyu tekushchej stroki (net avtomaticheskogo perevoda stroki). 3.1.5 Priem simvola bez ozhidaniya. Nekotorye programmy, rabotayushchie v real'nom vremeni ne mogut ostanavlivat'sya i zhdat' nazhatiya klavishi; oni prinimayut simvol iz bufera klaviatury tol'ko v te momenty, kogda eto udobno dlya prog- rammy. Naprimer, bezdejstvie processora vo vremya ozhidaniya vvoda s klaviatury ostanovilo by vse dejstviya na ekrane v igrovoj prog- ramme. Napomnim, chto legko proverit' pust ili net bufer klaviatu- ry, ispol'zuya metody, opisannye v [3.1.2]. Vysokij uroven'. Nado prosto ispol'zovat' INKEY$, ne pomeshchaya ego v cikl: 100 C$=INKEY$ 'poluchenie simvola 110 IF C$ <> "" THEN...'esli simvol vveden, to ... 120 ... 'inache net simvola v bufere Srednij uroven'. Funkciya 6 preryvaniya 21H - eto edinstvennyj sposob poluchit' vvedennyj simvol bez ozhidaniya. |ta funkciya ne daet eha na ekran i ne raspoznaet Ctrl-Break. Pered vyzovom preryvaniya v DL dolzhno byt' pomeshcheno 0FFH. V protivnom sluchae funkciya 6 sluzhit sovershen- no protivopolozhnoj celi - pechataet v tekushchej pozicii kursora simvol, nahodyashchijsya v DL. Flag nulya ustanavlivaetsya v 1, esli bufer klaviatury pust. Esli simvol prinyat, to on pomeshchaetsya v AL. Kod ASCII 0 indiciruet rasshirennyj kod i dlya polucheniya nomera koda preryvanie dolzhno byt' povtoreno. MOV AH,6 ;nomer funkcii DOS MOV DL,0FFH ;zapros vvoda s klaviatury INT 21H ;poluchenie simvola JZ NO_CHAR ;perehod esli net simvola CMP AL,0 ;proverka na rasshirennyj kod JE EXTENDED_CODE ;esli da, to na spec. proceduru ... ;inache v AL kod ASCII EXTENDED_CODE: INT 21H ;poluchaem nomer rasshirennogo koda ... ;nomer koda v AL 3.1.6 Poluchenie stroki simvolov. I Bejsik i MS DOS predostavlyayut procedury dlya priema stroki simvolov. Oni avtomaticheski povtoryayut procedury vvoda odnogo simvola, opisannye v predydushchih razdelah, ozhidaya vvoda vozvrata karetki, signaliziruyushchego okonchanie stroki. Konechno dolzhna byt' otvedena pamyat', dostatochnaya dlya priema vseh simvolov stroki, i dolzhna zapisyvat'sya dlina kazhdoj stroki dlya togo, chtoby otdelit' odnu stroku ot drugoj. |to delaetsya s pomoshch'yu deskriptorov stro- ki, kotorye sostoyat iz odnogo ili bolee bajtov, soderzhashchih adres i/ili dlinu stroki. V Bejsike pervye dva bajta deskriptora stroki soderzhat adres stroki, a sami deskriptory hranyatsya v massive otdel'no ot strok. Dlina stroki hranitsya v tret'em bajte 3-bajt- nogo deskriptora. S drugoj storony, DOS hranit dlinu stroki pryamo v nachale samoj stroki i dlya programmy dostatochno znat' polozhenie stroki v pamyati. Vysokij uroven'. Bejsik mozhet prinimat' s i bez avtomaticheskogo eha na ekrane. Bolee prosto delaetsya vvod s ehom, tak kak on vypolnyaetsya vstroennoj funkciej vvoda stroki INPUT. INPUT avtomaticheski sobi- raet vvodimye simvoly, vyvodya ih na ekran po mere polucheniya. Pri nazhatii klavishi <Enter> vvod zavershaetsya i znachenie stroki pris- vaivaetsya ukazannoj peremennoj (posylaemyj klavishej <Enter> kod ASCII 13 ne dobavlyaetsya k stroke). INPUT dopuskaet vozmozhnost' redaktirovaniya stroki, predostavlyaemuyu DOS, poetomu opechatki mogut byt' ispravleny pered vvodom stroki. INPUT prinimaet chisla v vvide stroki i avtomaticheski preobrazuet ih v chislovuyu formu, esli dlya vvoda budet ukazano imya chislovoj peremennoj. Nakonec, INPUT mozhet vydavat' na ekran stroku, zaprashivayushchuyu pol'zovatelya o trebuemoj informacii. Takaya stroka mozhet byt' dlinoj do 254 simvolov. Esli ee dlina bol'she, to lishnie simvoly ignoriruyutsya. Osnovnaya forma etogo operatora INPUT "zapros", imya_peremennoj. Polnoe opisanie etogo opertora sm. v rukovodstve po Bejsiku. 110 INPUT "Enter your name: ",NAME$ 'prinimaet imya kak stroku 120 INPUT "Enter your age: ",AGE% 'prinimaet vozrast kak chislo Operator INPUT neadekvaten, kogda v vvodimoj stroke mogut vstrechat'sya rasshirennye kody, takie kak kody upravleniya kursorom v polnoekrannom tekstovom redaktore. V etom sluchae trebuetsya ispol'zovat' funkciyu INKEY$ dlya priema kazhdogo simvola, zatem proveryat' vvod na rasshirennye kody, vydelyat' simvoly upravleniya kursorom, takie kak vozvrat karetki, i tol'ko posle etogo vyvo- dit' na ekran te simvoly, kotorye sleduet vyvodit'. Pri etom upravlyayushchie simvoly takzhe vklyuchayutsya po odnomu v konec strokovoj peremennoj. Tekstovye fajly predstavlyayut soboj nabor takih stro- kovyh peremennyh. V punkte [3.1.8] Vy najdete proceduru vvoda s klaviatury, v kotoroj funkciya INKEY$ ispo'zuetsya ukazannym obra- zom. Srednij uroven'. Funkciya 0AH preryvaniya 21H pozvolyaet vvodit' stroku dlinoj do 254 simvolov, vydavaya eho na terminal. |ta procedura prodolzhaet vvod postupayushchih simvolov do teh por, poka ne nazhata klavisha vozvrat karetki. DS:DX ukazyvaet na adres pamyati, kuda dolzhna byt' pomeshchena stroka. Pri vhode pervyj bajt v etoj pozicii dolzhen soderzhat' chislo bajtov, otvodimyh dlya etoj stroki. Posle togo kak stroka vvedena, vtoroj bajt dast chislo real'no vvedennyh simvo- lov. Sama stroka nachinaetsya s tret'ego bajta. Nado otvesti dostatochno pamyati dlya stroki nuzhnoj dliny plyus dva bajta dlya deskriptora stroki i odin dobavochnyj bajt dlya vozv- rata karetki. Kogda Vy ustanavlivaete maksimal'nuyu dlinu stroki v pervom bajte, to ne zabud'te dobavit' 1 dlya vozvrata karetki. Kod vozvrata karetki - ASCII 13 - vvoditsya kak poslednij simvol stro- ki, no on ne uchityvaetsya v rezul'tate, kotoryj funkciya pomeshchaet vo vtoroj bajt deskriptora stroki. Takim obrazom, dlya polucheniya 50-simvol'noj stroki nado otvesti 53 bajta pamyati i pomestit' v pervyj bajt ASCII 51. Posle vvoda 50 simvolov vtoroj bajt budet soderzhat' ASCII 50, a 53-j bajt otvedennoj pamyati - ASCII 13. ;---v segmente dannyh STRING DB 53 DUP(?) ;oblast' dlya stroki 50 simvolov ;---poluchenie stroki s klaviatury LEA DX,STRING ;DS:DX ukazyvayut na adres stroki MOV BX,DX ;pust' BX tozhe ukazyvaet na stroku MOV AL,51 ;ustanovka dliny stroki (+1 dlya CR) MOV [BX],AL ;posylaem v 1-j bajt deskriptora MOV AH,0AH ;nomer funkcii INT 21H ;poluchaem stroku ;---proverka dliny stroki MOV AH,[BX]+1 ;teper' dlina v AH V etoj procedure mozhno ispol'zovat' vozmozhnosti redaktirovaniya stroki MS DOS. Nazhatie klavishi zaboj ili "strelka-vlevo" udalyaet simvol s ekrana, a takzhe ne pomeshchaet ego v pamyat'. Rabotaet kla- visha tabulyacii, rasshirennye kody ignoriruyutsya, pustye stroki dopuskayutsya (imeetsya vvidu vozvrat karetki, kotoromu ne predshest- vuet drugogo simvola). Na terminale pri dostizhenii pravogo kraya stroka perenositsya na sleduyushchuyu stroku, a pri dostizhenii pravogo nizhnego ugla ekran sdvigaetsya na stroku vverh. Kogda vvoditsya bol'she simvolov, chem otvedeno mesta dlya stroki, to lishnie simvoly ignoriruyutsya i vklyuchaetsya gudok dinamika. MS DOS obespechivaet i drugoj sposob polucheniya stroki, pri kotorom ne vyvoditsya eho na terminal. Funkciya 3FH preryvaniya 21H - eto funkciya vvoda obshchego naznacheniya, kotoraya chashche vsego ispol'- zuetsya pri diskovyh operaciyah. Ona trebuet predopredelennogo deskriptora fajla (file handle), kotoryj yavlyaetsya kodovym chislom, ispol'zuemym operacionnoj sistemoj dlya oboznacheniya ustrojstva vvoda/vyvoda. Dlya klavitury ispol'zuetsya deskriptor 0 i on dolzhen byt' pomeshchen v BX. Pomestite v DS:DX adres, po kotoromu dolzhna nahodit'sya stroka, a v CX - maksimal'nuyu dlinu stroki i vyzovite funkciyu: ;---chtenie stroki bez eha MOV AH,3FH ;nomer funkcii MOV BX,0 ;nomer deskriptora fajla LEA DX,STRING_BUFFER ;ukazatel' na bufer vvoda stroki MOV CX,100 ;maksimal'naya dlina stroki INT 21H ;zhdem vvoda Vvod stroki zavershaetsya nazhatiem klavishi vozvrat karetki i DOS dobavlyaet v konec stroki dva simvola: vozvrat karetki i perevod stroki (ASCII 13 i ASCII 10). Iz-za etih dobavochnyh simvolov, pri ukazanii dliny stroki 100 simvolov ona mozhet zanimat' do 102 bajt pamyati. Dlina vvedennoj stroki vozvrashchaetsya v AX i eto znachenie vklyuchaet dva simvola-ogranichitelya. 3.1.7 Proverka/ustanovka statusa klavish-pereklyuchatelej. Dva bajta, raspolozhennye v yachejkah pamyati 0040:0017 i 0040:0018 soderzhat bity, otrazhayushchie status klavishi sdviga i dru- gih klavish-pereklyuchatelej sleduyushchim obrazom: Bit Klavisha Znachenie, kogda bit = 1 0040:0017 7 Insert rezhim vstavki vklyuchen 6 CapsLock rezhim CapsLock vklyuchen 5 NumLock rezhim NumLock vklyuchen 4 ScrollLock rezhim ScrollLock vklyuchen 3 Alt klavisha nazhata 2 Ctrl klavisha nazhata 1 levyj Shift klavisha nazhata 0 pravyj Shift klavisha nazhata 0040:0018 7 Insert klavisha nazhata 6 CapsLock klavisha nazhata 5 NumLock klavisha nazhata 4 ScrollLock klavisha nazhata 3 Ctrl-NumLock rezhim Ctrl-NumLock vklyuchen ostal'nye bity ne ispol'zuyutsya Preryvanie klaviatury nemedlenno obnovlyaet eti bity statusa, kak tol'ko budet nazhata odna iz klavish-pereklyuchatelej, dazhe esli ne bylo schitano ni odnogo simvola iz bufera klaviatury. |to verno i dlya klavishi Ins, kotoraya edinstvennaya iz etih 8 klavish pomeshchaet kod v bufer (ustanovka statusa Ins menyaetsya dazhe esli v bufere net mesta dlya simvola). Otmetim, chto bit 3 po adresu 0040:0018 ustanavlivaetsya v 1, kogda dejstvuet rezhim zaderzhki Ctrl-NumLock; poskol'ku v etom sostoyanii programma priostanovlena, to etot bit nesushchestvenen. Preryvanie klaviatury proveryaet sostoyanie statusnyh bitov pered tem, kak interpretirovat' nazhatye klavishi, poetomu kogda programma menyaet odin iz etih bitov, to effekt takoj zhe, kak pri fizicheskom nazhatii sootvetstvuyushchej klavishi. Vy mozhete zahotet' ustanovit' sostoyanie klavish NumLock i CapsLock, chtoby byt' uve- rennym, chto vvod budet trebuemogo vida. Naoborot, Vasha programma mozhet nuzhdat'sya v chtenii statusa etih klavish, naprimer dlya togo, chtoby vyvesti tekushchij status na ekran. Otmetim, chto klaviatura AT pravil'no ustanavlivaet svetovye indikatory sostoyaniya klavish, dazhe esli pereklyucheny programmno. Vysokij uroven'. V dannom primere klavisha NumLock perevoditsya v rezhim, kogda klavishi dopolnitel'noj klaviatury ispol'zuyutsya dlya peremeshcheniya kursora, za schet sbrasyvaniya bita 5 po adresu 0040:0017 v 0. |to dostigaetsya za schet operacii logicheskogo "I" znacheniya, raspolo- zhennogo po etomu adresu s chislom 223 (cepochka bitov 11011111B - opisanie logiki bitovyh operacij sm. v Prilozhenii B). Rezul'tat pomeshchaetsya v bajt statusa. V primere zatem vosstanavlivaetsya znachenie etogo bita v 1, za schet logicheskogo "ILI" s 32 (00100000B). 100 DEF SEG = &H40 'ustanavlivaem segment na oblast' 110 STATUSBYTE=PEEK(&H17) 'BIOS i berem bajt statusa 120 NEWBYTE=STATUSBYTE AND 223 'obnulyaem bit 5 130 POKE(&H17,NEWBYTE) 'posylaem novoe znachenie statusa CHtoby, naoborot, vklyuchit' etot bit: 120 NEWBYTE=STATUSBYTE OR 32 'ustanavlivaem bit 5 130 POKE(&H17,NEWBYTE) 'posylaem novoe znachenie statusa Stroki 110-130 mogut byt' uplotneny k vidu: 110 POKE(&H417,PEEK(&H417)AND 223) ili 110 POKE(&H417,PEEK(&H417)OR 223) Srednij uroven'. Funkciya 2 preryvaniya 16H predostavlyaet dostup k odnomu - no tol'ko odnomu - iz bajtov statusa. |to bajt po adresu 0040:0017, kotoryj soderzhit bol'she poleznoj informacii. Bajt vozvrashchaetsya v AL. ;---proverka statusa klavishi vstavki MOV AH,2 ;nomer funkcii INT 16H ;poluchaem bajt statusa TEST AL,10000000B ;proveryaem bit 7 JZ INSERT_OFF ;esli 0, to INSERT vyklyuchen Nizkij uroven'. V dannom primere ustanavlivaetsya rezhim vstavki, za schet usta- novki bita 7 bajta statusa po adresu 0040:0017 (kotoryj adresuet- sya kak 0000:0417). SUB AX,AX ;ustanavlivaem dobavochnyj segment na MOV ES,AX ;nachalo pamyati MOV AL,10000000B ;gotovim bit 7 k ustanovke OR ES:[417H],AL ;menyaem bajt statusa 3.1.8 Napisanie procedury vvoda s klaviatury obshchego naznacheniya. Sistema kodov, ispol'zuemyh klaviaturoj, ne poddaetsya prostoj intrepretacii. Kody mogut imet' dlinu 1 ili 2 bajta i net prosto- go sootvetstviya mezhdu dlinoj koda i tem, sluzhit li on dlya obozna- cheniya simvola ili dlya upravleniya oborudovaniem. Ne vse kombinacii klavish dazhe vydayut unikal'nyj kod, poetomu neobhodimy dobavochnye usiliya, chtoby razlichit' ih. Ni kody ASCII, ni rasshirennye kody ne uporyadocheny takim obrazom, kotoryj by pozvolil ih prostuyu gruppi- rovku i proverku oshibok. Drugimi slovami, procedura vvoda s kla- viatury obshchego naznacheniya trebuet hlopotlivogo programmirovaniya. Zdes' privedeny primery na Bejsike i s ispol'zovaniem preryva- niya 16H. V nih pokazano kak svesti vmeste bol'shinstvo informacii, privedennoj v dannoj glave. Obshchij algoritm pokazan na ris. 3-3. Vysokij uroven'. Procedura obrabotki vvoda s klaviatury, napisannaya na Bejsike, mozhet delat' vse chto delaet assemblernaya procedura, za odnim isklyucheniem. Funkciya INKEY$ ne predostavlyaet dostupa k skan-ko- dam. |to oznachaet, chto Vy ne mozhete skazat' polucheny li kody ASCII 8, 9, 13 i 27 ot nazhatiya klavish <BackSpace>, <Tab>, <Enter> i <Escape> ili cherez Ctrl-H, -I, -M i -[. Razlichie mozhet byt' ustanovleno proverkoj bita statusa klavishi Ctrl, po adresu 0040:0017, v moment nazhatiya klavishi. No etot metod ne budet rabo- tat', esli vvedennyj simvol byl zapasen v bufere klaviatury v techenie nekotorogo vremeni. 100 C$=INKEY$:IF C$="" THEN 100 'poluchenie simvola 110 IF LEN(C$)=2 THEN 700 'esli rasshirennyj, to na 700 120 C=ASC(C$) 'inache berem nomer koda ASCII 130 IF C<32 THEN 300 'esli upravlyayushchij, to na 300 140 IF C<65 OR C>123 THEN 100 'prinimaem tol'ko simvoly 150 '''pishushchej mashinki i delaem s nimi, chto hotim, naprimer: 160 S$=S$+C$ 'dobavlyaem simvol k stroke 170 PRINT C$; 'vyvodim ego na ekran 180 '''... i t.d. 190 GOTO 100 'na vvod sleduyushchego simvola . . 300 '''procedura obrabotki upravlyayushchih kodov ASCII 310 DEF SEG = 0 'ukazyvaem na nachalo pamyati 320 REGISTER=PEEK(&H417) 'berem registr statusa 330 X=REGISTER AND 4 'X=4, kogda nazhat Ctrl 340 IF X=0 THEN 500 'esli ne nazhat, to na 500 350 '''esli eto kombinaciya Ctrl-bukva, to delaem chto hotim 360 IF C=8 THEN GOSUB 12000 'naprimer, perehodim na proce- 370 '''duru vyvoda ekrana pomoshchi i t.d. 380 GOTO 100 'na vvod sleduyushchego simvola . . 500 '''procedura obrabotki 4-h klavish: dekodiruet kody ASCII 8, 510 '''9, 13 i 27, kogda klavisha Ctrl ne nazhata 520 IF C=8 THEN GOSUB 5000 'obrabotka <BackSpace> 530 IF C=9 THEN GOSUB 6000 'obrabotka <Tab> 540 IF C=13 THEN GOSUB 7000 'obrabotka <CR> 550 IF C=27 THEN GOSUB 8000 'obrabotka <Esc> 560 GOTO 100 'na vvod sleduyushchego simvola . . 700 '''procedura obrabotki rasshirennyh kodov 710 C$=RIGHT$(C$,1) 'berem tol'ko 2-j bajt C$ 720 C=ASC(C$) 'perevodim v chislovuyu formu 730 '''v C - rasshirennyj kod - delaem s nim, chto hotim, naprimer 740 IF C<71 OR C>81 THEN 100 'berem tol'ko upravlenie kursorom 750 IF C=72 THEN GOSUB 3500 'obrabotka "kursor-vverh" 760 '''... i t.d. 770 GOTO 100 'na vvod sleduyushchego simvola Srednij uroven'. |tot primer otlichaetsya ot predydushchego metodom raspoznavaniya chetyreh chastnyh sluchaev Ctrl-H, -I, -M i -[. Zdes', kogda vstaet vopros o tom, voznik li ukazannyj kod pri nazhatii odnoj klavishi, ili v kombinacii s klavishej Ctrl, proveryaetsya skan-kod. |tot metod bolee pravilen, chem proverka bita statusa, tak kak skan-kod zapominaetsya v bufere klaviatury, a ustanovka bita statusa mozhet byt' izmenena. ;---poluchenie koda nazhatoj klavishi i opredelenie ego tipa NEXT: MOV AH,0 ;funkciya vvoda s klaviatury BIOS INT 16H ;poluchaem vvedennyj kod CMP AL,0 ;proverka na rasshirennyj kod JE EXTENDED_CODE ;esli da, to na spec. proceduru CMP AL,32 ;proverka na upravlyayushchij simvol JL CONTROL_CODE ;esli da, to na spec. proceduru CMP AL,65 ;esli simvol ne vhodit v nabor pishu- JL NEXT ;shchej mashinki, to berem sleduyushchij CMP AL,123 ; JL NEXT ; ;---teper' obrabatyvaem simvol v AL STOSB ;zapominaem simvol po adresu ES:DI MOV AH,2 ;funkciya vyvoda simvola na ekran MOV DL,AL ;pomeshchaem simvol v DL pered vyvodom INT 21H ;vyvodim ego na ekran . . JMP NEXT ;perehodim k sleduyushchemu simvolu ;---analiziruem upravlyayushchie kody CONTROL_CODE: CMP AL,13 ;kod ASCII 13? JNE TAB ;esli net, to sled. proverka CMP AH,28 ;inache proveryaem skan-kod <CR> JNE C_M ;esli net, to bylo Ctrl-M CALL CARRIAGE_RET;obrabotka vozvrata karetki JMP NEXT ;perehod k sleduyushchemu simvolu C_M: CALL CTRL_M ;obrabotka Ctrl-M JMP NEXT ;perehod k sleduyushchemu simvolu TAB: CMP AL,9 ;proverka na tabulyaciyu... . . CMP AL,10 ;zatem proverka drugih . . REJECT: JMP NEXT ;perehod k sleduyushchemu simvolu ;---analiz rasshirennyh kodov (2-j bajt koda v AH): EXTENDED_CODE: CMP AH,71 ;proverka nizhnej granicy JL REJECT ;esli men'she, to sled. simvol CMP AH,81 ;proverka verhnej granicy JL REJECT ;esli bol'she, to sled. simvol ;---AH soderzhit simvol upravleniya kursorom, analiziruem ego: CMP AH,72 ;"kursor-vverh"? JE C_U ;esli da, to na proceduru CMP AH,80 ;"kursor-vniz"? JE C_D ;esli da, to na proceduru . . C_U: CALL CURSOR_UP ;vyzov sootvetstvuyushchej procedury JMP NEXT ;perehod k sleduyushchemu simvolu C_D: CALL CURSOR_DOWN ;vyzov sootvetstvuyushchej procedury JMP NEXT ;perehod k sleduyushchemu simvolu 3.1.9 Pereprogrammirovanie preryvaniya klaviatury. Kogda mikroprocessor klaviatury pomeshchaet skan-kod v port A mikroshemy 8255 (adres porta 60H - sm. [1.1.1]), to pri etom vyzyvaetsya preryvanie 9. Zadacha etogo preryvaniya - preobrazovat' skan-kod simvola, osnovyvayas' na sostoyanii klavish-pereklyuchatelej, i pomestit' ego v bufer klaviatury. (Esli skan-kod sootvetstvuet klavishe-pereklyuchatelyu, to v bufer klaviatury ne pishetsya nichego, za isklyucheniem sluchaya klavishi <Ins>, a vmesto etogo preryvanie izmenyaet bajty statusa, raspolozhennye v oblasti dannyh BIOS [3.1.7]). Preryvaniya "vvoda s klaviatury" DOS i BIOS na samom dele vsego lish' preryvaniya "vvoda iz bufera klaviatury". Na samom dele oni ne raspoznayut nazhatiya klavish. Tochnee, oni chitayut interp- retaciyu vvedennyh klavish, kotoruyu obespechilo preryvanie 9. Zame- tim, chto PCjr ispol'zuet special'nuyu proceduru (INT 48H) dlya preobrazovaniya vvoda ot ego 62 klavish k 83-klavishnomu protokolu, ispol'zuemomu drugimi IBM PC. Rezul'tat etoj procedury peredaetsya preryvaniyu 9, kotoroe vypolnyaet svoyu rabotu kak obychno. Preryva- niem 49H PCjr obespechivaet special'nye neklavishnye skan-kody, kotorye potencial'no mogut ustanavlivat'sya periferijnymi ust- rojstvami, ispol'zuyushchimi infrakrasnuyu (besprovolochnuyu) svyaz' s klaviaturoj. Trebuetsya ves'ma neobychnoe primenenie, chtoby imelo smysl pe- reprogrammirovat' eto preryvanie, osobenno uchityvaya, chto MS DOS pozvolyaet Vam pereprogrammirovat' lyubuyu klavishu klaviatury [3.2.6]. Esli vse zhe Vam pridetsya pereprogrammirovat' preryvanie 9, to eta glava dast Vam osnovy dlya starta. Snachala nado prochi- tat' [1.2.3], chtoby ponimat' kak programmiruyutsya preryvaniya. V preryvanii klaviatury mozhno vydelit' tri osnovnyh shaga: 1. Prochitat' skan-kod i poslat' klaviature podtverdayushchij sig- nal. 2. Preobrazovat' skan-kod v nomer koda ili v ustanovku oegist- ra statusa klavish-pereklyuchatelej. 3. Pomestit' kod klavishi v bufer klaviatury. V moment vyzova preryvaniya skan-kod budet nahodit'sya v porte A. Poetomu snachala nado etot kod prochitat' i sohranit' na steke. Zatem ispol'zuetsya port B (adres 61H), chtoby bystro poslat' sig- nal podtverzhdeniya mikroprocessoru klaviatury. Nado prosto ustano- vit' bit 7 v 1, a zatem srazu izmenit' ego nazad v 0. Zametim, chto bit 6 porta B upravlyaet signalom chasov klaviatury. On vsegda dolzhen byt' ustanovlen v 1, inache klaviatura budet vyklyuchena. |ti adresa portov primenimy i k AT, hotya on i ne imeet mikroshemy interfejsa s periferiej 8255. Snachala skan-kod analiziruetsya na predmet togo, byla li klavi- sha nazhata (kod nazhatiya) ili otpushchena (kod osvobozhdeniya). Na vseh mashinah, krome AT, kod osvobozhdeniya indiciruetsya ustanovkoj bita 7 skan-koda v 1. Dlya AT, u kotorogo bit 7 vsegda raven 0, kod osvobozhdeniya sostoit iz dvuh bajtov: snachala 0F0H, a zatem skan-kod. Vse kody osvobozhdeniya otbrasyvayutsya, krome sluchaya kla- vish-pereklyuchatelej, dlya kotoryh delayutsya sootvetstvuyushchie izmene- niya v bajtah ih statusa. S drugoj storony, vse kody nazhatiya obra- batyvayutsya. Pri etom opyat' mogut izmenyat'sya bajty statusa kla- vish-pereklyuchatelej. V sluchae zhe simvol'nyh kodov, nado proveryat' bajty statusa, chtoby opredelit', naprimer, chto skan-kod 30 soot- vetstvuet nizhnemu ili verhnemu registru bukvy A. Posle togo kak vvedennyj simvol identificirovan, procedura vvoda s klaviatury dolzhna najti sootvetstvuyushchij emu kod ASCII ili rasshirennyj kod. Privedennyj primer slishkom korotok, chtoby ras- smotret' vse sluchai. V obshchem sluchae skan-kody sopostavlyayutsya elementam tablicy dannyh, kotoraya analiziruetsya instrukciej XLAT. XLAT prinimaet v AL chislo ot 0 do 255, a vozvrashchaet v AL 1-bajt- noe znachenie iz 256-bajtnoj tablicy, na kotoruyu ukazyvaet DS:BX. Tablica mozhet nahodit'sya v segmente dannyh. Esli v AL nahodilsya skan-kod 30, to tuda budet pomeshchen iz tablicy bajt nomer 30 (31-j bajt, tak kak otschet nachinaetsya s nulya). |tot bajt v tablice dolzhen byt' ustanovlen ravnym 97, davaya kod ASCII dlya "a". Konech- no dlya polucheniya zaglavnoj A nuzhna drugaya tablica, k kotoroj obrashchenie budet proishodit', esli status sdviga ustanovlen. Ili zaglavnye bukvy mogut hranit'sya v drugoj chasti toj zhe tablicy, no v etom sluchae k skan-kodu nado budet dobavlyat' smeshchenie, oprede- lyaemoe statusom klavish-pereklyuchatelej. Nakonec, nomera kodov dolzhny byt' pomeshcheny v bufer klaviatury. Procedura dolzhna snachala proverit', imeetsya li v bufere mesto dlya sleduyushchego simvola. V [3.1.1] pokazano, chto etot bufer ustroen kak ciklicheskaya ochered'. YAchejka pamyati 0040:001A soderzhit ukaza- tel' na golovu bufera, a 0040:001C - ukazatel' na hvost. |ti slovnye ukazateli dayut smeshchenie v oblasti dannyh BIOS (kotoraya nachinaetsya v segmente 40H) i nahodyatsya v diapazone ot 30 do 60. Novye simvoly vstavlyayutsya v yachejki bufera s bolee starshimi adre- sami, a kogda dostignuta verhnyaya granica, to sleduyushchij simvol perenositsya v nizhnij konec bufera. Kogda bufer polon, to ukaza- tel' hvosta na 2 men'she ukazatelya na golovu - krome sluchaya, kogda ukazatel' na golovu raven 30 (nachalo oblasti bufera), a v etom sluchae bufer polon, kogda ukazatel' hvosta raven 60. Dlya vstavki simvola v bufer, nado pomestit' ego v poziciyu, na kotoruyu ukazyvaet hvost bufera i zatem uvelichit' ukazatel' hvosta na 2; esli ukazatel' hvosta byl raven 60, to nado izmenit' ego znachenie na 30. Vot i vse. Shema preryvaniya klaviatury pokazana na ris. 3-4. Nizkij uroven'. |ffektivnaya procedura trebuet glubokogo produmyvaniya. V etom primere dany tol'ko samye zachatki. On prinimaet tol'ko bukvy na nizhnem i verhnem registrah, prichem vse oni zagruzheny v odnu tab- licu, v kotoroj bukvy verhnego registra nahodyatsya na 100 bajt vyshe, chem ih mladshie brat'ya. Analiziruetsya tol'ko levaya klavisha sdviga i tekushchee sostoyanie klavishi CapsLock ignoriruetsya. ;---v segmente dannyh TABLE DB 16 DUP(0) ;propuskaem 1-e 16 bajt DB 'qwertyuiop',0,0,0,0 ;verhnij ryad klaviatury DB 'asdfghjkl',0,0,0,0,0 ;srednij ryad klaviatury DB 'zxcvbnm' ;nizhnij ryad klaviatury DB 16 DUP(0) ;propusk do verhnego registra DB 'QWERTYUIOP',0,0,0,0 ;te zhe simvoly na verhnem DB 'ASDFGHJKL',0,0,0,0,0 ;registre DB 'ZXCVBNM' ; ;---v nachale programmy ustanavlivaem preryvanie CLI ;zapret preryvanij PUSH DS ;sohranyaem registr MOV AX,SEG NEW_KEYBOARD ;DS:DX dolzhny ukazyvat' na MOV DS,AX ;proceduru obrabotki MOV DX,OFFSET NEW_KEYBOARD ;preryvaniya MOV AL,9 ;nomer vektora preryvaniya MOV AH,25H ;nomer funkcii DOS INT 21H ;menyaem vektor preryvaniya POP DS ;vosstanavlivaem registr STI ;razreshaem preryvaniya Programma prodolzhaetsya, zatem ostavayas' rezidentnoj [1.3.4]. ;---eto samo preryvanie klaviatury NEW_KEYBOARD PROC FAR ;sohranyaem vse izmenyaemye PUSH AX ;registry PUSH BX ; PUSH CX ; PUSH DI ; PUSH ES ; ;---poluchaem skan-kod i posylaem signal podtverzhdeniya IN AL,60H ;poluchaem skan-kod iz porta A MOV AH,AL ;pomeshchaem kopiyu v AH PUSH AX ;sohranyaem skan-kod IN AL,61H ;chitaem sostoyanie porta B OR AL,10000000B ;ustanavlivaem bit 7 OUT 61H,AL ;posylaem izmenennyj bajt v port AND AL,01111111B ;sbrasyvaem bit 7 OUT 61H,AL ;vozvrashchaem sostoyanie porta B ;---ES dolzhen ukazyvat' na oblast' dannyh BIOS MOV AX,40H ;ustanavlivaem segment MOV ES,AX ; POP AX ;vozvrashchaem skan-kod iz steka ;---proverka klavishi sdviga CMP AL,42 ;nazhat levyj sdvig? JNE KEY_UP ;net - smotrim sleduyushchee MOV BL,1 ;da - izmenyaem bit statusa OR ES:[17H],BL ;menyaem pryamo registr statusa JMP QUIT ;vyhod iz procedury KEY_UP: CMP AL,170 ;levyj sdvig otpushchen? JNE NEXTKEY ;net - smotrim sleduyushchee MOV BL,11111110B ;da - menyaem bit statusa AND ES:[17H],BL ;menyaem pryamo registr statusa JMP QUIT ;vyhod iz procedury NEXTKEY: ;prosmotr drugih pereklyuchatelej ;---eto simvol'naya klavisha - interpretiruem skan-kod TEST AL,10000000B ;kod osvobozhdeniya klavishi? JNZ QUIT ;da - vyhodim iz procedury MOV BL,ES:[17H] ;inache berem bajt statusa TEST BL,00000011B ;klavisha sdviga nazhata? JZ CONVERT_CODE ;net - uhodim dal'she ADD AL,100 ;da - znachit zaglavnaya bukva CONVERT_CODE: MOV BX,OFFSET TABLE ;gotovim tablicu XLAT TABLE ;preobrazuem skan-kod v ASCII CMP AL,0 ;vozvrashchen 0? JE QUIT ;esli da, to na vyhod ;---kod klavishi gotov, proveryaem ne polon li bufer klaviatury MOV BX,1AH ;smeshchenie ukazatelya na golovu MOV CX,ES:[BX] ;poluchaem ego znachenie MOV DI,ES:[BX]+2 ;poluchaem ukazatel' hvosta CMP CX,60 ;golova na vershine bufera? JE HIGH_END ;da - perehodim k spec. sluchayu INC CX ;uvelichivaem ukazatel' golovy INC CX ;na 2 CMP CX,DI ;sravnivaem s ukazatelem hvosta JE QUIT ;esli ravny, to bufer polon JMP GO_AHEAD ;inache vstavlyaem simvol HIGH_END: CMP DI,30 ;proverka spec. sluchaya JE QUIT ;esli bufer polon, to vyhod ;---bufer ne polon - vstavlyaem v nego simvol GO_AHEAD: MOV ES:[DI],AL ;pomeshchaem simvol v poziciyu hvosta CMP DI,60 ;hvost v konce bufera? JNE NO_WRAP ;esli net, to dobavlyaem 2 MOV DI,28 ;inache ukazatel' hvosta = 28+2 NO_WRAP: ADD DI,2 ;poluchaem novoe znachenie hvosta MOV ES:[BX]+2,DI ;posylaem ego v oblast' dannyh ;---zavershenie preryvaniya QUIT: POP ES ;vosstanavlivaem izmenyaemye POP DI ;registry POP CX ; POP BX ; POP AX ; MOV AL,20H ;vydaem signal ob okonchanii OUT 20H,AL ;apparatnogo preryvaniya IRET ;vozvrat iz preryvaniya NEW_KEYBOARD ENDP Razdel 2. Dostup k otdel'nym klavisham. Procedura obrabotki nazhatiya klavishi dolzhna proveryat' massu razlichnyh tipov klavish i uslovij, poskol'ku kak odno-, tak i dvuhbajtnye kody mogut poyavlyat'sya v kombinacii s klavishami-perek- lyuchatelyami. Ne vse klavishi logicheski sgruppirovany, po tipu koda, kotoryj im sootvetstvuet. Naprimer, klavisha <Backspace> generi- ruet odnobajtnyj kod ASCII, a klavisha <Delete> - dvuhbajtnyj rasshirennyj kod. Klavisha Ctlr generiruet odnobajtnyj kod, kogda ona ispol'zuetsya v sochetanii s alfavitnymi klavishami i dvuhbajt- nyj kod v ostal'nyh sluchayah. |ti neregulyarnosti voznmkayut iz-za ogranichennosti nabora ASCII: preryvanie klaviatury sleduet sogla- sheniyam ASCII, kogda vozmozhno, no kogda eto nevozmozhno vydaet svoi (rasshirennye) kody. V dannom razdele perechisleny razlichnye gruppy klavish, dany ih kody i ukazany vstrechayushchiesya anomalii. V bol'shinstve sluchaev eta informaciya dostupna v menee udobnom vide iz tablic kodov ASCII i rasshirennyh kodov, privedennyh v razdele 3 etoj glavy. Zdes' obsuzhdayutsya takzhe special'nye svojstva, pripisyvaemye otdel'nym klavisham Bejsikom, a takzhe special'naya obrabotka, dlya interpreta- cii otdel'nyh klavish (takih kak zaboj), primenyaemaya v preryvaniyah DOS. 3.2.1 Ispol'zovanie klavish <BackSpace>, <Enter>, <Escape> i <Tab>. Klavishi <BackSpace>, <Enter>, <Escape> i <Tab> - edinstvennye chetyre nesimvol'nye klavishi, kotorye generiruyut odnobajtnye ko- dy ASCII. |ti kody soderzhatsya v nabore upravlyayushchih kodov [7.1.9], kotorye zanimayut pervye 32 koda v nabore ASCII. |ti chetyre koda mogut byt' polucheny takzhe kombinaciej bukvennyh klavish s klavishej Ctrl: ASCII 8 BackSpace Ctrl + H ASCII 9 Tab Ctrl + I ASCII 13 Enter Ctrl + M ASCII 27 Escape Ctrl + [ V [3.2.2] pokazano kak razlichat' nazhatie odnoj klavishi i kombina- ciyu s klavishej Ctrl. Otmetim, chto obratnaya tabulyaciya, proizvodi- maya nazhatiem kombinacii <Shift> + <Tab>, vydaet rasshirennyj kod 0;15. Nekotorye iz preryvanij obrabotki vvoda s klaviatury avtomati- cheski interpretiruyut eti chetyre special'nyh koda. V Bejsike funk- ciya INPUT reagiruet na <Backspace>, <Tab> i <Enter>. Funkciya INKEY$ ne interpretiruet ni odin iz upravlyayushchih kodov, poskol'ku u nee net avtomaticheskogo eha na ekran. Vsyu rabotu dolzhna vypol- nyat' Vasha programma. Napomnim, chto dlya upravleniya dvizheniem kur- sora Bejsik predostavlyaet funkciyu TAB. Iz preryvanij BIOS i DOS, te kotorye vydayut eho na terminal interpretiruyut takzhe klavishi <BackSpace> i <Tab>. Posle togo kak eti kody interpretiruyutsya sootvetstvuyushchim obrazom, kody ASCII vse ravno poyavlyayutsya v AL, posle chego oni mogut byt' vklyucheny v stroku simvolov ili ignori- rovany, v zavisimosti ot togo, chto trebuetsya. 3.2.2 Ispol'zovanie klavish-pereklyuchatelej: <Shift>, <Ctrl> i <Alt>. Tri tipa klavish-pereklyuchatelej zastavlyayut tol'ko drugie klavi- shi klaviatury generirovat' razlichnye kody. Kak pravilo, takie kombinacii generiruyut rasshirennye kody. No v dvuh sluchayah oni dayut kody ASCII: (1) kogda ispol'zuetsya klavisha <Shift> s klavishami alfavitno-cifrovyh simvolov i (2) nazhatie kombinacii klavish ot Ctrl-A do Ctrl-Z daet ASCII kody ot 1 do 26. Vse ostal'nye kombi- nacii dayut rasshirennye kody, perechislennye v [3.3.5]. PCjr imeet neskol'ko isklyuchenij, kotorye obsuzhdayutsya nizhe. Nedopustimye kombinacii klavish ne proizvodyat koda, voobshche. Za isklyucheniem sluchaya special'nyh kombinacij s Ctrl-Alt, odnovremen- noe nazhatie neskol'kih pereklyuchatelej privodit k tomu, chto tol'ko odin iz nih stanovitsya effektivnym, prichem prioritet u Alt, zatem Ctrl, i zatem Shift. V [3.1.7] pokazano kak proverit'