Digitális technika 2 - Megoldások a V2-es ellenőrző feladatsorhoz

A VIK Wikiből


Ezen az oldalon a régi ötkredites Digit2 ellenőrző kérdéseihez összegyűjtött megoldások vannak. A megoldások nem mindenhol teljesek vagy jók. Az új Digit2-höz már más ellenőrző feladatsort adott ki a tanszék, de nagyon sok átfedés van ezzel!

A V2-es feladatsor itt érhető el.

1. feladat

2. feladat

by Lacee (a hibákat jelezni kérem a prisonerhu@freemail.hu címen)

2. a)

Készítsen megszakítási vonalakat kezelő áramkört, amely egy 8085-ös processzoron alapuló sín RST 5.5-ös és RST 6.5-ös megszakítási vonalaira csatlakozva2 db külsô megszakítás (IT1 és IT2) fogadására alkalmas.

A külső megszakítások kezelését külön-külön áramkörök végzik, amelyek a külső megszakítás felfutó élére kérnek megszakítást és alaphelyzetbe OUT utasítással állíthatók (vagy a ResetOut jel hatására). Egy megszakítási impulzus csak egyszer kérjen megszakítást. Az IT1 megszakítás hatására a C regiszter 55h, IT2 hatására a C regiszter AAh értéket vesz fel. A megszakítási flip-flopok 11h (IT1) és 17h (IT2) címen érhetők el.

  • Készítse el a rendszer inicializálását végző főprogramot (40h címtől kezdődően)!
  • Készítse el a megszakítási szubrutinokat!
       RST55 EQU 2CH
       RST65 EQU 34H
       C1 EQU 55H  
       C2 EQU AAH
       IT1 11H
       IT2 17H

       JMP INIC
       ORG 0040H
   INIC:
       MVI A,00001100B ;RST 7.5-T LETILTJUK, A TÖBBIT ENGEDÉLYEZZÜK
       SIM     ;MASZK BEÁLLÍTÁSA
       EI      ;MEGSZAKÍTÁS ENG
       
   VAR:    JMP VAR     ;VÉGTELEN CIKLUS, AZ RST-KRE VÁR, AZOK MEGSZAKÍTJÁK

       ORG RST55   ;RST55 CÍMÉN VAN,ÍGY HA MEGSZAKÍTÁS TÖRTÉNIK, AKKOR IDE UGRIK A PROGI
   MEGSZ1: MVI C,C1        ;BEÁLLÍTJUK A KÍVÁNT ÉRTÉKET    
       OUT IT1     ;VISSZAÁLLÍTJUK AZ IO-T
       EI      ;MEGSZAKÍTÁS ÉRVÉNYRE JUTTATÁSA
       RET

       ORG RST65   ;AZ ELÕBBI MINTÁJÁRA...
   MEGSZ2: 
       MVI C,C2    
       OUT IT2
       EI
       RET

2. b)

Írjon assembly szubrutint (KONV), amely az A regiszterben megkapott byte-ot átírja a 74LS374-es regiszter bekötésének megfelelően. A szubrutin kimenete az átkonvertált byte az A regiszterben. (A szubrutin más regiszterek tartalmát nem ronthatja el!)

Írjon ellenőrző 8085-ös assembly szubrutint (ELO), amely az összes lehetséges kombinációval ellenőrzi a kimeneti regiszter bekötését. A szubrutin lefutása után a D,E regiszterpárban legyen a felismert hibák száma! (A szubrutin a D,E regiszterpár kivételével a regiszterek tartalmát nem ronthatja el!) A megoldásban használja az előző feladatban definiált KONV szubrutint! A kimeneti regiszter 0FFh I/O címen írható és 01Fh címen olvasható.


   PÉLDA1 A MÛKÖDÉSRE
       10101111    ;A BEJÖVÕ ADAT -> EZT KELL KAPNUNK A PÉLDA1-BEN: 01011111
   RRC 11010111    ;JOBBRA FORGATJUK
   AND 01010101    ;ÖSSZEÉSELJÜK  55H-VAL (MÁSNÉVEN MASZKOLÁS)
       ----------
   =   01010101 -> D   ;AZ EREDMÉNYT BEÍRJUK A (D) REG-BE
   RLC 01011111    ;AZ EREDETI ADATOT FORGATJUK BALRA
   AND 10101010    ;ÉSELJÜK AAH-VAL
       ----------
   =   00001010 -> H   ;KIMENTJÜK H-BA, A PROGIBAN NEM KELL H-BA MENTENI,MERT AZ UTANA LEVÕ PARANCS A
         VAGYOLÁS ÉS AHHOZ AZ A- TARTALMA KELL, AMI MOST PONT A H-BA RAKOTTAL EGYEZIK MEG
   H OR D
       01010101    
       00001010    
       ----------  
       01011111    ;AZ EREDMÉNY!
   PÉLDA2:
       10101110 ->EBBÕL EZT:01011101
   RRC 01010111
   AND 01010101
       ----------
   =   01010101 -> D
   RLC 01011101
   AND 10101010
       -----------
   =   00001000 -> H
   H OR D
       01010101
       00001000
       -----------
       01011101
   ;NA ÉS VÉGRE A PROGI
   KONV:   PUSH H
       PUSH D
       PUSH PSW    ;kimentjük A-t
       RRC     ;jobbra forgatunk
       ANI 01010101B   ;maszkoljuk 55H-val
       MOV D,A     ;a maszkolt byte-ot kimentjük D-be
       POP PSW     ;vissza az A-t
       RLC         ;balra forgatjuk
       ANI 10101010B   ;maszkoljuk AAH-val
       ORA D       ;összevagyoljuk D-vel
       POP D       ;POPpolgatunk
       POP H
       RET
       
   ELO:    
       PUSH PSW
       PUSH H
       PUSH B
       PUSH A  
       MVI B,0H
       LXI D,0H
   FUT:
       MOV A,B
       OUT 0FFH    ;a B 0-tól FF-ig megy, ez az összes lehetséges kombináció
       CALL KONV   ;az A-ban a B-nek megfelelő beolvasott (átkonvertált) adat lesz
       MOV C,A     
       IN  01FH        ;beolvassuk a reg tartalmát
       CMP C       ;ha A=C akkor jó (C:a B konvertált alakja, A:a közvetlenül visszaolvasott alak
       
       JZ TOVABB   ;ha B=C -> Z=1, tehát nem kell növelni a DE-t
       INX D       ;ha azonban Z=0, növeljük DE-t
   TOVABB: INR B       
       MOV A,FF
       CMP B   
       JNZ FUT     ;ha B végigpörgött, tehát elérte az FF-t, akkor kilépünk
       POP A
       POP B
       POP H
       POP PSW

2. c)

Írja meg a VIZS 8085 assembly szubrutint, amely az A regiszterben kapott értéket beírja a kimeneti regiszterbe, majd a kimenet értékét visszaolvassa és ellenőrzi, hogy a beérkezett karakter helyes-e? Hiba esetén a szubrutinból való visszatéréskor Z=1, különben Z=0 legyen!

  • A kimeneti egység K1…K8 jelei a 0ACh IO címen olvashatók vissza.
  • a kimeneti regiszter (74374) a 0AAh IO címen írható
  • A kimeneti regiszter minden második bitje (K0,K2,K4,K6) negáltan legyen kivezetve.


   VIZS:   OUT 0AAH    ;BEÍRJUK AZ A REG TARTALMÁT A KIMENETI REG-BE
       AND 55H     ;A KIMENET ÉRTÉKE NEM A BEÍRT A-VAL LESZ EGYENLÕ
       XRA FFH     ;EZÉRT MEGCSINÁLJUK SZOFTVERESEN A BYTE MINDEN MÁSODIK BITJÉNEK NEGÁLÁSÁT


   ;példa 1:a fenti műveltre (AND 55H;XRA FFH)
   kiírt adat: 
       11111111  -> ebből ezt kell kapnunk: 10101010
   AND 01010101
       -----------
       01010101
   XRA 11111111
       -----------
       10101010  ->és kész!
   ;példa 2:
   kiírt adat:
       10111011  ->ez lesz belőle: 11101110
   AND 01010101
       -----------
       00010001
   XRA 11111111
       -----------
       11101110  -> ready!


   ;és a progi folytatása
       MOV B,A     ;elmentjük B-be, mert később a visszaolvasott adat alapból az A-ba kerül és felülírja ezt
       IN 0ACH     ;visszaolvasás
       CMP B       ;a szokásos vizsgálat, A-ból kivonjuk a B-t(az ellenőrző byte-ot)
       JNZ Z1      ;és ha az eredmény nem 0 (akkor Z=0,és hiba van), a feladata pont az ellentetjét kéri
       XRA A       ;ezért a Z flaget megnegáljuk az alábbi paranccsal
       JMP VEGE
   Z1: MOV A,1H
       ORA A       
   VEGE:   RET


2. d)

Illesszen i8085-ös mikroprocesszoros rendszersínre két 8251-es soros periféria illesztő áramkört. Az „A” áramkör csak kimenetre, a „B” áramkör csak bemenetre van felprogramozva. Az „A” áramkör TxD kimenetét a „B” áramkör RxD bemenetére kell kötni. Mindkét áramkör TxC és RxC órajel bemeneteire CLK96 órajel van kötve. Inicializáláskor mindkét áramkör programozása: aszinkron üzemmód, 8 bites karakter, páros paritás és 2 stop bit. A „B” áramkör az /RST 5,5 sínen kér megszakítást. Az „A” áramkör báziscíme 0AAh, a „B” áramkör báziscíme 0AEh.

Írja meg azt a két assembly programrészletet, amely a két 8251-est felprogramozza a fenti konfigurációnak megfelelően!


   AFELPROG:
       ;először a MODE INSTRUCTION-t kell kiküldeni
       ;kódszó: 11111101B - a alsó 2 bit értéke elvileg úgy jön ki, hogy a TxC és RxC órajeleknek 1-szeres arány kell legyen
       MOV A,FDH
       OUT 0AAH
       MOV A,00    000001B     ;Command Instruction
       OUT 0AAH        
       RET
       
   BFELPROG:
       ;kódszó: ugyanaz,mint az előbb
       MOV A,FDH
       OUT 0AEH
       MOV A,00000000B     ;Command Instruction, B lesz a vevő
       OUT 0AEH    
       JMP 002CH
       RET


2. e) NR!

Illesszen a 8085 mikroprocesszor sínrendszerére 8255-ös típusúPPIO áramkört, amely a 94H, 95H, 96H, 97H portcímeket foglalja el. A PPIO áramkör B portjára egy 8 bites párhuzamos adat kimenettel rendelkező periféria csatlakozik, (tehát a B portot bemenetként kell felprogramozni) amely hand-shaking (kézfogásosos) jelekkel ütemezi az adatátvitelt. Adat beolvasása esetén az áramkör kérjen megszakítást a CPU RST5.5 bemenetén. A periféria 8 adatvezetéken kívül az adattal egyidőben megjeleníti a PEVEN páros paritás jelet is. A PEVEN jel csak a hand-shaking folyamat közben áll rendelkezésre.

Vegye figyelembe, hogy a megszakítási szubrutinban megvalósított adatbeolvasás időpontjában nem biztos, hogy a PEVEN paritás rendelkezésre áll, viszont a feladathoz feltétlen szükséges. Ezért javasolt a paritás jel mintavételezése (a megfelelő hand-shaking jellel) és letárolása a PPIO áramkörön kívül, majd beolvasása az A porton keresztül (pl. PA0 bemeneten) a megszakítási szubrutinban.

  • Írjon INIC55 szubrutint, amely elvégzi a PPIO áramkör fentiek szerinti inicializálást, és az SP beállítását, ha a STACK 8F00h és 8FFFh memóriatartományban van
  • Írjon RST5.5 megszakítási szubrutint, amely beolvassa az adatot és a paritást PPIO áramkörről, ellenőrzi paritást, majd azadatot elhelyezi a 3456H című memória byte-ban, illetve paritáshiba esetén megnöveli a 3457H című memória byte tartalmát.
   INIC55: ORG 8F00H   
       TER DS FF   ;STACK helyfoglalás
       
       ORG 0H
       ;STÁTUSZ szó: 10111111  - segédlet 95-97.oldala alapján
       MOV A,DFH
       OUT 97H
       
       IN 95H
       JMP 2CH 
       ORG 2CH
       IN 94H      ;ez itt a PEVEN jel beolvasása 
       ANI 01H     ;a PA0 bitjét veszem a PEVEN paritás bitnek
       MOV D,A     ;és elmentem a D-be;ha D=0, akkor páratlan paritás,  D=1, akkor páros paritás van
       MVI B,0
       MVI C,8 
   PARIT:  RLC
       JNC TOV
       INR B       ;az utolsó ciklusba bekerül a beolvasott byte-ban lévő 1-esek száma
   TOV:    DCR C
       JNZ PARIT
       MOV A,B
       ANI 01H
       
       LXI H,3456H
       MOV M,A
   

2. f.)

Illesszen i8085-ös mikroprocesszoros rendszersínre egy visszaolvasható 8 bites kimeneti regisztert, mely az alábbi ábrán látható lámpa vezérlő egységet képes működtetni.

  • a kimeneti regisztert (74374) a 20h IO címen írható és a kimeneti egység L1…L8 jelei a 20H IO címen visszaolvashatók
  • Írja meg a CHECK 8085 assembly szubrutint, amely az A regiszterben kapott értéket beírja az előző feladatban kialakított kimeneti regiszterbe, majd a kimenet értékét visszaolvassa és ellenőrzi. Hiba esetén visszatéréskor CY=1, különben CY=0 legyen.
   CHECK:  OUT 20H     ;kiírás a reg-be
       CMA     ;bitenként negálja az A-t
       MOV B,A     ;ezt a negált értéket beírjuk a B reg-be
       IN 20H      ;20H címről beolvasunk
       CMP B       ;szokásos ellenőrzés
       JZ CY0      ;ha egyenlő a B és a visszaolvasott érték, akkor Z=1 és akkor ugrunk arra a részre ahol CY:=0
       STC     ;ha Z=0 akkor CY-t 1-be állitjuk
       JMP VEGE        ;és ugrunk a végére
   CY0:    STC     ;CY=1
       CMC     ;CY-t negálja
   VEGE:   RET

3. feladat

3. a)

           LXI D,X     ; X ms-ban
           LXI B,R     ; R-ratio, szazalekban
       ELEJE:  LXI H,X*1000000*R/100/7040
           MVI A,C8H   ; 11001000B
           SIM
           CALL HUROK
           MVI A,48H   ; 01001000B
           SIM
           LXI H,X*1000000*(100-R)/100/7040
           CALL HUROK
           JMP ELEJE
       HUROK:  DCX H       ; 4 fazis
           MOV A,H     ; 4 fazis
           ORA L       ; 4 fazis
           JNZ HUROK   ; 10 fazis, 7040 nsec
           RET

3. b.)

Írjon 8085 assembly szubrutint, amely a következő specifikáció szerint működik:

  • A szubrutin a SID jel felfutó élére egy adatkivitelt, a lefutó élére egy adatbeolvasást végezzen a következők szerint:
  • a szubrutin induláskor megvárja a SID jel 0=>1 átmenetét és a B regiszter tartalmát kiírja a 70h-es port címre,
  • majd a SID jel 1=>0 átmenetére 71h port címről beolvas egy adatbájtot, amit a C regiszterbe tesz, ezután kilép a szubrutinból.
  • A szubrutin bemenete: a kiírandó adat a B regiszterben.
  • A szubrutin kimenete: a beolvasott adat a C regiszterben
  • A megoldás során ügyeljen arra, hogy a szubrutin a C regiszter kivételével a regiszterek és a flag-ek értékét ne változtassa meg!
   RUTIN:  MVI C,0H        ;ezzel a reg-gel ellenőrizzük azt, hogy a SID jel milyen értékű, az 1. részben 0-1 átmenet kell
       PUSH PSW    ;kimentések
       PUSH A
       PUSH B
   VAR1:   RIM     ;a beolvasott byte felső bitje a SID jel értékét mutatja 
       MVI A,80H   ;maszkolás  
       ORA C       ;megnézzük, hogy a SID=0-e ha nem akkor ugárs VAR1-re / SID=1-re várunk
       JNZ VAR1
   VAR2:   RIM     ;itt gyakorlatilag ugyanaz van, mint az előbb, csak SID-1-re várunk
       MVI A,80H
       ORA C
       JZ VAR2     ;tehát ha SID=0 marad, akkor ugrunk VAR2-re / ha SID=1, akkor várunk még
       MOV A,0     ;itt azt nézzük, hogy az 1. részben vagyunk-e 
       CMP C       ;ha a kivonás eredménye 0, akkor az 1. részben vagyunk és ekkor írjuk ki a B-t a 70H-ra
       JZ B70H     
       JMP C71H        ;ha a 2. részben vagyunk, akkor az előző ugró utasítás nem teljesül és ide kell ugrani
   CIMKE:  MOV C,01H   ;ha az 1. részben vagyunk, akkor C reg-t 1-be kell állítani, a 2. részben már nem fogunk ide ugrani
       JMP VAR1
   B70H:   MOV A,B
       OUT 70H
       JMP CIMKE
   C71H:   IN 71H
       MOV C,A 
       POP B
       POP A
       POP PSW
       END

Egy másik megoldás:

       NULLBEOLV:  PUSH PSW
               RIM
               ANI 80H     ;10000000B
               JZ NULLBEOLV
               MOV A,B
               OUT 70H
       EGYBEOLV:   RIM
               ANI 80H
               JNZ EGYBEOLV
               IN 71H
               MOV C,A
               POP PSW
               JMP NULLBEOLV

3. c.)

Írjon 8085 assembly szubrutint, amely megvárja a SID jel változását (felfutó és lefutó él). A szubrutin kimenete:

  • Z=1 felfutó él volt,
  • Z=0 lefutó él volt!
  • A szubrutin ne változtassa meg a regiszterpárok értékét!
   RUTIN:  RIM
       ANI 80H     ;maszkolás, az SID értéke az A-ban lesz
       JZ FELFUT   ;ha az előbbi "és"-elés eredménye 0 (tehát a SID 0), akkor Z=1 -> ugrás a felfutójelhez
       JMP LEFUT   ;különben lefutó jelre várunk
   FELFUT: RIM
       ANI 80H     ;maszkolás
       JZ FELFUT   ;addig csináljuk amíg az eredmény 1 lesz (tehát a SID=1-re), Z=0-ra várunk
       XRA A       ;beállítjuk a Z-t 1-re
       JMP VEGE        ;ugrás végére
   LEFUT:  RIM
       ANI 80H
       JNZ FELFUT  ;ha Z=1, akkor az "és"-elés eredménye:0, tehát tovább kell várni a SID= 1 -> 0 átmenetre
       MOV A,FFH   
       ORA A       ;Z:=0
   VEGE:   RET

Egy másik megoldás:

               MVI A,0
               RIM
               ANI 80H
               JZ IDE
               MVI A,1
       IDE:        CALL IDERUTIN
               HALT
       IDERUTIN:   ANI FF
               JZ VAREGYRE
       VARNULLRA:  RIM
               ANI 80H
               JNZ VARNULLRA
               RZ
       VAREGYRE:   RIM
               ANI 80H
               JZ VAREGYRE
               RNZ

3. d.)

Írjon 8085 assembly szubrutint, amely a HL regiszterpárban kapott kezdőcímű és 32 byte hosszúságú adatblokkhoz 1 byte-os ellenőrző összeget számol ki, és elhelyezi a blokkot követő rekeszben. A szubrutin végén az akkumulátor az ellenőrző összeget tartalmazza! (A rutin bármely regiszter értékét elronthatja)!

Az ellenőrző összeg számítási algoritmusa: X(i) mod 256 0<i<32

   RUTIN:  MVI C,32        ;32 byte hosszúságú adatblokk
       XRA A       ;A:=0
   CIKLUS: ADD M       ;A+HL-> A
       INX H       ;forrásmutató növelése
       DCR C       
       JNZ CIKLUS  ;ha végigértünk akkor Z=1
       MOV M,A     ;a blokkot követő részen az ellenőrző összeg
       RET

Egy másik megoldás:

               LXI D,0     ;reszosszeg kinullazasa
               LXI H, KC   ;kezdocim
               LXI B, 32   ;db
           HUROK:  MOV A,M
               CALL OSSZEGZO
               INX H
               DCX B
               MOV A,C
               ORA B
               JNZ HUROK
               MOV M,E     ;E-ben van a mod256 reszosszeg
           
           OSSZEGZO:
               PUSH H
               MOV L,A
               MVI H,0
               DAD D
               XCHG
               POP H
               RET

3. e.)

Írjon assembly programot amely kivonja két memóriában elhelyezkedő 32 szavas memóriatömbök egyes szavait és az eredményeket visszahelyezi egy újabb memóriaterületre! A 2 byte-os szavak felső 8 bitjét a kisebb című (páros) byte, az alsó 8 bitet a következő (páratlan) cím tárolja!

   (9000H,9001H) = (9100H,9101H) - (9200H,9201H) ... stb.
  • Írja meg a kivonó programot!
  • A kivonások elvégzése után a 9000H-n kezdődő 32 szavas memória terület után helyezzen el egy olyan byte-ot, amely megadja, hogy a 32 eredmény szó közül mennyi a pozitív szám feltételezve, hogy az operandusok (és az eredmény) 16 bites kettes komplemens kódban van ábrázolva.
       LXI B,9000H
       LXI D,9101H
       LXI H,9201H
       MVI E,32H   ;2*32 szót vonunk ki egymásból  
   KIVON:  STC     ;CY:=1
       CMC     ;CY:=/CY -> CY:=0
       LDAX A,D        ;9101H-n található adatot betölti az A-ba
       SBB M       ;A-(HL által mutatott címen levő adat)-CY , ha van átvitel akkor CY=1 lesz
       STAX B      ;B által mutatott címre A tartalmát helyezi
       DCX B       
       DCX D
       DCX H
       LDAX A,D        ;9100H-n található adat megy az A-ba
       SBB M       ;A-M-CY
       STAX B      ;9000H-n a kivonás eredménye (2 byte-on)
       INX H
       INX H
       INX D
       INX D
       INX B
       INX B
       DCR E
       JNZ KIVON
       MVI E,32H   ;32 szavat vizsgálunk meg
       MVI D,0H        ;a pozitív számok számát ebben tároljuk 
   SZAMOL: LXI B,9000H 
       ANI 80H     ;ha a MSB (legfelső bit)=1 akkor a szám negatív
       JZ TOVABB   ;ha szám negatív, akkor Z=1 és nem kell növelni
       INR D   
   TOVABB: INX H       
       INX H
       DCR E       
       JNZ SZAMOL
       END

Egy másik megoldás:

           XPOINTER EQU 9080H
           YPOINTER EQU 9082H
           ZPOINTER EQU 9084H  ;ideiglenes regiszterpárok, KIHASZNÁLATLAn ramterület, senkit nem zavar
           X EQU 9100H
           Y EQU 9200H
           Z EQU 9000H

           LXI H,X         ;ebbol
           SHLD XPOINTER
           LXI H,Y         ;ezt
           SHLD YPOINTER
           LXI H,Z         ;ide(eredmény)
           SHLD ZPOINTER
            
       CIKLUS: CALL CIKLUSMAG
           LXI B, X+32*2
           LHLD XPOINTER
           MOV A,H
           CMP B
           JNZ CIKLUS
           MOV A,L
           CMP C
           JNZ CIKLUS
           HALT

       CIKLUSMAG:
           LHLD XPOINTER       ;H=91,L=00
           MOV D,M
           INX H
           MOV E,M         ;DE=ebbol
           INX H
           SHLD XPOINTER
           LHLD YPOINTER
           MOV A,M
           CMA
           MOV B,A
           INX H
           MOV A,M
           CMA
           MOV C,A
           INX B           ;BC-ben kivonando kettes komplemense(-1szerese)         
           INX H           
           SHLD YPOINTER
           XCHG            ;HL-ben ebbol
           DAD B
           XCHG            ;DE-ben eredmeny
           LHLD ZPOINTER
           MOV M,D
           INX H
           MOV M,E
           INX H
           SHLD ZPOINTER
           RET

3. f.)

Írjon assembly szubrutint amely kivonja két, a memóriában elhelyezkedő 64 byte-os memóriatömb egyes byte-jait és az eredményeket visszahelyezi az első operandus helyére! Az operandusok kezdőcímeit a szubrutin a HL és DE regiszterpárokban kapja. A kivonások elvégzése után a rutin az BC regiszter-párban kapott címtől kezdődően helyezzen el egy olyan byte-ot, amely megadja, hogy a 64 eredmény byte közül mennyi a pozitív szám (>0), egy másik byte-ot, hogy mennyi a negatív szám (<0), és egy harmadik byte-ot, hogy hány érték volt 0 (=0). (Az operandusok és az eredmény 8 bites kettes komplemens kódban vannak ábrázolva.)

  • Írja meg a szubrutint!
  • Írja meg azt a programrészletet, amely meghívja a szubrutint a HL=8000h, DE=8800h és BC=9000h paraméterekkel, majd ellenőrzi, hogy a 9000h címtől kezdődő 3 byte összege valóban 64.


   RUTIN:  PUSH B      ;kimentjük BC-t,mert a számlálónak a B-t használjuk fel
       PUSH H      ;a későbbi vizsgálat során az eredeti címtől indulunk, így ezt is kimentjük
       MVI B,64        
       XCHG        ;HL és DE felcserélése
   KIVON:  LDAX D      ;az A-ba betölti a DE (eredetileg HL) által mutatott címen lévő adatot
       SUB M       ;így DE-ből kivonjuk a HL-t
       STAX D      ;DE által mutatott címre visszahelyezzük az eredményt
       INX D       
       INX H
       DCR B       
       JNZ KIVON   ;ha végigértünk a 64 byte-on, akkor Z=1 lesz
       XCHG        ;HL és DE visszacserélése
       
       POP B
       POP H
       PUSH H      
       MVI D,0     
       MVI E,64
   POZ:    MOV A,M     ;A-ban a HL által mutatott címen lévő byte
       ANI 80H     ;maszkolás az előjel bitre
       JNZ PT      ;ha az előjel bit=1, akkor Z=0 és akkor negatív, így kihagyjuk a D növelését
       INR D       ;ha Z=1, akkor a szám pozitív és növeljük D-t
   PT: DCR E       
       JNZ POZ     ;amíg végig nem értünk Z=0
       MOV A,D     ;D-ben van a pozitív számok darabszáma
       STAX B      ;B címére elhelyezzük a darabszámot
       INX B       ;a B következő címére kerül a negatív számok darabszáma
   ;pepita...
       POP H       
       PUSH H
       MVI D,0
       MVI E,64    
   NEG:    MOV A,M
       ANI 80H
       JZ NT
       INR D
   NT: DCR E
       JNZ NEG
       MOV A,D
       STAX B
       INX B       ;a B következő címére kerül a 0 értékű számok darabszáma
       
   ;0-k száma, pepita
       POP H
       MVI D,0
       MVI E,64
   NULL:   MOV A,M
       ORA 00H     ;egyedül itt van különbség, ha byte csupa 0, csak akkor lesz ORA 0H = 0-val és ezzel együtt Z=1
       JNZ NULT
       INR D
   NULT:   DCR E
       JNZ NEG
       MOV A,D
       STAX B
       RET


  • Írja meg azt a programrészletet, amely meghívja a szubrutint a HL=8000h, DE=8800h és BC=9000h paraméterekkel, majd ellenőrzi, hogy a 9000h címtől kezdődő 3 byte összege valóban 64.
       LXI H,8000H
       LXI D,8800H
       LXI B,9000H
       CALL RUTIN
       MOV C,0
       MOV D,3
       STC
       CMC
   ELL:    LDAX B
       ADC C
       MOV C,A
       DCR D
       JNZ ELL
       MOV A,64
       CMP C
       JZ JO
       STC     ;ezt itt a feladat nem kéri, de utólag vhogy el kell tudni dönteni, hogy az összeg valóban 64-e
       CMC     ;ezért ha nem jó akkor CY flag értéke 0 lesz, jó összeg esetén 1
       JMP VEGE        
   JO:     STC
   VEGE:   END

Egy másik megoldás:

       KISERED EQU 8000H
       KIVONANDO EQU 8800H
       ELOJEL EQU 9000H            

       LXI H,KISERED
       LXI D,KIVONANDO
                   ;LXI B,ELOJEL ;ELOJEL=POZITÍVAK, ELOJEL+1=negatívak, ELOJEL+2=nullák
       
   CIKLUS: MOV A,M
       PUSH PSW
       LDAX D
       MOV B,A
       POP PSW
       SUB B           ;AKKUMULÁTORBAN EREDMÉNY
       MOV M,A
       JZ NULL
       JP POZ
       PUSH H          ;(NEGATÍV ÁG)   
       LHLD ELOJEL+1
       INX H
       SHLD ELOJEL+1
       POP H
       JMP ELLEN
   NULL:   PUSH H          ;(0 ÁG) 
       LHLD ELOJEL+2
       INX H
       SHLD ELOJEL+2
       POP H
       JMP ELLEN       
   POZ:    PUSH H          ;(POZITÍV ÁG)   
       LHLD ELOJEL
       INX H
       SHLD ELOJEL
       POP H
   ELLEN:  INX H
       INX D
       LXI B,KISERED+64
       MOV A,H
       CMP B
       JNZ CIKLUS
       MOV A,L
       CMP C
       JNZ CIKLUS
       LXI B,ELOJEL

       LXI H,ELOJEL
       MOV A,M
       INX H
       ADD M
       INX H
       ADD M
       CPI 64
       JZ JO
   NEMJO:  NOP         ;NEM JO!!!!!!!!!!
   JO: HALT

3. g.)

Írjon assembly szubrutint, amely a HL regiszterpárban kapott címen elhelyezkedő 00h végjelre végződő karakterstringben megkeresi az első '1' számjegyet. (az ’1’ számjegy ASCII kódja 31h). Találat esetén a szubrutinból visszatéréskor a HL regiszterpár mutasson a megtalált karakter címére és CY = 0 legyen. Ha a keresett karakter nem található, akkor a szubrutin CY=1 értékkel térjen vissza. (Ilyenkor a HL regiszterpár a 00h végjelre mutasson.

   RUTIN:  MVI B,00H
   KERES:  MVI A,31H
       CMP M       ;megnézzük, hogy a HL által mutatott címen lévő adat 31H-e
       JNZ TOV     
       JMP VEGT        ;ha megtaláltuk az '1' számjegyet, akkor Z=1 és ugrunk a VEGT (VÉGe és Találtunk)

   TOV:    MOV A,B     ;00 végjel figyelésére szolgál
       CMP M       ;ha HL által mutatott címen 00H található, akkor és csak akkor a kivonás eredménye 0 (Z=1)
       JZ VEGNT        ;ugrás a VÉGe és Nem Találtunk részre
       INX H       ;mutató növelése
       JMP KERES   

   VEGT:   STC     ;a HL címe ekkor automatikusan a keresett karakterre mutat, így csak a CY flaget kell állítani
       CMC     
       JMP VEGE

   VEGNT:  STC     ;itt is a megfelelő helyre mutat a HL, így csak CY:=1-t állítunk
        
   VEGE:   RET

Egy másik megoldás:

       KC EQU 9100H        ;egyéni
       
   CIKLUS: MOV A,M
       CPI 31H
       JZ TALALT
       CPI 0
       JZ NULLTALALT           
       INX H
       JMP CIKLUS
   TALALT: STC
       CMC
       JMP VEGE
   NULLTALALT: STC
   VEGE:   HALT

3. h.)

Írjon assembly szubrutint, amely a HL regiszterpárban kapott címtől kezdődően átmásol 32 bájtot a DE regiszterpárban megadott kezdőcímen kezdődő memóriaterületre. A megoldás során ügyeljen arra, hogy a rutin ne változtassa meg a flag-ek állapotát és a BC regiszterpár értékét!

Írjon assembly programrészletet, amely SID=1 esetén várakozzon SID=0-ra, majd SID=0 esetén a fenti szubrutin meghívásával másoljon át 32 bájtot a 9000h memóriacímről a 9150h címre.

   RUTIN:  PUSH PSW
       PUSH B
       
       MVI B,32
   MASOL:  XCHG        ;DE felcserélése HL-lel
       LDAX D      ;DE (=eredetileg HL) beírása az A-ba
       XCHG        ;visszacsere
       STAX D      ;beírjuk A-t az eredeti DE által mutatott címre
       INX H
       INX D
       DCR B   
       JNZ MASOL
       POP PSW
       POP B
       RET
   ;programrészlet:
   VAR:    RIM
       ANI 80H
       JNZ VAR
       LXI H,9000H
       LXI D,9150H
       CALL RUTIN
       END

Egy másik megoldás:

    VAR:    RIM
       ANI 80H     ;10000000B
       JNZ VAR
       LXI H,9000H
       LXI D,9150H
       CALL MASOL
       HALT
           ;HL-ben és DE-ben már megvan a kezdõcímünk..
   
   MASOL:  PUSH PSW
       PUSH B
       LXI B,32
   CIKLUS: MOV A,M
       STAX D
       INX H
       INX D   
       DCX B
       MOV A,C
       ORA B
       JNZ CIKLUS
       POP B
       POP PSW
       RET

3. i.)

Írjon assembly szubrutint, amely a DE regiszterpárban kapott címtől kezdődő 16 bájtot a blokk végétől kezdve visszafelé átmásol a HL regiszterpárban megadott címen kezdődő memóriaterületre (A forrás-blokk utolsó byte-ja van a cél-blokk első helyén). A megoldás során ügyeljen arra, hogy a rutin ne változtassa meg a flag-ek állapotát és a regiszterpárok értékét!


   RUTIN:  PUSH PSW
       PUSH B
       PUSH D
       PUSH H
       MVI B,16
   ;a DE-t megnöveljük 16-tal
   DENOV:  INX D
       DCR B
       JNZ DENOV   
       MVI B,16
   MASOL:  LDAX D
       XCHG
       STAX D
       XCHG
       INX H
       DCX D
       DCR B
       JNZ MASOL
       POP H
       POP D
       POP B
       POP PSW
       RET

Egy másik megoldás:

       PUSH PSW
       PUSH B
       PUSH D
       PUSH H
       
       PUSH H
       LXI B,16
       DAD B
       MOV B,H
       MOV C,L
       XCHG
       LXI D,15
       DAD D
       XCHG
       POP H
       
   CIKLUS: LDAX D
       MOV M,A
       INX H
       DCX D
       MOV A,H
       CMP B
       JNZ CIKLUS
       MOV A,L
       CMP C
       JNZ CIKLUS
       
       POP H
       POP D
       POP B
       POP PSW

3. j.)

Írjon assembly szubrutint, amely a DE regiszterpárban kapott címtől kezdődő 16 bájtban megszámolja a negatív számokat (feltételezve, hogy az adatok 8 bites kettes komplemensben ábrázolt előjeles számok), és a kapott eredményt elhelyezi a 8000h memória rekeszbe. A megoldás során ügyeljen arra, hogy a rutin ne változtassa meg a flag-ek állapotát és a regiszterpárok értékét!

   RUTIN:  PUSH PSW
       PUSH B
       PUSH D
       MVI B,16
       MVI C,0 
   SZAMOL: LDAX D
       ANI 80H
       JZ NEMNEG
       INR C       ;ha Z=0, akkor negatív a számunk, ekkor növelünk
   NEMNEG: DCR B
       JNZ SZAMOL
       MOV A,C
       STA 8000H
       POP D
       POP B
       POP PSW
       RET

Egy másik megoldás:

       PUSH PSW
       PUSH B
       PUSH D
       PUSH H

       LXI H,8000H
       MVI M,0
       MVI B,0
   CIKLUS: LDAX D
       ANI 80H
       CMP D       ;FELESLEGES
       JZ POZITIV
       INR M
   POZITIV:INX D
       INR B
       MOV A,B
       CPI 16
       JNZ CIKLUS

       POP H
       POP D
       POP B
       POP PSW
       HALT

3. k.)

Írjon assembly szubrutint, amely a HL regiszterpárban kapott címtől kezdődő 254 byte-os adatblokk végére kiszámít egy 2 byte-os ellenőrző szót (a blokk byte-jainak összeadásával), és elhelyezi az adatokat követően. A megoldás során ügyeljen arra, hogy a rutin ne változtassa meg a flag-ek állapotát és a regiszterpárok értékét!

   RUTIN:  PUSH PSW
       PUSH B
       PUSH H
       PUSH D
       
       MVI B,254
       LXI D,0
       MVI A,0
   ELL:    PUSH H  
       MOV A,M     ;HL által mutatott címen lévő adat betöltése A-ba
       MOV L,A     ;a címen lévő adat, így már a címmutató regiszter alsó részén van (itt elfér nem kell hozzá a H reg)
       DAD D       ;HL+D -> HL
       XCHG        ;HL cseréje DE-vel (így DE-ben van az ellenőrző összeg)
       POP H       
       INX H       ;cím növelése
       DCR B
       JNZ ELL     ;amíg végig nem értünk
       MOV M,D     ;D betöltése a HL címre
       INX H
       MOV M,E     ;a következő byte-ra pedig az E kerül
           
       POP D
       POP H
       POP B
       POP PSW
       RET

Egy másik megoldás:

    PUSH PSW
    PUSH B
    PUSH D
    PUSH H
    
    XCHG            ;DE-ben kezdocim
    LXI H,0         ;reszosszeg HL-ben
    MVI A,0         ;itt számoljuk a 254 db-ot
CIKLUS: PUSH PSW
    LDAX D
    MVI B,0
    MOV C,A
    DAD B
    INX D
    POP PSW
    INR A
    CPI 254
    JNZ CIKLUS
    MOV A,L
    STAX D
    INX D
    MOV A,H
    STAX D
    
    POP H
    POP D
    POP B
    POP PSW

3. l.)

Írjon assembly szubrutint, amely 15 byte adatot és egy byte ellenőrző karaktert tartalmazó üzenet átvitelét ellenőrzi. A szubrutin bemenete az üzenet kezdőcíme (HL-ben), kimenete legyen hibátlan átvitel esetén Z=1, hibás átvitelkor Z=0. A megoldás során ügyeljen arra, hogy a rutin ne változtassa meg a regiszterpárok (BC,DE,HL) értékét!

   RUTIN:  PUSH B
       PUSH H
       PUSH D
       PUSH H
       XCHG        ;HL és DE cseréje
       MVI H,16        ;16 byte másolására fog sorra kerülni
       LXI B,0     ;ahova másolunk, az a 0-s címen található (feltesszük, hogy a HL címe és ez nem lapolódik össze)
       PUSH B
   MASOL:  LDAX D      ;DE által mutatot cím tartalma az A-ban lesz
       STAX B      ;az A tartalma a BC címre kiíródik
       INX D
       INX B
       DCR H
       JNZ MASOL
       
       POP B       ;a BC-t visszacsökkentjük az eredetire
       MVI D,16
   ELL:    LDAX B      ;a BC-n és HL-n található byte-okat kivonogatjuk egymásból
       SUB M
       JZ HIBA     ;ha a kivonás eredménye 1, akkor hiba van
       DCR D   
       JNZ ELL 
   NOHIBA: XRA A       ;Z-t 1-be állítjuk
       JMP VEGE        ;és átugorjuk a HIBA részt
   HIBA:   MOV A,FFH
       ORA A       ;ezzel a Z-t 0-ba állítottuk
   VEGE:   POP D
       POP H
       POP B
       RET

Egy másik megoldás:

RUTIN:
    PUSH B
    PUSH D
    PUSH H          
    
    XCHG
    LXI H,0
    MVI A,0
CIKLUS: PUSH PSW
    LDAX D
    MVI B,0 
    MOV C,A
    DAD B
    INX D
    POP PSW
    INR A
    CPI 15
    JNZ CIKLUS
    LDAX D
    CMP L       ;BE VAN ALLITVA A Z FLAG

    POP H
    POP D
    POP B

    RET

3. m.)

Írjon Intel 8085 mikroprocesszor assembly nyelvén a PORTOLV szubrutint, amely a a CPU SID jelének 0 -> 1 átmenetére beolvassa 64H I/O című portot és az adatot az akkumulátorban adja vissza a szubrutint meghívó programrésznek.

Írjon a OLV32 szubrutint, amely a PORTOLV szubrutin felhasználásával beolvas 32 byte-ot és elhelyezi a memória 2000H-201FH memóriatartományában. Az OLV32 szubrutin változatlan tartalommal adja vissza a meghívó programnak a CPU regisztereket.


   PORTOLV:
   VAR1:   RIM
       ANI 80H
       JNZ VAR1        ;ha SID=0, akkor Z=1 lesz és akkor mehetünk tovább
   VAR2:   RIM
       ANI 80H
       JZ VAR2     ;megvárjuk, míg SID=1 lesz  
       IN 64H
       RET
   OLV32:  PUSH PSW
       PUSH B
       PUSH D
       LXI B,2000H
       MVI D,32
   MASOL:  CALL PORTOLV
       STAX B
       INX B
       DCR D
       JNZ MASOL
       
       POP D
       POP B
       POP PSW
       RET

Egy másik megoldás:

PORTOLV:
    RIM
    ANI 80H
    JZ PORTOLV
    IN 64H
    RET

OLV32:
    PUSH PSW
    PUSH B
    PUSH D
    PUSH H
    
    KC EQU 2000H
    VC EQU 201FH
    LXI H,KC
    LXI D,VC+1
CIKLUS: 
    CALL PORTOLV
    MOV M,A
    INX H
    MOV A,L
    CMP E
    JNZ CIKLUS
    MOV A,H
    CMP D
    JNZ CIKLUS
    
    POP H
    POP D
    POP B
    POP PSW
    RET

3. n.)

Írja meg a SENDBYTE 8085 assembly szubrutint, amely a következő specifikáció szerint működik: A szubrutin feladata a mellékelt ábrán specifikált hand-shake szekvencia alapján a B regiszterben kapott adat byte továbbítása a 20H I/O címre. A megoldás során ügyeljen arra, hogy a szubrutin a flag-ek értékét ne változtassa meg! Rajzolja fel a szubrutin mellé a rutin folyamatábráját is!

Hand-shake: rajz

  • először megjelenik az érvényes adat a porton
  • majd a SOD jel 0 -> 1 átmenete után (némi várakozás után min kb. 320 ns) a SID jel is 0 -> 1-be váltjuk
  • utána a SOD 0-ba vált (ekkor a porton az adatvezeték nagyimpedanciás lesz/nem lesz adat), ezután a SID is 0-ba váltjuk
  • a lényeg, hogy a SOD 1-be váltását követően de még a 0-ba váltását megelőzően ki kell olvasni az adatot és be kell állítani a megfelelő állapotba a SID-et

Írjon 8085 assembly kódrészletet, mely a 2345h címtől kezdődő 34 byte adatot a SENDBYTE szubrutin segítségével továbbítja.

   SENDBYTE:       ;ez túl sok karakternek tűnik :)
       PUSH PSW
   VAR:    RIM
       ANI 80H
       JNZ VAR
       MOV A,B
       OUT 20H
       RIM
       MVI A,0C0H  ;11000000B
       SIM
   WSID0:  RIM     
       ANI 80H
       JZ WSID0
       RET
   ;programrészlet
       LXI D,2345H
       MVI H,34
   MASOL:  LDAX D
       MOV B,A
       CALL SENDBYTE
       DCR H
       JNZ MASOL

Egy másik megoldás:

SENDBYTE:
    RIM
    ANI 80H
    JNZ SENDBYTE
    MOV A,B
    OUT 20H
    RIM
    ORI C0H     ;11000000B
    SIM
VARSID1:RIM
    ANI 80H
    JZ VARSID1
    RIM
    ANI 7FH     ;01111111B
    ORI 40H     ;01000000B
    RET

3. o.)

Írjon 8085 assembly szubrutint, amely a következő specifikáció szerint működik:

  • A szubrutin (GETBLOCK) feladata a 80H I/O címen elhelyezkedő 8255 párhuzamos periféria illesztő A portján 1-es üzemmódban az RST 5.5 IT-vel érkező 32 byte-os adatblokk és a hozzá tartozó 1 byte-os ellenőrző összeg beolvasása. A rutin a beolvasott adatokat a 9000h címtől kezdődően helyezze el. Az ellenőrző összeg számítási algoritmusa:
  • Ai mod 256 1=<i=<32
  • A rutin Z=1-gyel jelezze, ha az ellenőrző összeg helyes, Z=0-val, ha hibás volt. Mindkét esetben az

akkumulátor a helyes (a számított) ellenőrző összeget tartalmazza! (A rutin bármely regiszter értékét elronthatja!)

  • Írja meg a 8255-öst felprogramozó szubrutint (A port: 1-es üzemmód, bemenet; B port: 0-ás üzemmód, kimenet; C port:

bemenet)

   FELPROG:    
       MOV A,10111001B
       OUT 83H
       RET


Írja meg azt az RST 5.5-ös IT rutint, amely a 8001h címen elhelyezkedő byte legmagasabb helyértékű bitjének bebillentésével jelzi, ha beolvasott egy adatot. Az adat ilyenkor a 8000h memória címen található.

       ORG 2CH
   RST55:  LXI D,8001H
       LDAX D
       XRI 01H
       STAX D  
       RET


Írja meg a GETBLK szubrutint, az RST 5.5-ös IT rutin használatával Feltételezheti, hogy a rutin hívásakor az RST5.5 IT már engedélyezve van, de ne feledkezzen meg arról, hogy inicializáláskor a megszakítást a 8255-ösben letiltottuk!

   GETBLK: EI
       MVI B,32        ;32 byte beolvasása
       MVI C,0     ;az ellenőrző összeg számításához
       LXI D,9000H 
   BEOLV:  IN 80H
       CALL RST55
       STAX D
       ADD C
       INX D
       DCR B
       JNZ BEOLV
       LDAX D      ;az ellenőrző összeg beolvasása, a 32 byte-os adatblokk után következik
       CMP C
       MOV A,C
       DI  
       RET

Egy másik megoldás:

ORG 2CH:JMP 1000H
ORG 1000H:
    IN 80H
    MOV M,A
    PUSH H
    XCHG        ;HL-ben RESZOSSZEG
    MOV E,A
    MVI D,0
    DAD D       ;HL-ben uj reszosszeg       
    XCHG        ;DE-ben .............
    POP H       ;HL-ben cim (9000H)
    INX H
    DCR C
    EI
    RET


RUTIN:  MVI A,B9H   ;10111001B
    OUT 83H
    LXI H,9000H
    LXI D,0
    MVI C,32
KORBE:  MVI A,0
    CMP C
    JNZ KORBE
    MOV A,M
    CMP E
    MOV A,E         
    RET
ORG 2CH:JMP1000H
ORG 1000H:
    LXI H,8001H
    MOV A,M
    ANI 01111111B
    MOV M,A
    IN 80H
    LXI H,8000H
    MOV M,A
    LXI H,8001H
    MOV A,M
    ORI 10000000B
    MOV M,A
    EI
    RET

3. p.)

Készítse el egy 8251 típusú USART-ot tartalmazó soros adó/vevő áramkör terveit és az aszinkron vételi folyamatot megvalósító szubrutin programját.Az USART áramkör a 80h és 81h port címterületet foglalja el. Írja meg az áramkört inicializáló és a vételi folyamatot engedélyező programrészt! Az átvitel paraméterei:

  • aszinkron adás és vétel
  • egyszeres Baud-rate
  • 8 adatbit, páros paritás, 1 STOP bit
  • adás letiltva, vétel engedélyezve
   ;programrész
       MOV A,01111101B     ;119.o./ aszinkron átvitelre vonatkozó Mode Instruction
       OUT 80H
       MOV A,11100110B     ;121.o./ Command Instruciton
       OUT 80H         ;elvileg ugyanarra a címre kell küldeni, mint a Mode Instr.-t
   

Írja meg a 8251-es áramkörön keresztül 32 adatbyte-ot ciklikus lekérdezéssel beolvasó szubrutint, amely az adatot a memória 8000h - 801Fh tartományába írja be! A szubrutinban feltételezheti, hogy a vétel során nem lép fel hiba!

  • a 116.o. alján találhatók szerint a 8251-esen keresztüli adatbeolvasáshoz a C/D(negált)-nak 0-nak kell lennie
  • arra nem jöttem rá, hogy hogyan lehet ezt állítani, lehet, hogy a feladat szerint feltesszük azt, hogy a megfelelő állapotban van
   BEOLV:  LXI D,8000H
       MVI C,32
   OLV:    IN 80H
       STAX D
       INX D
       DCR C
       JNZ OLV

4. feladat

4. a.)

   ;kód            ;PC    ;adatsín ;/RD v. /WR   ;megjegyzés
   -----------------------------------------------------------------------------------
   ORG 0000h                                  direktíva
   LXI SP,0h       0000   31H      /RD
                   0001   00       /RD
                   0002   00       /RD        SP=0000H
   RST 7           0003   FFH      /RD        itt ugrik a 0038H-ra    
                   FFFF   00       /WR
                   FFFD   04       /WR        ;SP=FFFD
   HLT                                        hát ez most kimarad!
   ORG 38h                                    direktíva
   XRA A           0038   AFH      /RD        kinullázza A-t, így Z flag=1 lesz
   LXI H,0F000h    0039   3AH      /RD
                   003A   00H      /RD
                   003B   F0H      /RD        HL=F000H
   MOV M,A         003C   77H      /RD        az F000H címre 0-t tölt be
   ORA M           003D   B6H      /RD        0 OR 0=0 -> Z=1
   JNZ 38h         003E   C2H      /RD        feltétel nem teljesül így csak 1 byte-os az ut.
   RET             003F   C9H      /RD        PC=0000 , SP=0002

4. f.)

   ;kód            ;PC    ;adatsín ;/RD vagy /WR   ;megjegyzés
   --------------------------------------------------------------------
   ORG 0000h                             direktíva                                      
   LXI H,9000h     0000   21H     /RD
                   0001   00H     /RD
                   0002   90H     /RD    HL=9000H
   SPHL            0003   F9H     /RD    SP=HL=9000H
   LXI H,0100h     0004   21H     /RD    
                   0005   00H     /RD
                   0006   01H     /RD    HL=0100H
   PCHL            0007   E9H     /RD    PC=0100H
   HLT                                   ez most kimarad! (de később idejutunk)
   CALL 0102h                            ez is! (de ide később se jutunk el)
   ORG 0100h                             direktíva
   MVI A,45h       0100   3EH     /RD
                   0101   45H     /RD    A=45H
   LXI B,1234h     0102   01H     /RD    
                   0103   34H     /RD
                   0104   12H     /RD    BC=1234H
   XRA C           0105   A9H     /RD    A=34 XOR 45 =   00110100
                                                 XOR     01000101        
                                                         -----------
                                                         01110001= 71H =A, Z flag=0
   PUSH B          0106   C5H     /RD    
                   8FFF   34H     /WR
                   8FFE   12H     /WR    SP=8FFE
   XRA B           0107   A8H     /RD    A=01100010B= 62H ,  Z flag=0
   POP D           0108   D1H     /RD
                   8FFE   12H     /RD
                   8FFF   34H     /RD    D=1234H
   HLT             0109   76H     /RD    
   JMP 0008h       010A   C3H     /RD
                   010B   08H     /RD
                   010C   00H     /RD
   HLT:  ez kimarad mert előtte ugrunk az 1. HLT-re (PC=0008), ahol a progi befagy

5. feladat

5. a.)

Az alábbi kódrészlettel a 8000h címen elhelyezkedő 500 byte-os memóriaterület modulo 256-os ellenőrző összegét szeretnénk kiszámolni, és a memória területet követő byte-ban eltárolni. A program hibásan működik. Miért?

       LXI H,8000h
       LXI D,500
       XRA A
   ciklus:     
       ADD M
       INX H
       DCX D
       JNZ ciklus
       MOV M,A

Válasz: a DCX utasítás nem állítja a Z flaget, így a JNZ utasítás nem működik

5. b.)

Egy i8085-ös mikroszámítógép megszakítási rendszerének megvalósításakor i8259A megszakításvezérlőt alkalmaztunk, amely báziscíme 20h. Az alábbi megszakítást úgy szeretnénk megvalósítani, hogy bármelyik másik megszakítás-bemenetre érkező kérés azonnal érvényre juthasson mielőtt maga az IRUT rutin befejeződik. A program hibásan van megírva. Miért? Mit kellene kijavítani?

   IRUT:   PUSH PSW
       PUSH B
       EI
       OUT 41h
       IN 40h
       ADI 1
       OUT 40h
       MVI B,3
   CIKL:   IN 40h
       ACI 0
       OUT 40h
       DCR B
       JNZ CIKL
       POP B
       MVI A,20h
       OUT 20h
       POP PSW
       RET

Az a hiba, hogy a megszakítás vezérlőben az IT nyugtázása (EOI) csak az IT rutin végén történik meg (MVI A,20h; OUT 20h), ezért az alacsonyabb prioritású interruptok csak ez után jutnának érvényre.

5. c.)

Ugyanaz mint az #5. a.)

5. d.)

Az alábbi kódrészlettel a 8000h címen elhelyezkedő szót (16bit) szeretnénk hozzáadni a 8150h címen elhelyezkedő szóhoz úgy, hogy az eredmény a 8000h címre kerüljön (A szó alacsonyabb helyértékű bájtja (LSB) mindig a kisebb címen helyezkedik el.). A program hibásan működik. Miért? Mit kellene kijavítani?

   Osszead:    LXI H,8000h
       LDA 8150h
       ADD M       
       MOV M,A
       INX H
       LDA 8151h
       ADD M       ;itt ADC M kell, mert lehet átvitel a előző byte-ok összadása során
       MOV M,A
       RET
   

6. feladat

Ehhez létezik egy javításokat tartalmazó PDF. Megtekintés.

6. a.)

Egy kaszkádosított megszakításkezelő rendszerben, milyen esetben kell parancsbyte-ban megadni a SLAVE megszakításkezelőknek, hogy slave áramkörök?
Kaszkádosítás esetén, bufferelt kapcsolás esetén (62.o./3.5. , 63.o./3.6.3.)
Ebben az esetben hány ICW parancsbyte-ot kell kiadni és miért?
4, ICW1-4 (66.o./ 3.6.2. - 3.6.3.) ICW3 a kaszkádosítás miatt kell, az ICW4 pedig a bufferelt kapcsolás miatt (M/S bit)
Miért van szükség ICW3 parancsbyte-ra?
Mert kaszkádosott megszakításkezelő rendszert használunk
Miért van szükség ICW4 parancsbyte-ra?
A master-slave pozíciókat az ICW-4-el lehet beállítani (bufferelt üzemmód esetén szükséges) (M/S bit)

6. b.)

Inicializáljon egy 90h báziscímű i8255-ös párhuzamos periféria áramkör: A portját 1-es üzemmódban kimenetre, B portját szintén 1 üzemmódban bemenetre, C port alsó és felső felét bemenetre kell állítani. Adja meg a vezérlő szó értékét! Állítsa be a 8255 INTE ff-jainak értékét is!

   MOV A,10101111B     ;95.o./5.1 táblázat
   OUT 93H             ;94.o./működési tábla
   DI
gondolom az INTE ff-kat mind 0-ra kell állítani, mert ha 1 lenne, akkor az üzembe helyezést követően már kérne megszakítást
de az üzemmód megváltoztatásakor a f/f-k törlődnek,így ehhez sztem külön parancs nem szükséges

6. c.)

Egy vegyesen kaszkádosított 8259-es megszakítási rendszerben a MASTER egység IR2 bemenetére SLAVE áramkör kapcsolódik. A MASTER egység ugrási táblájának kezdőcíme 8000h, a SLAVE ugrási táblájának kezdőcíme 9000h, mindkettő nyolcas osztásban.

Adja meg, hogy milyen ICW3 parancsot kell küldeni a MASTER illetve a SLAVE egységeknek!

   LXI D,8000H ;MASTER
   MOV A,0000100B
   INX D
   STAX D
   LXI H,9001H ;SLAVE, másik módszerrel
   MOV A,0000010B
   MOV M,A
   
Adja meg, mennyi lesz a MASTER IR6 bemenetére érkező megszakítás szubrutinjának kezdőcíme!
802CH (65.o. ADI=0 esetén táblázat)

Adja meg, mennyi lesz a SLAVE IR6 bemenetére érkező megszakítás szubrutinjának kezdőcíme! -902CH (65.o. ADI=0 esetén táblázat)

6. d.)

Egy aszinkron üzemmódba felprogramozott 8251-es soros áramkör hibásan működik. A program státusz beolvasáskor olyan hibákat olvas, amelyek adat fogadásakor lépnek fel. Melyek lehetnek ezek, mi lehet a hibák oka ?

  1. OVERRUN ERROR (=túlfutási hiba), akkor ha a puffer-regiszter megelőző tartalmát a CPU még nem olvasta ki és ezt a 8251 felülírja
  2. FRAMING ERROR (=kerethiba): 0 színtű STOP bitek érkeznek
  3. PARITY ERROR (=paritás hiba): rossz paritás

6. e.)

Mit jelent a BREAK üzemmód a 8251-es áramkörnél?

  • aszinkron üzemmódban folyamatos kiküldhetők a vonalra, ha nincs folyamatban adatkivitel, állapotjelzésre is szolgálhat

Mire alkalmazható?

  • felhasználható megszakításkérés jelzésére

Hogyan lehet beállítani?

  • beállítása: a Command Instruction 3. bitje, a SBRK =1 esetén a TXD=0 lesz (Break karakter)

6. f.)

Rajzolja fel egy aszinkron üzemmódban felprogramozott USART kimeneti jelalakját (TxD) 8 bites, 0Fh értékű adat elküldésekor, ha páros paritást és 1 stop bitet alkalmazunk.

    0   1   1   1   1   0   0   1
       ___ ___ ___ ___         ___
  |___|               |___ ___|

6. g.)

Egy i8085-ös mikroprocesszoros rendszerben az A, B, C jelek külön kártyákon állnak elő, változásuk egymástól független, de mindannyian szeretnének időszakosan megszakítást kérni a processzor RST5.5 vonalán. Milyen kimenetű kapukat kell a szaggatottal jelölt dobozokba tervezni, hogy a rendszer helyesen működjön, miért?

  • Open collector, mivel a kimeneteket összekötöttük, és a rendszer tartalmazott közvetlen felhúzó ellenállást

6. h.)

Egy i8085-ös mikroprocesszoros rendszerben az A, B, C jelek külön kártyákon állnak elő, változásuk egymástól független, de mindegyiket szeretnénk időszakosan címezhetően külön-külön beolvasni a processzor D0 adatvonalán. Milyen kimenetű kapukat kell a szaggatottal jelölt dobozokba tervezni, hogy a rendszer helyesen működjön, miért?

  • Tristate, mivel a kimenetek összekötöttük és a rendszer nem tartalmazott közvetlen felhúzó ellenállást

6. i.)

Egy 8085 mikroprocesszoros rendszerben 1 master és 4 slave 8259-es IT vezérlőt használunk. Hány megszakítást tudunk összesen lekezelni a 8259-esekkel?

  • 4*8+(8-4)=36
  • A 4 Slave 8 megszakítást tud kezelni + a Master maradék IR bemenetei felhasználhatók megszakításkérés céljára (60.o./3.4.)

A fenti konfigurációt úgy kötötték be, hogy a slave egységek a master 0,2,4 és 6 sorszámú bemenetére kapcsolódnak. A rendszer hibásan működik. Miért? Indokolja a választ!

  • ha a Masternek egyedi megszakításkérő vezetékei is vannak, akkor a IR0 bemenetre nem szabadna az egyik Slave-t sem rákötni, ugyanis a CAS vezetékek 0 állapota egyszerre jelentené a Master és az egyik Slave megszakításkérését (62.o./3.4.)

A fenti konfigurációban az összes vezérlő egy közös meghajtón (74LS245) keresztül csatlakozik a rendszersínre. Hogyan lehet ilyen esetben az egyes vezérlőknek megmondani, hogy master vagy slave szerepet játszanak?

  • az ICW 4 parancsbyte 2. bitjével (=M/S) (66.o./3.6.3.)

6. j.)

Egy DMA vezérlő mind a 4 csatornájára egy-egy periféria csatlakozik. Használható-e ilyenkor az 1-es csatorna AUTOLOAD üzemmódban? Indokolja a választ!

  • Nem, csak a CH2 és CH3 használható (81.o./4.6.4.)

Programozza fel a DMA vezérlőt AUTOLOAD üzemmódba úgy, hogy a 9000h memóriacímtől kezdődő címre periódikusan 128 byte adatot legyen képes betölteni a perifériából. A 8257-es báziscíme: 70H.

       LXI D,9000H
       MVI B,128
       MOV A,10101111B
       OUT 78H         ;beírás A3=1, A2=A1=A0=0
   TOLT:   IN 78H      ;kiolvasás is A3=1, A2=A1=A0=0
       STAX D
       INX D
       DCR B
       JNZ TOLT
       END

6. k.)

Mi különbség adatátvitel szinkronizálása szempontjából a 8251-es soros áramkör aszinkron és szinkron soros adatátvitele között?

  • az aszinkron átvitel esetén a start és stop bitek segítségével szinkronizájla az átvitelt, a start bit megérkezésést az RXD 1 -> 0 átmenet jelzi
  • a szinkron átvitel esetén a szinkronizálást külső, vagy belső eljárással kell megoldani, SYNC karakter érkezésére várunk (belső) vagy a SYNDET-et bemenetként programozzuk fel

6. l.)

Programozzon fel egy 8253-as timer áramkört, amely 3,072MHz-ről 4800Hz frekvenciára osztja le jelet, 50-50%-os kitöltésűre! A 8253-as áramkör binárisan számol, és 90h báziscíme van. Használja a 0-s számlálót!

   ;3,072 Mhz=4800*640
   ;640= 0000 0001 | 0100 0000
   MOV A,00111110B
   OUT 93H
   MOV A,01H
   OUT 90H
   MOV A,80H
   OUT 91H

6. m.)

Egy kaszkádosított 8259-es rendszerben a MASTER egység IR7 és IR6 bemenetére SLAVE áramkörök kapcsolódnak. Adja meg, hogy milyen ICW3 parancsot kell küldeni a Master egységnek!

  • 11000000 (66.o./3.6.2.)

Adja meg, hogy milyen ICW3 parancsot kell küldeni Az IR6-ra csatlakozó SLAVE egységnek

  • 00000110 (66.o./3.6.2.)

Hogyan tudjuk kijelölni, hogy lesz ICW3 parancs?

  • az ICW1 SNGL bitjének 0 állapotba állításával, az ICW1 1. bitje (D1) (63.o. táblázat, 64.o. ICW1 - SNGL)

7. feladat

Ehhez létezik egy javításokat tartalmazó PDF. Megtekintés.

7. a.)

Sorolja fel az i8085 állapotait!

  • RUN, WAIT, HALT, HOLD

7. b.)

Szerkesszen gráfot, amely az i8085-ös állapotainak kapcsolatát ábrázolja! A nyilazott ágakra az állapot-változások okait kell felírni.

  • RUN -> WAIT: Ready jel 0 szintre vált
  • WAIT -> RUN: Ready jel 1-re vált
  • RUN -> HALT: HLT parancs kiadásakor
  • HALT -> RUN: megszakításkérés érkezésekor
  • RUN -> HOLD: HOLD 1-be vált
  • HOLD -> RUN: a HOLD jel megszűnése után
  • HALT -> HOLD: HOLD igény érkezésekor (HOLD=1)
  • HOLD -> HALT: HOLD megszűnése (HOLD=0)

7. c.)

Milyen esetekben kerül a 8085-ös mikroprocesszor HALT állapotból RUN állapotba?

  • HALT -> RUN: megszakításkérés érkezésekor, illetve reset hatására

7. d.)

Sorolja fel azokat az eseteket, amikor az INTE FF = 0 értékű lesz!

  • DI parancs kiadásakor, reset, megszakítás érvényre jutása után

7. e.)

Sorolja fel azokat az eseteket, amikor az RST7.5 FF = 0 értékű lesz!

  • SIM utasítás esetén,ha a 4. bittel töröljük az RST7.5-t (A4=1), illetve RESET után

7. f.)

Az i8085-ös processzor reszetelésekor milyen értékű lesz az INTEFF, és mi lesz a PC tartalma?

  • az INTEFF-kat törli, tehát 0 lesz , PC:0000H

7. g.)

Milyen kezdőcímeken kezdődnek az RST 2 és RST 5 utasításokkal meghívott szubrutinok, illetve az RST 5.5 és az RST 7.5 megszakítási szubrutinok?

  • RST 2: 10H
  • RST 5: 28H
  • RST 5.5: 2CH
  • RST 7.5: 3CH

7. h.)

Mit kell kezdőértéknek az SP-be betölteni ha a programozó úgy kívánja beállítani a STACK tárat, hogy az első értékes beírt bájt 8FFFh-ra íródjon? Miért?

  • 9000H, mert először csökkenti az SP értékét a processzor, és csak utána ír a stackre.

7. i.)

Hogyan jelezzük a fordítóprogramnak, hogy a generált kódot az 1698h címtől kezdődően helyezze el?

  • ORG 1698H

7. j.)

Hogyan jelezzük a fordítóprogramnak, hogy az 1712h címtől kezdődően helyezze el a „digit” stringet?

   ORG 1712H
   KAR DB "digit"

7. k.)

Hogyan jelezzük a fordítóprogramnak, hogy inicializált vagy inicializálatlan helyfoglalás történik?

  • inicializált: DB vagy DW,
  • inicializálatlan: DS direktívát használunk

7. l.)

Mi a különbség az EQU 1200h és a DW 1200h direktívák között?

  • CIMKE EQU 1200H: értékadás, hivatkozás a CIMKE-vel
  • DW 1200H: inicializált helyfoglalás

7. m.)

Sorolja fel az i8085 mikroprocesszor megszakítással kapcsolatos jeleit!

  • TRAP, RST 5.5,6.5,7.5, INTR

7. n.)

Milyen típusú kimenettel rendelkező áramkörökkel lehet busz rendszerű vezetékeket meghajtani? Húzza alá, hogy melyik típusú kimenet alkalmas arra, hogy egy vezetéket (busz) több kimenet egyidejűleg is meghajthasson?

  • tristate, open collector

7. o.)

Miért nem lehet két totem-pole kimenetű áramkör kimeneteit összekötni? Indokolja a választ? (sztem érdemes indokolni:))

  • mert az ellenáláskon túl nagy teljesítmény disszipálódna, és ennek eredménye a tönkremenetel

7. p.)

i8255-ös párhuzamos periféria áramkör A portját 1-es üzemmódban kimenetre, B-portját 0 üzemmódban bemenetre, C port alsó felét bemenetre, felső felét kimenetre kell állítani. Adja meg a vezérlő szó értékét!

  • 10100011

Adja meg, melyik regiszterbe és milyen értéket kell írni, hogy a fenti üzemmód esetén a PC4 portbit 0 , illetve 1 értékű legyen!

  • Bit Set/Reset művelettel: (a 8255-ös címe+3) címre kell kiküldeni a 00001000 byte-ot a 0-ba állításhoz, 00001001 byte-ot az 1-be állításhoz

7. q.)

Egy 3 gépi ciklusból álló utasítás (pl.: IN 83h) végrehajtása során az első gépi ciklus T1 fázisában egyidőben High (1) értékűek lesznek az INT és a HOLD bemenetek.

Mikor adja át a DMA vezérlőnek a 8085-ös a busz vezérlési jogot? Indokolja a válaszát!
a HOLD bemenet 1-be váltásakor
Mikor jut érvényre a megszakítás (megszakításkérés engedélyezett állapotban van és nincs más kérés) Indokolja a válaszát!
a HOLD jel megszűnését követően, hiszen a 7. b.) feladatban leírtak szerint működik a 8085, HOLD állapotból HALT-ba a HOLD=0-t követően, a HALT-ból a RUN-ba a megszakításkérést követően jut