Bölüm 9: Aygıt Kontrolü
Giriş
Öğrenme Çıktıları
IN ve OUT komutlarının biçimlerini ve sınırlarını bilmek.
Bir porttaki her bitin bir lambaya, mıknatısa ya da duruma karşılık geldiğini çözümlemek.
Aygıtın hazır bitini bekleyen döngüler yazmak.
INT 15h / AH = 86h ile mikrosaniye cinsinden bekleme süresi hesaplamak.
Trafik ışıkları, step motor, LED ekran, termometre, yazıcı, robot ve test aygıtını programlamak.
Programın ROM'dan RAM'e yüklenip çalıştırılma ilkesini açıklamak.
Giriş
emu8086'ya Bağlı 7 Sanal Aygıt
| Aygıt | Port(lar) | Yön | Veri |
|---|---|---|---|
| Trafik lambaları (traffic lights) | 4 | OUT | word: 12 lamba biti |
| Step motor (stepper motor) | 7 | OUT / IN | bit 0–2 mıknatıslar, bit 7 hazır |
| Robot | 9, 10, 11 | OUT / IN | komut, veri, durum |
| Test aygıtı (simple io test) | 110, 112 | IN / OUT | byte (110), word (112) |
| Termometre ve ısıtıcı | 125, 127 | IN / OUT | sıcaklık, ısıtıcı aç/kapa |
| Yazıcı (printer) | 130 | OUT | karakter (INT 21h/05h ile) |
| LED ekran (LED display) | 199 | OUT | word: işaretli sayı |
Aygıtlar emu8086'da virtual devices menüsünden açılır; programın başına #start=Traffic_Lights.exe# gibi bir yönerge yazılırsa emülatör aygıtı kendisi başlatır.
G/Ç Temelleri
Aygıt Kontrolü
- x86 ailesi CPU'lar geniş bir aygıt yelpazesini denetleyebilir. Temel G/Ç port numaraları sistemden sisteme farklılık gösterebilir ve uygun bir donanımla (adres çözücü, “tricky” elektronik devre) değiştirilebilir.
- Gömülü bir sistemde derlenen
.bindosyası Salt Okunur Bellek (ROM) yongasına yazılır. - Sistem açılınca programı ROM'dan okur, RAM'e yükler ve yürütür. Bu ilke birçok modern cihazda (çamaşır makinesi, yazıcı, modem…) kullanılır.
G/Ç Temelleri
IN ve OUT Komutları
| Biçim | Anlamı | Port aralığı |
|---|---|---|
IN AL, port | porttan 1 bayt oku | 0–255 (sabit) |
IN AX, port | porttan 1 word oku | 0–255 (sabit) |
IN AL, DX / IN AX, DX | port numarası DX'te | 0–65 535 |
OUT port, AL / OUT port, AX | porta yaz | 0–255 (sabit) |
OUT DX, AL / OUT DX, AX | port numarası DX'te | 0–65 535 |
OUT 4, BX veya IN CL, 7 geçersizdir.MOV DX, 300 yazılır, sonra OUT DX, AL. Bu derste tüm emu8086 portları 255'in altındadır.G/Ç Temelleri
Port Eşlemeli ve Bellek Eşlemeli G/Ç
- 8086'nın ayrı bir 64 K'lık G/Ç adres uzayı vardır.
- Erişim yalnızca
IN/OUTile; M/IO̅ pini G/Ç döngüsünü belirtir. - Bellek adreslerini tüketmez.
- Bu bölümdeki tüm aygıtlar böyledir.
- Aygıt yazmaçları bellek adreslerinde durur.
- Her MOV/ADD/CMP komutu kullanılabilir.
- Örnek: PC metin ekranı B800:0000'dan başlar; oraya yazılan bayt ekranda görünür.
Trafik Işıkları
Trafik Lambaları (Port 4)
- Kavşakta 4 direk, her direkte 3 lamba: toplam 12 lamba = port 4'e yazılan word'ün bit 0–11'i.
- Bit = 1 → lamba yanar, 0 → söner. Bit 12–15 kullanılmaz.
- Her direkte (k = 0…3): bit 3k kırmızı, 3k+1 sarı, 3k+2 yeşil.
- Örnek:
0000_0011_0000_1100b→ bit 2 ve 8 (yeşil), bit 3 ve 9 (kırmızı).
| Direk | Bitler |
|---|---|
| sağ alt | 0 1 2 |
| sağ üst | 3 4 5 |
| sol üst | 6 7 8 |
| sol alt | 9 A B |
Trafik Işıkları
Durum (Situation) Tablosu
; FEDC_BA98_7654_3210 situation dw 0000_0011_0000_1100b s1 dw 0000_0110_1001_1010b s2 dw 0000_1000_0110_0001b s3 dw 0000_1000_0110_0001b s4 dw 0000_0100_1101_0011b sit_end = $ all_red equ 0000_0010_0100_1001b
| Ad | Hex | Lambalar |
|---|---|---|
situation | 030Ch | sağ alt: yeşil; sağ üst: kırmızı; sol üst: yeşil; sol alt: kırmızı |
s1 | 069Ah | sağ alt: sarı; sağ üst: kırmızı + sarı; sol üst: sarı; sol alt: kırmızı + sarı |
s2 | 0861h | sağ alt: kırmızı; sağ üst: yeşil; sol üst: kırmızı; sol alt: yeşil |
s3 | 0861h | sağ alt: kırmızı; sağ üst: yeşil; sol üst: kırmızı; sol alt: yeşil |
s4 | 04D3h | sağ alt: kırmızı + sarı; sağ üst: sarı; sol üst: kırmızı + sarı; sol alt: sarı |
all_red | 0249h | sağ alt: kırmızı; sağ üst: kırmızı; sol üst: kırmızı; sol alt: kırmızı |
s2 ve s3 aynıdır: yan yol yeşili iki aralık (10 s) sürer. s1 ve s4 sarı geçişleridir (kırmızı + sarı = “hazırlan”).
Trafik Işıkları
Durumlar Adım Adım
all_red = 0249h → sağ alt: kırmızı; sağ üst: kırmızı; sol üst: kırmızı; sol alt: kırmızı
situation = 030Ch → sağ alt: yeşil; sağ üst: kırmızı; sol üst: yeşil; sol alt: kırmızı
s1 = 069Ah → sağ alt: sarı; sağ üst: kırmızı + sarı; sol üst: sarı; sol alt: kırmızı + sarı
s2 = 0861h → sağ alt: kırmızı; sağ üst: yeşil; sol üst: kırmızı; sol alt: yeşil
s3 = 0861h → sağ alt: kırmızı; sağ üst: yeşil; sol üst: kırmızı; sol alt: yeşil
s4 = 04D3h → sağ alt: kırmızı + sarı; sağ üst: sarı; sol üst: kırmızı + sarı; sol alt: sarı
Program önce tüm yönleri kırmızı yapar, sonra situation → s1 → s2 → s3 → s4 → situation… diye 5 saniyelik aralıklarla döner.
Trafik Işıkları
INT 15h / AH = 86h ile Bekleme
; 5 saniye bekle (5 milyon µs) mov cx, 4Ch ; 004C4B40h = 5 000 000 mov dx, 4B40h mov ah, 86h int 15h
- BIOS işlevi INT 15h, AH = 86h: CX:DX mikrosaniye bekler.
- CX yüksek word, DX düşük word: 32 bitlik bekleme süresi.
5 s = 5 × 1 000 000 = 5 000 000 µs
Süre mikrosaniyeye çevrilir.
5 000 000 ÷ 16 = 312 500 kalan 0
312 500 ÷ 16 = 19 531 kalan 4
19 531 ÷ 16 = 1 220 kalan 11 (B)
1 220 ÷ 16 = 76 kalan 4
76 ÷ 16 = 4 kalan 12 (C)
4 ÷ 16 = 0 kalan 4
Ardışık 16'ya bölme: kalanlar sondan başa okunur → 4C4B40h.
0 0 4 C | 4 B 4 0
CX = 004Ch · DX = 4B40h
32 bitlik değer 0000 0000 0100 1100 0100 1011 0100 0000b ikiye bölünür.
1 s → 1 000 000 = 000F4240h → CX = 000Fh, DX = 4240h
Başka bir örnek: 1 saniyelik bekleme.
Trafik Işıkları · Kodu adım adım çalıştır
Trafik Işıkları Programı
Tablo 0124h'de varsayıldı (ORG 100h; adres derleyiciye göre değişebilir). sit_end = 012Eh.
AX = all_red = 0249h (sabit, EQU).
Port 4'e yaz: tüm yönler kırmızı.
SI = 0124h: tablonun başı (situation).
AX ← [SI] = 030Ch.
OUT 4, AX: lambalar yeni duruma geçer (SI = 0124h).
CX = 004Ch (bekleme süresinin yüksek word'ü).
DX = 4B40h (düşük word).
AH = 86h: BIOS bekleme işlevi.
INT 15h: 5 saniye bekle.
SI = 0126h: sonraki word.
CMP SI, sit_end (012Eh): SI < sit_end → CF = 1.
JB: CF = 1, next'e dön.
… bekleme ve SI artırma … OUT 4, AX: SI = 0126h → port 4 = 069Ah.
… bekleme ve SI artırma … OUT 4, AX: SI = 0128h → port 4 = 0861h.
… bekleme ve SI artırma … OUT 4, AX: SI = 012Ah → port 4 = 0861h.
… bekleme ve SI artırma … OUT 4, AX: SI = 012Ch → port 4 = 04D3h.
CMP SI, sit_end (012Eh): SI = sit_end → CF = 0.
JB: CF = 0, atlama yok: tablo bitti.
SI = 0124h: tabloya baştan başla.
JMP next: sonsuz döngü.
… bekleme ve SI artırma … OUT 4, AX: SI = 0124h → port 4 = 030Ch.
#start=Traffic_Lights.exe# mov ax, all_red out 4, ax mov si, offset situation next: mov ax, [si] out 4, ax mov cx, 4Ch ; 5 s bekle mov dx, 4B40h mov ah, 86h int 15h add si, 2 ; sonraki durum cmp si, sit_end jb next mov si, offset situation jmp next
Döngü hiç bitmez: gömülü sistemlerde ana program genellikle sonsuz bir döngüdür.
Trafik Işıkları
Etkileşimli Trafik Bit Düzenleyici
Bitlere tıklayın (F…0). Bit 12–15 kullanılmaz.
Step Motor
Step Motor (Port 7)
- Motor hem saat yönünde (CW) hem de tersine (CCW) döndürülebilir.
- Port 7'ye yazılan baytın bit 0, 1, 2'si üç elektromıknatısı açar/kapatır.
- Yarı adım 11,25°, tam adım 22,5°'dir.
- Yarı adım: çift mıknatıs, ardından tek mıknatıs açılarak döndürülür.
- Tam adım: çift mıknatıs, çift mıknatıs, tek mıknatıs şeklinde devam eder.
- Motor yeni komut almaya hazır olduğunda porttan okunan baytın bit 7'sini 1 yapar.
Step Motor
Step Motor Veri Tabloları
| Tablo | Anlam | 1 | 2 | 3 | 4 |
|---|---|---|---|---|---|
datcw | CW yarı adım | 110 | 100 | 011 | 010 |
datccw | CCW yarı adım | 011 | 001 | 110 | 010 |
datcw_fs | CW tam adım | 001 | 011 | 110 | 000 |
datccw_fs | CCW tam adım | 100 | 110 | 011 | 000 |
- Tablolar bellekte arka arkaya durur: her biri 4 bayt. Bu yüzden
add bx, 4bir sonraki tabloya geçirir. - Program 32 (20h) tur sonra tabloyu değiştirir: CW yarı → CCW yarı → CW tam → CCW tam → başa.
- Bayt değerindeki bitler mıknatısları gösterir:
110b= mıknatıs 2 ve 1 açık;000b= hepsi kapalı. - Kaynak koddaki biçim:
datcw db 0000_0110bve alt satırlardadb 0000_0100b… (alt çizgi yalnızca okunabilirlik içindir).
Step Motor
Mıknatıs Dizileri Adım Adım
- Yarı adım dizisi (datcw): çift → tek → çift → tek mıknatıs.
- Tam adım dizisi (datcw_fs): tek, çift, çift ve “hepsi kapalı” bayt.
- Her OUT komutundan sonra motor yeni konumuna gidene kadar meşguldur; bu yüzden program her bayttan önce bit 7'yi yoklar.
CW yarı adım, 1. bayt: açık mıknatıslar → 2, 1
CW yarı adım, 2. bayt: açık mıknatıslar → 2
CW yarı adım, 3. bayt: açık mıknatıslar → 1, 0
CW yarı adım, 4. bayt: açık mıknatıslar → 1
CW tam adım, 1. bayt: açık mıknatıslar → 0
CW tam adım, 2. bayt: açık mıknatıslar → 1, 0
CW tam adım, 3. bayt: açık mıknatıslar → 2, 1
CW tam adım, 4. bayt: açık mıknatıslar → hiçbiri
Step Motor
Step Motor Kontrol Programı
ORG 100h steps_before_direction_change = 20h jmp start datcw db 110b,100b,011b,010b datccw db 011b,001b,110b,010b datcw_fs db 001b,011b,110b,000b datccw_fs db 100b,110b,011b,000b start: mov bx, offset datcw mov si, 0 mov cx, 0 ; tur sayacı
- Yoklama (wait): bit 7 = 0 ise motor meşgul, tekrar oku.
[bx][si]= [BX + SI]: BX tablonun başı, SI sıra (0–3).- 4 bayt gönderilince SI = 0, CX +1; CX = 20h olunca BX 4 artar, son tablodan sonra başa döner.
steps_before_direction_change = 20hbir sabittir (EQU gibi), bellekte yer kaplamaz.
next_step: wait: in al, 7 test al, 10000000b jz wait mov al, [bx][si] out 7, al inc si cmp si, 4 jb next_step mov si, 0 inc cx cmp cx, steps_before_direction_change jb next_step mov cx, 0 add bx, 4 ; sonraki tablo cmp bx, offset datccw_fs jbe next_step mov bx, offset datcw jmp next_step
Step Motor · Kodu adım adım çalıştır
Step Motor: İlk Tur
ORG 100h, steps_before_direction_change = 20h. Port 7 önce 00h (meşgul), sonra 80h (hazır) döndürecek.
Veri tablolarının üzerinden atla.
BX = 0102h: datcw tablosu (CW yarı adım).
SI = 0: tablonun ilk baytı.
CX = 0: tur sayacı.
IN AL, 7 → AL = 00h (bit 7 = 0, motor meşgul).
TEST AL, 80h → ZF = 1.
JZ: ZF = 1 → tekrar bekle.
IN AL, 7 → AL = 80h (bit 7 = 1, hazır).
TEST AL, 80h → ZF = 0.
JZ: ZF = 0 → devam.
AL ← [BX+SI] = [0102h] = 110b.
OUT 7, AL: mıknatıslar 110b → motor yarım adım (11,25°) döner.
SI = 1.
CMP SI, 4 → CF = 1.
JB: SI < 4 → next_step.
IN AL, 7 → AL = 80h (bit 7 = 1, hazır).
TEST AL, 80h → ZF = 0.
JZ: ZF = 0 → devam.
AL ← [BX+SI] = [0103h] = 100b.
OUT 7, AL: mıknatıslar 100b → motor yarım adım (11,25°) döner.
SI = 2.
CMP SI, 4 → CF = 1.
JB: SI < 4 → next_step.
IN AL, 7 → AL = 80h (bit 7 = 1, hazır).
TEST AL, 80h → ZF = 0.
JZ: ZF = 0 → devam.
AL ← [BX+SI] = [0104h] = 011b.
OUT 7, AL: mıknatıslar 011b → motor yarım adım (11,25°) döner.
SI = 3.
CMP SI, 4 → CF = 1.
JB: SI < 4 → next_step.
IN AL, 7 → AL = 80h (bit 7 = 1, hazır).
TEST AL, 80h → ZF = 0.
JZ: ZF = 0 → devam.
AL ← [BX+SI] = [0105h] = 010b.
OUT 7, AL: mıknatıslar 010b → motor yarım adım (11,25°) döner.
SI = 4.
CMP SI, 4 → CF = 0.
JB: SI = 4: tablo bitti.
SI = 0: tabloyu baştan oku.
CX = 1: bir tur (4 adım) tamamlandı.
CMP CX, 20h → CF = 1 (henüz 32 tur olmadı).
JB next_step: aynı tabloyla devam. 32 turdan sonra add bx, 4 sonraki tabloya geçer.
jmp start ; tablolar 0102h-0111h start: mov bx, offset datcw mov si, 0 mov cx, 0 ; tur sayacı next_step: wait: in al, 7 test al, 10000000b jz wait mov al, [bx][si] out 7, al inc si cmp si, 4 jb next_step mov si, 0 inc cx cmp cx, steps_before_direction_change jb next_step
LED Ekran
LED Ekran (Port 199)
- Port 199'a yazılan word 5 haneli onluk sayı olarak gösterilir.
- Değer işaretli (ikiye tümleyen) yorumlanır: −32 768 … 32 767.
- −5678 = 10000h − 162Eh = E9D2h; ekranda -5678 görünür.
- Yalnızca
OUT 199, AXkullanılır (199 ≤ 255 olduğundan sabit port yeterli).
LED Ekran · Kodu adım adım çalıştır
LED Ekran Kontrolü
Ekran başlangıçta 00000 gösterir.
AX = 1234 (onluk) = 04D2h.
OUT 199, AX: ekranda 1234.
AX = −5678 = E9D2h (ikiye tümleyen).
OUT 199, AX: ekranda -5678.
AX = 0: sayaç.
OUT 199, AX: ekranda 0.
AX = 1.
JMP x1: sonsuz döngü (alttaki HLT'ye hiç ulaşılmaz).
OUT 199, AX: ekranda 1.
AX = 2.
JMP x1: sonsuz döngü (alttaki HLT'ye hiç ulaşılmaz).
OUT 199, AX: ekranda 2.
AX = 3.
JMP x1: sonsuz döngü (alttaki HLT'ye hiç ulaşılmaz).
#start=led_display.exe# mov ax, 1234 out 199, ax mov ax, -5678 out 199, ax ; port'a sonsuz döngüde yaz: mov ax, 0 x1: out 199, ax inc ax jmp x1 hlt ; hiç çalışmaz
emu8086'da adım gecikmesi (step delay) 0 iken sayılar çok hızlı akar; döngüye INT 15h/86h ile bekleme eklenebilir.
Termometre
Termometre ve Isıtıcı (Port 125, 127)
IN AL, 125: anlık hava sıcaklığını (°C, işaretli bayt) okur.OUT 127, AL: AL = 1 ısıtıcıyı açar, AL = 0 kapatır.- Isıtıcı açıkken sıcaklık yavaşça artar, kapalıyken düşer.
- Amaç: sıcaklığı 60–80 °C arasında tutan bir termostat.
- Sıcaklık eksi olabileceği için karşılaştırmalar işaretli atlamalarla (
JL,JLE,JG) yapılır.
Termometre · Kodu adım adım çalıştır
Termostat Programı
Port 125 sırayla 55, 70 ve 85 °C döndürecek. Isıtıcı başlangıçta kapalı.
AX = CS = 0700h.
DS = 0700h (kesim yazmacına sabit doğrudan yazılamaz).
IN AL, 125 → sıcaklık 55 °C.
CMP AL, 60: 55 − 60 → SF = 1, OF = 0.
JL (SF ≠ OF): 55 < 60 → low.
AL = 1.
OUT 127, AL: ısıtıcı açıldı.
JMP ok.
JMP start: yeni ölçüm.
IN AL, 125 → sıcaklık 70 °C.
CMP AL, 60: 70 − 60 → SF = 0, OF = 0.
JL (SF ≠ OF): atlama yok.
CMP AL, 80 → ZF = 0, SF = 1.
JLE: 60 ≤ 70 ≤ 80 → ok (ısıtıcıya dokunma).
JMP start: yeni ölçüm.
IN AL, 125 → sıcaklık 85 °C.
CMP AL, 60: 85 − 60 → SF = 0, OF = 0.
JL (SF ≠ OF): atlama yok.
CMP AL, 80 → ZF = 0, SF = 0.
JLE: atlama yok.
JG: 85 > 80 → high.
AL = 0.
OUT 127, AL: ısıtıcı kapatıldı.
JMP start: yeni ölçüm.
; DS'yi CS'ye eşitle: mov ax, cs mov ds, ax start: in al, 125 cmp al, 60 jl low cmp al, 80 jle ok jg high low: mov al, 1 out 127, al ; ısıtıcı açık jmp ok high: mov al, 0 out 127, al ; ısıtıcı kapalı ok: jmp start ; sonsuz döngü
jg high yerine jmp high da yazılabilirdi: JLE atlamadıysa sıcaklık zaten 80'den büyüktür.
Termometre
Etkileşimli Termostat
Yazıcı
Yazıcı (Printer, Port 130)
- emu8086 yazıcısı port 130'a bağlıdır; ama program porta doğrudan yazmak yerine DOS işlevini kullanır:
INT 21h,AH = 05h: DL'deki karakteri yazıcıya (PRN) gönderir.- Denetim karakterleri yazıcıyı yönetir:
| Kod | Ad | Etki |
|---|---|---|
| 0Ah (10) | LF | bir satır aşağı |
| 0Dh (13) | CR | satır başına dön |
| 09h (9) | HT | yatay sekme (tab) |
| 0Ch (12) | FF | yeni sayfa (form feed) |
db 13, 9 için “carriage return and vertical tab” yazıyordu. 9 yatay sekmedir (HT); dikey sekme (VT) 11 = 0Bh'dir.Ayrıca
0Ah, 0Dh sırası LF + CR'dir; alışılmış sıra CR + LF'tir, ama ikisi birlikte aynı sonucu verir.Yazıcı
Yazıcı Programı: Veri
org 100h jmp start msg db "Hello, Printer!", 0Ah, 0Dh db "***************" db 13, 9 ; CR ve yatay sekme (HT) db "Have a nice printing day!" msg_end db 0 msg2 db "press any key to eject the page.$"
offset msg_end - offset msg derleme zamanında hesaplanır: 15 + 2 + 15 + 2 + 25 = 59 = 3Bh bayt.'$' ile biter: INT 21h / AH = 09h ekrana yazdırırken $'a kadar gider.Yazıcı · Kodu adım adım çalıştır
Yazıcı Programı: Yazdırma Döngüsü
Çıktı paneli yazıcı kâğıdını gösterir: LF satır atlar, CR satır başına döner, TAB 8 sütunluk sekmeye gider.
DL = 12 (0Ch): form feed.
AH = 05h: DOS yazıcı çıkışı.
INT 21h: yazıcı yeni sayfaya geçer.
SI = 0102h: msg'nin adresi.
CX = 59 (003Bh): karakter sayısı.
DL ← [SI] = 'H'.
AH = 05h: DOS yazıcı çıkışı.
INT 21h: 'H' yazıcıya gider.
SI = 0103h.
LOOP: CX = 58 → devam.
DL ← [SI] = 'e'.
AH = 05h: DOS yazıcı çıkışı.
INT 21h: 'e' yazıcıya gider.
SI = 0104h.
LOOP: CX = 57 → devam.
DL ← [SI] = 'l'.
AH = 05h: DOS yazıcı çıkışı.
INT 21h: 'l' yazıcıya gider.
SI = 0105h.
LOOP: CX = 56 → devam.
… INT 21h: 'l' yazıldı (CX = 56).
… INT 21h: 't' yazıldı (CX = 48).
… INT 21h: '*' yazıldı (CX = 40).
… INT 21h: '*' yazıldı (CX = 32).
… INT 21h: 'a' yazıldı (CX = 24).
… INT 21h: 'c' yazıldı (CX = 16).
… INT 21h: 'i' yazıldı (CX = 8).
DL ← [SI] = '!'.
AH = 05h: DOS yazıcı çıkışı.
… INT 21h: '!' yazıldı (CX = 1).
SI = 013Dh.
LOOP: CX = 0 → 59 karakter bitti.
start: mov dl, 12 ; form feed: yeni sayfa mov ah, 5 int 21h mov si, offset msg mov cx, offset msg_end - offset msg print: mov dl, [si] mov ah, 5 ; DOS yazıcı işlevi int 21h inc si ; sonraki karakter loop print
CR (13) LF olmadan gelince üçüncü metin yıldızların üzerine basılır (panelde üzerine yazma olarak gösterildi). Döngüden sonra: mov dx, offset msg2 / mov ah, 9 / int 21h ekrana mesaj yazar; int 16h (AH = 0) bir tuş bekler; son form feed sayfayı yazıcıdan çıkarır.
Robot
Robot (Port 9, 10, 11)
- Robot bir ızgara dünyasında hareket eder; duvarları ve lambaları algılayabilir, lambaları yakıp söndürebilir.
- Port 9 komut (OUT), port 10 veri (IN), port 11 durum (IN). Dünya, aygıt penceresindeki araç kutusuyla düzenlenir.
Robot
Robot Komutları ve Durum Bitleri
| Komut (port 9) | Etki |
|---|---|
| 0 | hiçbir şey yapma |
| 1 | ileri git |
| 2 | sola dön |
| 3 | sağa dön |
| 4 | önündekini incele (examine) |
| 5 | lambayı yak |
| 6 | lambayı söndür |
| Veri (port 10) | Önündeki |
|---|---|
| 255 (FFh) | duvar |
| 0 | boş |
| 7 | yanan lamba |
| 8 | sönük lamba |
| Durum (port 11) | 1 ise |
|---|---|
| bit 0 | veri yazmacında yeni veri var |
| bit 1 | robot meşgul (komut sürüyor) |
| bit 2 | son komutta hata |
Robot
Robot Programı: Lambayı Bul ve Yak
#start=robot.exe# dongu: CALL hazir_bekle MOV AL, 4 ; incele OUT 9, AL CALL veri_bekle IN AL, 10 CMP AL, 0FFh ; duvar? JE don CMP AL, 8 ; sönük lamba? JNE ilerle CALL hazir_bekle MOV AL, 5 ; yak OUT 9, AL JMP dongu don: MOV AL, 3 ; sağa dön JMP gonder ilerle: MOV AL, 1 ; ileri gonder: PUSH AX ; komutu koru CALL hazir_bekle POP AX OUT 9, AL JMP dongu
- Her komuttan önce meşgul biti (bit 1) sıfır olana kadar beklenir.
- İncele (4) komutundan sonra veri hazır biti (bit 0) beklenir, sonra port 10 okunur.
- Duvarsa sağa dön, sönük lambaysa yak, yoksa ilerle.
- Bekleme yordamları
CALLile çağrılır: dönüş adresi yığında (Bölüm 8).
Robot
Robot: Bekleme Yordamları ve Dikkat Edilecekler
hazir_bekle PROC b1: IN AL, 11 TEST AL, 010b ; meşgul? JNZ b1 RET hazir_bekle ENDP veri_bekle PROC v1: IN AL, 11 TEST AL, 001b ; yeni veri? JZ v1 RET veri_bekle ENDP
hazir_bekle AL'yi IN ile ezer. gonder yolunda AL komut değerini taşıdığı için yordamdan önce PUSH AX, sonra POP AX yapılır; aksi hâlde porta durum baytı gönderilirdi.Robot
Basit G/Ç Test Aygıtı (Port 110, 112)
- Port 110: bir bayt; port 112: bir word.
- Pencereye yazılan değerler programa giriş olur (hex için
hsoneki), programın yazdıkları pencerede görünür. - Giriş portları her 100 ms'de güncellenir.
- IN/OUT'u denemek ve hata ayıklamak için idealdir.
IN AL, 110 ; ör. A7h okunur INC AL OUT 110, AL ; A8h yazılır IN AX, 112 ; ör. 1234h ADD AX, 1 OUT 112, AX ; 1235h
Özet
Özet
| Aygıt | Port | Anahtar fikir |
|---|---|---|
| Trafik lambaları | 4 | Her bit bir lamba; durum tablosu + INT 15h/86h bekleme. |
| Step motor | 7 | Bit 0–2 mıknatıs, bit 7 hazır; yarı adım 11,25°, tam adım 22,5°. |
| LED ekran | 199 | Word, işaretli onluk gösterim. |
| Termometre | 125, 127 | Okuma + işaretli karşılaştırma + ısıtıcı aç/kapa. |
| Yazıcı | 130 | INT 21h/05h; denetim karakterleri LF, CR, HT, FF. |
| Robot | 9, 10, 11 | Komut, veri, durum; meşgul/veri bitlerini yokla. |
| Test aygıtı | 110, 112 | Bayt ve word G/Ç denemesi. |
Ortak desen: durum oku → bit test et → hazırsa veri yaz/oku → döngü. IN/OUT yalnızca AL/AX ile, port > 255 ise DX ile.
Özet
Alıştırmalar
- Tüm yönlerde yalnızca sarı lambaları yakan port 4 değeri nedir?
- 2,5 saniyelik bekleme için CX ve DX ne olmalıdır?
- LED ekranda −1 göstermek için AX'e hangi hex değer yazılır?
- Termostatı 20–25 °C aralığına göre değiştirin; sıcaklık −10 °C iken
JBkullanılsaydı ne olurdu? - Step motor programında motoru yalnızca saat yönünde, tam adımla döndürmek için hangi satırlar değişmeli?
- Yazıcıya “Merhaba” yazıp sayfayı çıkaran en kısa programı yazın.
Cevaplar
- Bit 1, 4, 7, 10 → 0000_0100_1001_0010b = 0492h.
- 2 500 000 = 002625A0h → CX = 0026h, DX = 25A0h.
- FFFFh.
cmp al, 20 / jl low / cmp al, 25 / jle ok / .... −10 = F6h; işaretsiz JB için 246 > 20 olur ve ısıtıcı açılmazdı.mov bx, offset datcw_fsve tablo değiştiren kısım (inc cx…jmp next_step) kaldırılıpjmp next_stepyazılır.- Her karakter için
MOV DL, 'M'/MOV AH, 5/INT 21h(veya döngü), sonunda DL = 12 ile form feed.
Özet
Kaynaklar
- emu8086 yardım belgeleri: I/O ports and hardware interrupts, Virtual devices ve örnek programlar (traffic_lights.asm, stepper_motor.asm, led_display_test.asm, thermometer.asm, printer.asm, robot.asm).
- Intel, The 8086 Family User's Manual, 1979 — IN/OUT komutları ve G/Ç adres uzayı.
- R. Brown, Ralf Brown's Interrupt List — INT 15h/86h, INT 21h/05h, INT 16h/00h.
- B. B. Brey, The Intel Microprocessors, 8. baskı, Pearson, 2009 — Bölüm 11 (Temel G/Ç arabirimi).