You are on page 1of 145

TRÖÔØNG ÑAÏI HOÏC KYÕ THUAÄT

KHOA COÂNG NGHEÄ THOÂNG TIN


WX

LUAÄN VAÊN TOÁT NGHIEÄP


Ñeà taøi:

Thieát keá, thi coâng vaø vieát chöông trình ñieàu khieån
maïch thöïc haønh cho Z80 CPU.
Giao tieáp vôùi maùy tính qua ngoõ maùy in.

Giaùo vieân höôùng daãn: Thaày Nguyeãn Xuaân Minh.


Sinh vieân thöïc hieän : Hoaøng Leâ Bình.
Löu Ñình Duõng.
Lôùp : KSII_K6_T.
Ñeà taøi:

Thieát keá, thi coâng vaø vieát chöông trình ñieàu khieån maïch thöïc haønh cho Z80 CPU vôùi caùc ñaëc
ñieåm sau:
- Giao tieáp vôùi maùy tính qua ngoõ maùy in.
- Giaû laäp ROM ñeå nhaän chöông trình töø maùy tính.
- Coù khaû naêng chaïy töøng böôùc töø beân maùy tính.
- Coù khaû naêng thoâng baùo traïng thaùi caùc thanh ghi veà beân maùy tính.
- Coù khaû naêng ñieàu khieån moät soá coång xuaát nhaäp ñôn giaûn.
- Thi coâng maïch, thöû maïch.
- Vieát chöông trình vaø thöû chaïy theo töøng chöùc naêng.

WX

WX WX

2
MUÏC LUÏC
Môû ñaàu ...............................................................................................................trang 4

) Chöông I Phaân tích yeâu caàu


1.1 Phaân tích yeâu caàu.........................................................................................trang 5
1.2 Phöông höôùng giaûi quyeát vaán ñeà ................................................................trang 5

) Chöông II Thieát keá phaàn cöùng


z 2.1. Phaân tích caùc chöùc naêng cuûa coång gheùp noái vôùi maùy in ........................trang 8
z 2.2. Kieán truùc Z80 CPU. .................................................................................trang 10
z 2.3. Thieát keá chi tieát........................................................................................trang 48
z 2.4. Nguyeân lyù hoaït ñoäng. ..............................................................................trang 49

) Chöông III. Giôùi thieäu phaàn soaïn thaûo vaên baûn


3.1. Caùc thaønh phaàn chính cuûa main menu ........................................................trang 55
3.2. Höôùng daãn söû duïng trong maøn hình soaïn thaûo ...........................................trang 55

) Chöông IV. Giaûi thuaät ....................................................................................trang 57

) Chöông V. Chöông trình nguoàn


5.1. Chöông trình ñöa data ra RAM chung, Debug, Dump, Run......................trang 71
5.2. Chöông trình con vieát baèng ngoân ngöõ con Assembler Z80 duøng
ñoïc traïng thaùi caùc thanh ghi .......................................................................trang 109
5.3. Chöông trình con vieát baèng ngoân ngöõ con Assembler Z80 duøng
dump memory ..............................................................................................trang 111
5.4. Chöông trình taïo tieän ích soaïn thaûo vaên baûn vaøhoã trôï cheá ñoä chaïy
debug Z80.....................................................................................................trang 111
5.5. Caùc chöông trình ví duï.................................................................................trang 133

) Phuï luïc A: Caùc thoâng baùo loãi. .......................................................................trang 142

) Phuï luïc B: Vi maïch 8255. ..............................................................................trang 143

) Taøi lieäu tham khaûo.........................................................................................trang 145

WX WX

3
Lôøi noùi ñaàu
Söï phaùt trieån ñi leân vöôït baäc cuûa ngaønh kyõ thuaät maùy tính vaø ñieän töû hieän nay ñaõ ñöôïc minh
chöùng cuï theå qua cuoäc soáng haèng ngaøy cuûa chuùng ta trong taát caû caùc lónh vöïc.
Vieäc öùng duïng maùy vi tính vaøo kyõ thuaät ño löôøng vaø ñieàu khieån ñaõ ñem laïi nhöõng keát quaû ñaày
tính öu vieät. Caùc thieát bò, heä thoáng ño löôøng vaø ñieàu khieån gheùp noái vôùi maùy tính coù ñoä chính xaùc
cao, thôøi gian thu thaäp soá lieäu ngaén, nhöng ñaùng quan taâm hôn laø möùc ñoä töï ñoäng hoaù trong vieäc
thu nhaän vaø xöû lyù döõ lieäu.
Kyõ thuaät soá ra ñôøi ñaõ khaéc phuïc ñöôïc caùc khuyeát ñieåm cuûa kyõ thuaät töông töï, laøm cho caùc boä
phaän maùy moùc trôû neân ñôn giaûn, goïn nheï, ít toán keùm naêng löôïng vaø xöû lyù thoâng tin nhanh, chính
xaùc hôn so vôùi kyõ thuaät töông töï.
Tuy vaäy, neáu söû duïng caùc boä ñieàu khieån duøng caùc IC soá chuùng vaãn coøn maéc moät soá khuyeát
ñieåm maø so vôùi kyõ thuaät vi xöû lyù noù vaãn toàn taïi nhö:
- Kích thöôùc lôùn.
- Naêng löôïng tieâu thuï lôùn.
- Tính meàm deõo thaáp, khoù thay ñoåi.
- Khoù söûa chöõa, baûo trì.
Vi xöû lyù laø moät vi maïch ñieän töû coù maät ñoä tích hôïp cao, trong ñoù goàm caùc maïch soá coù khaû
naêng nhaän, xöû lyù vaø xuaát döõ lieäu. Ñaëc bieät laø quaù trình xöû lyù döõ lieäu ñöôïc ñieàu khieån theo moät
chöông trình goàm taäp hôïp caùc leänh töø beân ngoaøi maø ngöôøi söû duïng coù theå thay ñoåi ñöôïc moät caùch
deã daøng. Moät vi xöû lyù coù theå thöïc hieän raát nhieàu yeâu caàu ñieàu khieån khaùc nhau.
Kyõ thuaät vi xöû lyù ra ñôøi vôùi söï keát hôïp giöõa phaàn cöùng vaø phaàn meàm ñaõ laøm cho hoaït ñoäng
cuûa caùc maïch ñieän trôû neân meàm deõo hôn vôùi nhöõng phaàn meàm raát linh hoaït maø ta coù theå söûa
chöõa, thay ñoåi hoaëc boå sung laøm cho chöông trình ñieàu khieån theâm phong phuù tuøy theo nhu caàu
cuûa ngöôøi söû duïng.
Kyõ thuaät vi xöû lyù coù tính phöùc taïp trong hoaït ñoäng, thieát keá nhöng laïi raát kinh teá vì giaù thaønh
haï vaø kích thöôùc chieám choã khoâng nhieàu, coù dung löôïng cao. Ngoaøi ra veà maët kyõ thuaät cuõng hôn
haún kyõ thuaät soá vì quaù trình hoaït ñoäng raát meàm deõo, toác ñoä xöû lyù cao vaø laïi coù theå môû roäng tính
naêng hoaït ñoäng sau naøy cho maïch ñieän. Ñaây laø öu ñieåm raát thuaän lôïi maø kyõ thuaät vi xöû lyù mang
laïi.

Chuùng em xin chaân thaønh caûm ôn Thaày Nguyeãn Xuaân Minh ñaõ taän tình höôùng daãn ñeå hoaøn
thaønh luaän vaên naøy. Chuùng toâi cuõng xin chaân thaønh caûm ôn caùc baïn beø ñaõ ñoùng goùp yù kieán vaø chæ
daãn trong khi thöïc hieän ñeà taøi.

Vì trình ñoä coù haïn vaø ñaây laøñeà taøi ñaàu tieân thöïc hieän moät caùch coù heä thoáng cho neân chaéc chaén
khoâng theå traùnh khoûi nhieàu thieáu soùt.

WX WX

4
Chöông I. Phaân tích yeâu caàu

1.1. Phaân tích yeâu caàu.

1.1.1. Ñaëc ñieåm cuûa coång gheùp noái vôùi maùy in.

Vieäc noái maùy in vôùi maùy tính ñöôïc thöïc hieän qua oå caém 25 chaân ôû phiaù sau maùy tính. Nhöng
ñaây khoâng chæ laø choã noái vôùi maùy in maø khi söû duïng maùy tính vaøo muïc ñích ño löôøng vaø ñieàu
khieån thì vieäc gheùp noái cuõng thöïc hieän qua oå caém naøy. Qua coång naøy döõ lieäu ñöôïc truyeàn ñi song
song neân ñoâi khi coøn ñöôïc goïi laø coång gheùp noái song song vaø toác ñoä truyeàn döõ lieäu cuõng ñaït ñeán
möùc lôùn ñaùng keå. Taát caû caùc ñöôøng daãn cuûa coång naøy ñeàu töông thích TTL, nghóa laø chuùng ñeàu
cung caáp moät möùc ñieän aùp naèm giöõa 0V vaø 5V. Do ñoù ta coøn caàn phaûi löu yù laø ôû caùc ñöôøng daãn
loái vaøo coång naøy khoâng ñöôïc ñaët caùc möùc ñieän aùp quaù lôùn.

1.1.2. Ñaëc ñieåm chung cuûa Z80 CPU.

Z80 CPU laø moät vi xöû lyù 8 bit cuûa haõng ZILOG ñöôïc thieát keá ñeå coù theå laøm vieäc moät caùch ñoäc
laäp, coù theå giao tieáp vôùi caùc boä xöû lyù khaùc thoâng qua caùc thieát bò ngoaïi vi.
Ñaëc ñieåm chung:
- Data bus: 8 bits.
- Addr bus: 16 bits.
- Taäp thanh ghi ñöôïc phaân thaønh 3 loaïi:
. Taäp thanh ghi chính (8 bit).
. Taäp thanh ghi phuï (8 bit).
. Taäp thanh ghi chuyeân duïng (16 bits)
- Taäp leänh CPU Z80 coù theå chia laøm nhieàu nhoùm khaùc nhau theo nhieàu caùch. ÔÛ ñaây
coù theå chia thaønh 4 nhoùm sau:
. Nhoùm leänh xöû lyù döõ kieän.
. Nhoùm leänh truyeàn döõ kieän.
. Nhoùm leänh kieåm soaùt chöông trình.
. Nhoùm leänh kieåm soaùt traïng thaùi.

Phaàn moâ taû chi tieát Z80 CPU seõ ñöôïc noùi kyõ trong chöông II.

1.2. Phöông höôùng giaûi quyeát vaán ñeà.

1.2.1. Giao tieáp giöõa PC & KIT Z80.

Ñeå coù theå thöïc hieän vieäc giao tieáp giöõa maùy tính vaø moät KIT Z80 coù theå duøng moät trong hai
phöông phaùp sau:

5
Phöông phaùp thöù nhaát: Thöïc hieän vieäc baét tay giöõa maùy tính vaø KIT Z80 khi thao taùc truyeàn
döõ lieäu. Muoán thöïc hieän ñöôïc ñieàu naøy thì maùy tính vaø KIT Z80 seõ ôû trong traïng thaùi saün saøng
hoaït ñoäng tröôùc khi thöïc hieän thao taùc baét tay ñeå truyeàn döõ lieäu. Nhö vaäy treân KIT Z80 seõ coù moät
chöông trình ñeå coù theå thöïc hieän thao taùc naøy, vieäc gheùp noái bus cuøng vôùi vieäc phaùt caùc tín hieäu
baét tay giöõa maùy tính vaø KIT Z80 seõ do chöông trình beân trong KIT Z80 vaø chöông trình beân
trong maùy tính ñaûm nhieäm. Phöông phaùp naøy coù öu ñieåm laø vieäc thu vaø nhaän data seõ dieãn ra ñoàng
boä, nhanh choùng vaø chính xaùc nhöng laïi hôi phöùc taïp trong vieäc thöïc hieän caùc thao taùc baét tay.

Phöông phaùp thöù hai: Moïi thao taùc truyeàn döõ lieäu seõ do maùy tính chuû ñoäng, döõ lieäu truyeàn seõ
ñöôïc chöùa trong RAM (ñöôïc goïi laø RAM chung). RAM naøy giaû laäp ROM ñeå chaïy chöông trình töø
maùy tính.

Ñeå ñôn giaûn cho vieäc thieát keá (caû phaàn cöùng vaø phaàn meàm) vaø phuø hôïp vôùi noäi dung cuûa yeâu
caàu ñaët ra, ngöôøi thieát keá löïa choïn phöông phaùp thöù hai ñeå thöïc hieän yeâu caàu cuûa baøi toaùn ñaët ra.

1.2.2. Döøng vaø cho chaïy Z80 CPU.

Söû duïng caùc möùc logic thích hôïp ñöa vaøo chaân WAIT ñeå taïm thôøi döøng hoaït ñoäng cuûa Z80
CPU, ñaët Z80 CPU vaøo traïng thaùi chôø hoaëc cho Z80 CPU hoaït ñoäng ôû cheá ñoä bình thöôøng.
Khi chaân WAIT ôû möùc logic '1', Z80 CPU hoaït ñoäng bình thö ôøng.
Khi möùc logic taïi chaân WAIT laø '0', Z80 CPU seõ ñöôïc ñaët vaøo traïng thaùi chôø. ÔÛ traïng thaùi naøy
döõ lieäu treân ñöôøng ñòa chæ vaø data ñöôïc giöõ oån ñònh, ñoàng thôøi CPU lieân tuïc ñoïc vaøo möùc logic
treân chaân WAIT cho ñeán khi chaân naøy ñaït trôû laïi möùc logic '1'. Sau khi thoaùt khoûi traïng thaùi
WAIT Z80 CPU seõ daønh 2 chu kyø xung clock ñeå laøm töôi boä nhôù Ram ñoäng, sau ñoù thi haønh böôùc
keá tieáp cuûa leänh hoaëc thi haønh leänh keá.
Nhö vaäy khi ñaët Z80 CPU vaøo traïng thaùi chôø ta coù theå ñoïc ñöôïc döõ lieäu treân data bus, address
bus hoaëc coù theå can thieäp vaøo hoaït ñoäng cuûa CPU baèng caùch ñaët moät giaù trò khaùc leân data bus
trong thôøi gian CPU laáy maõ leänh hoaëc truy xuaát boä nhôù chöông trình (luùc naøy caàn thieát phaûi caám
CS boä nhôù chöông trình (ROM chöông trình)).

1.2.3. Höôùng môû roäng ñeà taøi.

Do coù yù ñoà môû roäng ñeà taøi theo höôùng duøng KIT ñeå söû duïng nhö laø 1 thieát bò moâ phoûng duøng
cho Z80 CPU neân trong phaàn thieát keá ñaõ coá gaéng traùnh can thieäp nhieàu vaøo Z80 CPU. Ñeå Z80
CPU coù theå chaïy ñöôïc ôû cheá ñoä Debug chæ caàn laáy tín hieäu CSROM vaø M1 ñeå ñieàu khieån quaù
trình. Nhö vaäy, coù theå duøng KIT ñeå laøm 1 boä moâ phoûng ( simulator) cho caùc thieát keá khaùc coù söû
duïng Z80 CPU. Sô ñoà khoái nhö sau :

6
Jack 25 KIT Z80 baát kyø
pin
PC

Adrres bus Rom Caùc


Simulator chöông Z80 linh
trình CPU kieän
khaùc
Data bus

Ctrl bus

Addr bus : ñöôïc laáy tröïc tieáp töø adress bus cuûa KIT
Data bus : ñöôïc laáy tröïc tieáp töø data bus cuûa KIT
Ctrl bus goàm :
Wait : noái vaøo chaân soá h cuûa 74LS74 (U8A)
Reset : noái vaøo chaân soá l cuûa 74LS04 (U2E)
Chuù yù : Trong cheá ñoä Debug caàn phaûi coù bieän phaùp can thieäp vaøo chaân interrupt cuûa KIT Z80 baát
kyø, khi KIT naøy chaïy ôû cheá ñoä coù duøng ngaét.
Tín hieäu INT
16
T.h cho pheùp/caám Z80 CPU

Caám=’0’ : Khi chaïy ôû cheá ñoä Debug(caám ngaét).

WX WX

7
Chöông II. Thieát keá phaàn cöùng

2.1. Phaân tích caùc chöùc naêng cuûa coång gheùp noái vôùi maùy in.
Söï saép xeáp caùc chaân ra ôû coång maùy in vôùi taát caû caùc ñöôøng daãn ñöôïc moâ taû treân hình 2.1.

Chaân Kyù hieäu Vaøo/Ra Moâ taû


1 STB Output Bit 0 cuûa thanh ghi ñieàu khieån
2 D0 Output Ñöôøng döõ lieäu D0
3 D1 Output Ñöôøng döõ lieäu D1
4 D2 Output Ñöôøng döõ lieäu D2
5 D3 Output Ñöôøng döõ lieäu D3
6 D4 Output Ñöôøng döõ lieäu D4
7 D5 Output Ñöôøng döõ lieäu D5
8 D6 Output Ñöôøng döõ lieäu D6
9 D7 Output Ñöôøng döõ lieäu D7
10 ACK Input Bit 6 cuûa thanh ghi traïng thaùi
11 BUSY Input Bit 7 cuûa thanh ghi traïng thaùi
12 PE Input Bit 5 cuûa thanh ghi traïng thaùi
13 SLCT Input Bit 4 cuûa thang ghi traïng thaùi
14 AF Output Bit 1 cuûa thanh ghi ñieàu khieån
15 ERROR Input Bit 3 cuûa thanh ghi traïng thaùi
16 INIT Output Bit 2 cuûa thanh ghi ñieàu khieån
17 SLCTIN Output Bit 3 cuûa thanh ghi ñieàu khieån
18 GND
19 GND
20 GND
21 GND
22 GND
23 GND
24 GND
25 GND

Hình 2.1. Boá trí chaân ôû coång maùy in ôû maùy tính PC.
Ta thaáy beân caïnh 8 bit döõ lieäu coøn coù nhöõng ñöôøng daãn tín hieäu khaùc, toång coäng ngöôøi söû duïng
coù theå trao ñoåi moät caùch rieâng bieät vôùi 17 ñöôøng daãn, bao goàm 12 ñöôøng daãn ra vaø 5 ñöôøng daãn
vaøo. Bôûi vì 8 ñöôøng daãn döõ lieäu D0 - D7 khoâng phaûi laø ñöôøng daãn 2 chieàu trong taát caû caùc loaïi
maùy tính, neân ta seõ söû duïng D0 - D7 nhö laø loái ra. Caùc loái ra khaùc nöõa laø STB, AF, INIT vaø
SLCTIN.
Caùc ñöôøng daãn loái vaøo laø: ERROR, SLCT, PE, ACK, BUSY.
8
Taát caû caùc ñöôøng daãn tín hieäu vöøa ñöôïc giôùi thieäu cho pheùp trao ñoåi qua caùc ñòa chæ boä nhôù
cuûa maùy tính PC. 17 ñöôøng daãn cuûa coång maùy in saép xeáp thaønh 3 thanh ghi: thanh ghi data, thanh
ghi traïng thaùi, thanh ghi ñieàu khieån. Hình 2.2 chæ ra söï saép xeáp cuûa caùc ñöôøng daãn tín hieäu tôùi caùc
bit döõ lieäu rieâng bieät cuûa thanh ghi.

Thanh ghi data (Ñòa chæ cô baûn)


D7 D6 D5 D4 D3 D2 D1 D0
D0 (pin 2)
D1 (pin 3)
D2 (pin 4)
D3 (pin 5)
D4 (pin 6)
D5 (pin 7)
D6 (pin 8)
D7 (pin 9)

Thanh ghi traïng thaùi (Ñòa chæ cô baûn + 1)


D7 D6 D5 D4 D3 0 0 0
ERROR (pin 15)
SLCT (pin 13)
PE (pin 12)
ACK (pin 10)
BUSY (pin 11)

Thanh ghi ñieàu khieån (Ñòa chæ cô baûn + 2)


D7 D6 D5 D4 D3 D2 D1 D0

STB (pin 1)
AF (pin 14)
INIT (pin 16)
SLCTIN (pin 17)
IRQ-Enable
Hình 2.2. Thanh ghi ôû coång maùy in cuûa maùy tính PC.
Ñòa chæ ñaàu tieân ñaït ñeán ñöôïc cuûa coång maùy in ñöôïc xem nhö laø ñòa chæ cô baûn. ÔÛ caùc maùy
tính PC ñòa chæ cô baûn cuûa coång maùy in ñöôïc saép xeáp nhö sau:
LPT1 (Coång maùy in thöù nhaát) => Ñòa chæ cô baûn = 378H
Hoaëc laø 3BCH ôû maùy Laptop
LPT2 (Coång maùy in thöù hai) => Ñòa chæ cô baûn = 278H

Ñòa chæ cô baûn ñoàng nhaát vôùi thanh ghi döõ lieäu. Thanh ghi traïng thaùi coù ñòa chæ = ñòa chæ cô baûn
+ 1. Caàn chuù yù raèng möùc logic cuûa BUSY (chaân 11) ñöôïc saép xeáp ngöôïc vôùi bit D7 cuûa thanh ghi
traïng thaùi. Thanh ghi ñieàu khieån vôùi 4 ñöôøng daãn loái ra cuûa noù coù ñòa chæ = ñòa chæ cô baûn + 2. ÔÛ
ñaây laïi caàn chuù yù tôùi söï ñaûo ngöôïc cuûa caùc tín hieäu: STB, AF, SLCTIN.

9
2.2. Kieán truùc Z80 CPU.

2.2.1. Sô ñoà khoái Z80 CPU. Bus döõ kieän 8 bits

Kieåm soaùt döõ kieän

Bus noäi
Giaûi maõ Thanh ALU
Tín hieäu & ghi
ñieàu khieån ñieàu leänh Kieåm soaùt CPU
heä thoáng khieån
& CPU CPU
Thanh ghi

Kieåm soaùt ñòa chæ

Bus ñòa chæ 16 bits

Hình 1-1: Sô ñoà khoái Z80 CPU.

Sô ñoà khoái cuûa kieán truùc beân trong Z80 CPU ñöôïc cho trong hình 1-1. Sô ñoà naøy trình baøy taát caû
caùc phaàn töû chính trong CPU vaø noù seõ ñöôïc xem xeùt kyõ qua caùc phaàn moâ taû sau.

2.2.2. Caùc thanh ghi cuûa CPU.

Z80 CPU chöùa moät boä nhôù R/W 208 bit. Boä nhôù naøy coù theå ñöôïc truy xuaát bôûi ngöôøi laäp trình.
Hình 1-2 cho thaáy boä nhôù naøy ñöôïc caáu taïo bôûi 8 thanh ghi 8 bit vaø 4 thanh ghi 16 bit. Taát caû caùc
thanh ghi cuûa Z80 CPU ñeàu duøng RAM tónh. CaÙc thanh ghi bao goàm 2 taäp 6 thanh ghi ña duïng,
taäp caùc thanh ghi naøy coù theå ñöôïc söû duïng ñoäc laäp nhö laø caùc thanh ghi 8 bit hoaëc töøng caëp nhö
laø caùc thanh ghi 16 bit. Coù hai taäp ( chính vaø phuï) thanh ghi tích luõy, thanh ghi côø vaø saùu thanh
ghi ñaëc bieät.

Taäp caùc thanh ghi ñaëc bieät.

Program Counter (PC): giöõ ñòa chæ möôøi saùu bit cuûa leänh hieän taïi ñang ñöôïc laáy veà töø boä
nhôù. PC töï ñoäng taêng sau khi noäi dung cuûa noù ñöôïc ñaët leân bus ñòa chæ. Khi 1 leänh nhaûy xaûy ra, 1
giaù trò môùi ñöôïc töï ñoäng ñaët vaøo trong PC thay cho giaù trò seõ ñöôïc taêng cuûa noù.

Stack pointer (SP): giöõ ñòa chæ 16 bit cuûa ñænh ngaên xeáp hieän haønh trong boä nhôù RAM ngoaøi.
Boä nhôù ngaên xeáp beân ngoaøi ñöôïc toå chöùc nhö laø 1 file vaøo sau ra tröôùc (LIFO). Döõ lieäu coù theå
ñöôïc ñaåy vaøo ngaên xeáp töø caùc thanh ghi xaùc ñònh cuûa CPU hay ñöôïc laáy ra khoûi ngaên xeáp ñeå ñöa
vaøo caùc thanh ghi xaùc ñònh cuûa CPU qua vieäc thi haønh caùc leänh Push vaø Pop. Döõ lieäu ñöôïc laáy ra

10
töø ngaên xeáp luoân luoân laø döõ lieäu ñöôïc ñaåy vaøo ngaên xeáp sau cuøng. Ngaên xeáp cho pheùp ñôn giaûn
hoùa vieäc thi haønh caùc loaïi ngaét quaõng khoâng giôùi haïn caùc chöông trình con loàng nhau vaø ñôn
giaûn hoùa nhieàu kieåu thao taùc treân döõ lieäu.

Hai thanh ghi chæ muïc (IX vaø IY): Hai thanh ghi chæ muïc ñoäc laäp giöõ ñòa chæ cô baûn 16 bit
ñöôïc duøng trong cheá ñoä ñònh ñòa chæ chæ muïc. Trong cheá ñoä naøy, moät thanh ghi chæ muïc ñöôïc duøng
nhö laø moät vò trí cô baûn chæ ñeán moät vuøng trong boä nhôù nôi maø döõ lieäu baét ñaàu ñöôïc chöùa hay
ñöôïc khoâi phuïc. Byte ñöôïc theâm trong caâu leänh chæ muïc ñeå xaùc ñònh khoaûng caùch ñeán vò trí cô
baûn. Khoaûng caùch naøy ñöôïc xaùc ñònh baèng pheùp buø 2 moät soá nguyeân coù daáu. Cheá ñoä naøy laøm ñôn
giaûn ñi raát nhieàu cho chöông trình. Ñaëc bieät cho caùc baûng döõ lieäu ñöôïc söû duïng.

Thanh ghi ñòa chæ trang ngaét (I) Z80 CPU coù theå ñöôïc ñieàu khieån trong 1 cheá ñoä maø ôû ñoù
moät leänh goïi tröïc tieáp ñeán baát kyø vuøng naøo cuûa boä nhôù coù theå ñöôïc thöïc hieän baèng caùch ñaùp öùng
ngaét. Thanh ghi I ñöôïc duøng cho muïc ñích naøy ñeå chöùa 8 bit cao cuûa ñòa chæ tröïc tieáp trong khi
thieát bò ngaét cung caáp 8 bit ñòa chæ thaáp. Ñaëc ñieåm naøy cho pheùp chöông trình phuïc vuï ngaét ñònh
vò nhanh tôùi baát kyø vuøng nhôù naøo vôùi thôøi gian truy xuaát ñeán chöông trình laø nhoû nhaát.

Thanh ghi laøm töôi boä nhôù (R): Z80 CPU chöùa 1 boä ñeám laøm töôi boä nhôù ñeå cho pheùp boä nhôù
ñoäng ñöôïc duøng deã daøng nhö boä nhôù tónh. Baûy trong 8 bit cuûa thanh ghi naøy ñöôïc töï ñoäng taêng
sau moãi laàn laáy leänh. Bit thöù 8 coøn laïi ñöôïc laäp trình nhö laø keát quaû cuûa leänh LD R,A. Data trong
boä ñeám laøm töôi ñöôïc gôûi leân phaàn thaáp cuûa bus ñòa chæ keøm theo moät tín hieäu laøm töôi trong khi
CPU giaûi maõ vaø thöïc thi leänh vöøa ñöôïc laáy veà. Caùch thöùc laøm töôi naøy hoaøn toaøn deã hieåu ñoái vôùi
ngöôøi laäp trình vaø khoâng laøm chaäm hoaït ñoäng cuûa CPU. Ngöôøi laäp trình coù theå laáy thanh ghi R
cho muïc ñích kieåm tra, nhöng thanh ghi naøy thì thöôøng khoâng ñöôïc ngöôøi laäp trình duøng. Trong
thôøi gian laøm töôi, noäi dung cuûa thanh ghi I ñöôïc ñaët leân 8 bit cao cuûa bus ñòa chæ.

Thanh ghi tích luõy vaø thanh ghi côø: CPU bao goàm hai thanh ghi tích luõy ñoäc laäp vaø ñöôïc keát
hôïp vôùi caùc thanh ghi côø 8 bit. Thanh ghi tích luõy löu giöõ keát quaû cuûa pheùp toaùn logic vaø soá hoïc
trong khi thanh ghi côø cho bieát caùc ñieàu kieän xaùc ñònh khi thöïc hieän caùc pheùp toaùn 8 bit hay 16 bit
nhö laø cho bieát keát quaû cuûa 1 pheùp tính coù baèng 0 hay khoâng. Ngöôøi laäp trình löïa choïn thanh ghi
tích luõy vaø thanh ghi côø vôùi 1 leänh hoaùn chuyeån ñôn vì coù theå laøm vieäc vôùi moät trong hai caëp.

Caùc thanh ghi ña duïng: Coù 2 taäp ñoái xöùng caùc thanh ghi ña duïng. Moãi taäp chöùa 6 thanh ghi 8
bit hay nhö caëp thanh ghi 16 bit. Taäp thöù nhaát ñöôïc goïi laø BC, DE vaø HL trong khi taäp leänh töông
öùng ñöôïc goïi laø BC’, DE’ vaø HL’. Trong baát kyø thôøi ñieåm naøo ngöôøi laäp trình coù theå choïn 1 trong
caùc taäp thanh ghi ñeå laøm vieäc qua 1 leänh hoaùn chuyeån ñôn. Trong caùc heä thoáng yeâu caàu ñaùp öùng
ngaét nhanh, moät taäp cuûa taäp thanh ghi ña duïng vaø moät thanh ghi côø /tích luõy coù theå ñöôïc döï tröõ
ñeå giaûi quyeát chöông trình raát nhanh naøy. Chæ caàn moät leänh ñôn giaûn ñöôïc thöïc thi ñeå chaïy giöõa
caùc chöông trình. Ñieàu naøy thu giaûm thôøi gian phuïc vuï ngaét do vieäc loaïi boû yeâu caàu caát vaø khoâi
phuïc noäi dung thanh ghi ôû ngaên xeáp trong thôøi gian ngaét hay xöû lyù chöông trình con. Caùc thanh
ghi ña duïng naøy ñöôïc duøng cho nhieàu öùng duïng bôûi ngöôøi laäp trình.
Thanh ghi tích luõy Thanh ghi côø Thanh ghi tích luõy A’ Thanh ghi
A F côø F’
B C B’ C’
Thanh ghi
D E D’ E’
ña duïng
11
H L H’ L’

Taäp thanh ghi chính Taäp thanh ghi phuï

Interrup vertor I Memory refresh R


Thanh ghi chæ muïc IX Thanh ghi ña
Thanh ghi chæ muïc IY duïng
Con troû ngaên xeáp SP
Ñeám chöông trình PC

Hình 1-2: Caáu truùc caùc thanh ghi cuûa Z80 CPU

2.2.3. Ñôn vò logic soá hoïc (ALU):

Caùc leänh logic vaø soá hoïc 8 bit cuûa CPU ñöôïc thöïc hieän trong ALU. Giao tieáp giöõa ALU vôùi
caùc thanh ghi vaø data bus beân ngoaøi ñöôïc thöïc hieän treân data bus beân trong. Caùc chöùc naêng ALU
goàm:
 Coäng
 Tröø
 Logic AND
 Logic OR
 Logic XOR
 So saùnh
 Dòch traùi, dòch phaûi hay quay ( Soá hoïc vaø logic)
 Pheùp toaùn taêng
 Pheùp toaùn giaûm
 Set bit
 Reset bit
 Test bit

2.2.4. Ñieàu khieån CPU vaø thanh ghi leänh.

Moãi 1 leänh ñöôïc laáy veà töø boä nhôù, noù ñöôïc ñaët vaøo trong thanh ghi leänh vaø ñöôïc giaûi maõ. Caùc
phaàn ñieàu khieån thi haønh chöùc naêng naøy, phaùt vaø caáp caùc tín hieäu ñieàu khieån caàn thieát ñeå ñoïc
hoaëc ghi data töø (hoaëc ñeán) caùc thanh ghi, ñieàu khieån ALU vaø ñaùp öùng caùc yeâu caàu cuûa tín hieäu
ñieàu khieån beân ngoaøi.

2.2.5. Chöùc naêng caùc chaân cuûa Z80.

a. Giôùi thieäu.

Sô ñoà caùc chaân cuûa Z80 CPU ñöôïc moâ taû trong hình sau :
12
27
/M1 30 A0
31 A1
19
/MREQ 32 A2
20
/IORQ 33 A3
21
/RD 34 A4
22
/WR 35 A5
36
28 A6
/RFSH 37
A7
38 A8
18
/HALT 39 A9
40 A10
24
/WAIT 1 A11

/INT
16 Z80 CPU 2
3
A12
A13
17 4
/NMI A14
5
A15
/RESET 26

25 14
/BUSREQ D0
23 15
/BUSACK D1
12 D2
6 8 D3
/CLK
7 D4
11
+5 V 9
29 D5
GND 10
D6
13
D7

SÔ ÑOÀ CHAÂN Z80

13
b. Chöùc naêng caùc chaân:

• A15 ÷A0: Bus ñòa chæ (out put, active high, 3 traïng thaùi), A15 ÷A0 taïo thaønh bus ñòa chæ 16 bit.
Bus ñòa chæ cung caáp ñòa chæ cho boä nhôù ñeå trao ñoåi data (leân ñeán 64 Kbyte) vaø cho thieát bò
I/O.
• Busack: Bus acknowledge (output, active low) baùo cho thieát bò yeâu caàu bieát ñòa chæ bus, data
bus vaø caùc tín hieäu ñieàu khieån: /MREQ, /IORQ, /RD, /WR ñaõ ôû traïng thaùi trôû khaùng cao.
Maïch ngoaøi coù theå duøng nhöõng ñöôøng naøy ngay luùc naøy.
• /BUSREQ: Bus request (input, active low) bus request coù ñoä öu tieân cao hôn /NMI vaø noù luoân
ñöôïc nhaän dieän vaøo cuoái chu kyø maùy hieän taïi. /Busreq ñoøi hoûi address bus, data bus vaø caùc tín
hieäu ñieàu khieån: /MREQ, /IORQ, /RD, /WR phaûi ôû traïng thaùi trôû khaùng cao ñeå caùc thieát bò
khaùc coù theå ñieàu khieån caùc ñöôøng naøy. Bus request thöôøng ñöôïc noái vaøo coång OR vaø yeâu caàu
ñieän trôû keùo leân beân ngoaøi cho caùc öùng duïng kieåu naøy.
• D7 ÷ D0: Data bus (input / output, active high, 3 traïng thaùi) D7 ÷ D0 taïo thaønh data bus 8 bit
hai chieàu, söû duïng ñeå trao ñoåi data vôùi boä nhôù vaø I/O.
• /HALT: Halt (output, active low) baùo raèng CPU ñang thöïc thi 1 leänh Halt vaø seõ chôø 1 trong
hai tín hieäu: /NMI hoaëc /INT (vôùi mask cho pheùp) tröôùc khi söï ñieàu khieån ñöôïc khoâi phuïc.
Trong thôøi gian Halt, CPU thöïc thi caùc leänh NOP ñeå duy trì vieäc laøm töôi boä nhôù.
• /INT: Interrup request (input, active low) Interrup request ñöôïc thieát bò I/O phaùt ra. CPU chaáp
nhaän yeâu caàu ngaét taïi thôøi ñieåm cuoái cuûa leänh hieän taïi neáu ñöôïc phaàn meàm cho pheùp. /INT
thöôøng ñöôïc noái vaøo caùc coång OR vaø caàn moät trôû keùo leân cho caùc öùng duïng loaïi naøy.
• /IORQ: Input/ Output Request (output, active low, 3 traïng thaùi) baùo nöûa thaáp cuûa address bus
giöõ 1 ñòa chæ I/O hôïp leä cho hoaït ñoäng ñoïc hay ghi I/O. /IORQ cuõng ñöôïc phaùt ñoàng thôøi vôùi
/M1 trong 1 chu kyø coâng nhaän ngaét ñeå baùo raèng 1 vertor ñaùp öùng ngaét coù theå ñöôïc ñaët leân
data bus.
• /M1: Machine cycle one (output, active low) /M1 cuøng vôùi /MREQ baùo raèng chu kyø maùy hieän
taïi laø chu kyø laáy maõ leänh. /M1 cuøng vôùi /IORQ baùo cho bieát raèng ñang ôû chu kyø coâng nhaän
ngaét.
• /MREQ: Memory request (output, active low, 3 traïng thaùi) /MREQ baùo raèng address bus
ñang giöõ moät ñòa chæ hôïp leä cho vieäc ñoïc ghi boä nhôù.
• /NMI: Non Maskable Interrup (input, tích cöïc caïnh xuoáng) /NMI coù ñoä öu tieân cao hôn /INT.
/NMI luoân luoân ñöôïc chaáp nhaän taïi chu kyø cuoái cuûa leänh hieän haønh, ñoäc laäp vôùi traïng thaùi cuûa
Flip-Flop interrupt vaø töï ñoäng ñöa CPU ñeán vò trí 0066h.
• /RD: Read (output, active low, 3 traïng thaùi) baùo raèng CPU muoán ñoïc data töø boä nhôù hay thieát
bò I/O. Thieát bò I/O ñöôïc chæ ñònh hay boä nhôù seõ duøng tín hieäu naøy ñeå ñöa data leân data bus.
• /RESET: Reset (input, active low) /RESET khôûi ñoäng CPU nhö sau: reset IFF1 & IFF2 xoùa
PC vaø caùc thanh ghi I & R, ñaët traïng thaùi interrupt ñeán cheá ñoä 0. Trong thôøi gian reset, addr
bus vaø data bus seõ ôû traïng thaùi trôû khaùng cao vaø taát caû caùc ñöôøng ñieàu khieån output seõ ôû
traïng thaùi khoâng tích cöïc. Chuù yù raèng ñöôøng /RESET phaûi active ít nhaát laø 3 chu kyø xung
clock tröôùc khi hoaït ñoäng reset hoaøn taát.
• /RFSH: Refresh (output, active low) /RFSH cuøng vôùi /MREQ baùo raèng 7 bit thaáp cuûa ñöôøng
addr coù theå ñöôïc duøng laøm ñòa chæ laøm töôi cho boä nhôù RAM ñoäng.
• /WAIT: Wait (input, active low) /WAIT baùo cho CPU boä nhôù ñöôïc chæ ñònh hay thieát bò I/O
chöa saün saøng cho vieäc truyeàn data. CPU tieáp tuïc ôû traïng thaùi chôø. Vieäc keùo daøi traïng thaùi
/WAIT coù theå ngöng vieäc laøm töôi cho boä nhôù RAM ñoäng.
14
• /WR: Write (output, active low, 3 traïng thaùi) /WR baùo data bus ñang giöõ 1 giaù trò data hôïp leä
ñeå ñöa vaøo boä nhôù ñöôïc chæ ñònh hoaëc vuøng I/O.
• /CLK: Clock (input).

15
2.2.6. Caùc giaûn ñoà thôøi gian.

a. Giôùi thieäu.

Z80 CPU thi haønh leänh theo töøng böôùc caên baûn goàm:
 Ñoïc vaø ghi boä nhôù
 Ñoïc vaø ghi thieát bò I/O
 Ñaùp öùng ngaét
Taát caû leänh laø taäp hôïp caùc hoaït ñoäng cô baûn. Moãi hoaït ñoäng caên baûn coù theå chieám töø 3 ñeán 6
chu kyø clock ñeå hoaøn taát hoaëc chuùng coù theå ñöôïc keùo daøi ñeå ñoàng boä toác ñoä giöõa CPU vôùi thieát
bò beân ngoaøi. Chu kyø Clock caên baûn ñöôïc xem nhö laø chu kyø T vaø hoaït ñoäng caên baûn ñöôïc xem
nhö laø chu kyø M. Hình 3-1 minh hoïa moät chu kyø leänh cô baûn. Löu yù raèng leänh naøy goàm 3 chu kyø
maùy ( M1,M2 vaø M3). Chu kyø maùy ñaàu tieân cuûa baát kyø leänh naøo laø chu kyø laáy maõ leänh (daøi 4, 5
hay 6 chu kyø T tröø khi bò keùo daøi bôûi tín hieäu Wait). Chu kyø laáy leänh (M1) ñöôïc duøng ñeå laáy maõ
leänh seõ ñöôïc thi haønh. Chu kyø maùy sau chuyeån data giöõa CPU vaø boä nhôù hay thieát bi I/O vaø
chuùng coù theå coù töø 3 ñeán 5 chu kyø T (tröø khi bò keùo daøi bôûi traïng thaùi Wait ñeå ñoàng boä vôùi toác
ñoä thieát bò beân ngoaøi). Ñoaïn sau ñaây moâ taû vieäc ñònh thôøi (xaûy ra trong baát kyø chu kyø maùy naøo).
Trong khoaûng thôøi gian T2 vaø moãi TW sau ñoù, CPU laáy maãu ñöôøng Wait taïi söôøn xuoáng cuûa xung
clock. Neáu ñöôøng Wait ñöôïc tích cöïc taïi thôøi ñieåm naøy, moät traïng thaùi Wait khaùc seõ ñöôïc theâm
vaøo trong chu kyø sau. Duøng kyõ thuaät naøy thì vieäc ñoïc coù theå keùo daøi ñeå phuø hôïp vôùi thôøi gian
truy xuaát cuûa baát kyø kieåu thieát bò boä nhôù naøo.

Chu kyø T

/Clk
T1 T2 T3 T4 T1 T2 T3 T1 T2 T3

Chu kyø maùy M1 Ñoïc boä nhôù M2 Ghi boä nhôù M3

Chu kyø leänh


Hình 3 -1 : Giaûn ñoà thôøi gian cô baûn

b. Laáy leänh.

Hình 3-2 laø giaûn ñoà thôøi gian cuûa chu kyø M1 (laáy maõ leänh). PC ñöôïc ñaët treân bus ñòa chæ taïi
ñieåm baét ñaàu cuûa chu kyø M1. Nöûa chu kyø clock sau ñoù tín hieäu /MREQ ñöôïc tích cöïc. Taïi thôøi
ñieåm naøy ñòa chæ tôùi boä nhôù coù ñuû thôøi gian ñeå oån ñònh do ñoù caïnh xuoáng cuûa /MREQ coù theå ñöôïc
duøng nhö laø moät tín hieäu cho pheùp boä nhôù RAM ñoäng. Ñöôøng /RD seõ tích cöïc ñeå chæ ra raèng data
ñöôïc ñoïc töø boä nhôù seõ ñöôïc ñöa leân data bus. CPU laáy maãu data töø boä nhôù treân bus data taïi söôøn
leân xung Clock cuûa chu kyø T3 vaø CPU duøng caïnh leân naøy ñeå taét tín hieäu /RD vaø /MREQ. Nhö
vaäy, data ñaõ saün saøng ñöôïc CPU laáy maãu tröôùc khi tín hieäu /RD trôû thaønh khoâng tích cöïc. Taïi
T3, T4 cuûa chu kyø laáy leänh ñöôïc duøng ñeå laøm töôi boä nhôù RAM ñoäng. (CPU duøng thôøi gian naøy
ñeå giaûi maõ vaø thöïc thi caùc leänh khaùc ñaõ ñöôïc laáy veà, do ñoù seõ khoâng coù hoaït ñoäng naøo khaùc ñöôïc
16
thöïc hieän trong thôøi gian naøy). Trong suoát T3 vaø T4, baûy bit thaáp cuûa ñöôøng ñòa chæ chöùa ñòa chæ
laøm töôi boä nhôù RAM ñoäng. Chuù yù raèng tín hieäu /RD khoâng ñöôïc sinh ra trong suoát thôøi gian laøm
töôi ñeå traùnh data töø boä nhôù khaùc bò ñaåy leân data bus. Tín hieäu /MREQ seõ ñöôïc söû duïng trong
suoát thôøi gian laøm töôi.
Chu kyø M1

T1 T2 T3 T4 T1
/Clk

A15÷A0 PC Refresh address

/MREQ

/RD

/WAIT

/M1

D7÷D0
IN
/RFSH

Hình 3-2: Chu kyø laáy maõ leänh


c. Ñoïc vaø ghi boä nhôù.

Hình 3-3 minh hoïa giaûn ñoà thôøi gian cuûa chu kyø ñoïc, ghi boä nhôù. Chu kyø naøy thöôøng ñöôïc keùo
daøi trong 3 chu kyø xung clock tröø phi coù traïng thaùi ñôïi ñöôïc boä nhôù yeâu caàu qua tín hieäu /WAIT.
Tín hieäu /MREQ vaø tín hieäu /RD ñöôïc duøng gioáng nhö trong chu kyø laáy leänh. Trong tröôøng hôïp
ghi boä nhôù, /MREQ cuõng trôû thaønh tích cöïc khi bus ñòa chæ ñaõ ôû traïng thaùi oån ñònh do ñoù noù coù theå
ñöôïc duøng tröïc tieáp nhö laø tín hieäu choïn chip cho boä nhôù RAM ñoäng. Ñöôøng /WR tích cöïc khi döõ
lieäu treân data bus ñaõ ôû traïng thaùi oån ñònh do ñoù noù coù theå ñöôïc duøng tröïc tieáp nhö laø xung /WR
cho caùc boä nhôù baùn daãn.

17
Chu kyø ñoïc boä nhôù Chu kyø ghi boä nhôù

T1 T2 T3 T1 T2 T3
/Clk

A15÷A0 MEMORY ADDR MEMORY ADDR

/MREQ

/RD

/WR

D7÷D0
I DATA OUT

/WAIT

Hình 3-2: Chu kyø ñoïc ghi boä nhôù.

d. Chu kyø nhaäp/xuaát.

Hình 3-4 minh hoïa hoaït ñoäng ñoïc hay ghi I/O. Chuù yù raèng trong thôøi gian hoaït ñoäng I/O thì
moät traïng thaùi ñôïi ñöôïc töï ñoäng theâm vaøo. Lyù do laø trong quaù trình hoaït ñoäng I/O, thôøi gian töø khi
tín hieäu /IORQ trôû neân tích cöïc cho ñeán khi CPU laáy maãu ñöôøng /WAIT thì raát ngaén do ñoù neáu
khoâng theâm traïng thaùi naøy vaøo thì khoâng ñuû thôøi gian ñeå coång I/O giaûi maõ ñòa chæ cuûa noù. Ngoaøi
ra, neáu khoâng coù traïng thaùi ñôïi thì seõ khoù khaên trong vieäc thieát keá caùc linh kieän I/O loaïi MOS
ñeå coù theå hoaït ñoäng töông öùng vôùi toác ñoä CPU. Trong thôøi gian xaûy ra traïng thaùi ñôïi, tín hieäu
/WAIT luoân ñöôïc laáy maãu.
Trong quaù trình ñoïc I/O, ñöôøng /RD ñöôïc duøng ñeå cho pheùp coång ñöôïc choïn ñöa data leân data
bus gioáng nhö trong tröôøng hôïp ñoïc boä nhôù. Tröôøng hôïp ghi I/O, ñöôøng /WR ñöôïc duøng nhö laø
Clock tôùi coång I/O.

18
T1 T2 TW T3 T1
/Clk

A15÷A0 PORT ADDRESS

/IORQ

/RD

CHU KYØ
D7÷D0 ÑOÏC
IN

/WAIT

/WR

CHU KYØ
D7÷D0 GHI
OUT

Hình 3-4: Chu kyø xuaát / nhaäp.

e. Chu kyø Bus Req/Ack.

Hình 3-5 minh hoïa giaûn ñoà thôøi gian cuûa chu kyø bus request/ack. Tín hieäu /BUSREQ ñöôïc
CPU laáy maãu ôû caïnh leân cuûa chu kyø Clock cuoái trong moät chu kyø maùy. Neáu tín hieäu /BUSREQ
tích cöïc, CPU seõ ñaët ñòa chæ, döõ lieäu vaø caùc tín hieäu ñieàu khieån ôû traïng thaùi trôû khaùng cao taïi
caïnh leân cuûa xung Clock keá tieáp. Taïi thôøi ñieåm ñoù, thieát bò beân ngoaøi baát kyø coù theå kieåm soaùt
bus ñeå truyeàn döõ lieäu giöõa boä nhôù vaø thieát bò I/O ( ví duï DMA ). Thôøi gian toái ña cho CPU ñaùp
öùng bus request baèng ñoä daøi cuûa 1 chu kyø maùy vaø thieát bò ñieàu khieån ngoaøi coù theå duy trì söï ñieàu
khieån cuûa bus trong nhieàu chu kyø Clock theo yeâu caàu. Neáu duøng chu kyø DMA daøi vaø boä nhôù
ñoäng ñöôïc duøng, thieát bò ñieàu khieån ngoaøi phaûi thöïc hieän chöùc naêng laøm töôi. Tröôøng hôïp naøy chæ
xaûy ra khi moät khoái döõ lieäu raát lôùn ñöôïc truyeàn döôùi söï ñieàu khieån cuûa DMA. Cuõng phaûi ñeå yù
trong suoát chu kyø bus request, CPU khoâng theå bò ngaét bôûi tín hieäu /NMI hay /INT.

19
CHU KYØ M BAÁT KYØ TRAÏNG THAÙI COÙ
THEÅ CUÛA BUS
Traïng thaùi
T cuoái Tx Tx Tx T1

/Clk

/BUSRQ Maã
Maãuu
Maãu

/BUSACK

A15÷A0

D7÷D0

Floatin
/MERQ
/RD, /WR
/IORQ
/RFSH

Hình 3-5: CHU KYØ BUS REQ/ACK

f. Chu kyø interrupt req/ack

Hình 3-6 minh hoïa giaûn ñoà thôøi gian keát hôïp vôùi moät chu kyø ngaét quaõng. Tín hieäu ngaét /INT
ñöôïc CPU laáy maãu ôû caïnh leân cuûa clock cuoái taïi ñieåm keát thuùc cuûa leänh baát kyø. Tín hieäu seõ
khoâng ñöôïc chaáp nhaän neáu F-F ñieàu khieån ngaét khoâng ñöôïc phaàn meàm trong CPU khôûi taïo leân
möùc logic ‘1’ hay neáu tín hieäu /BUSREQ laø tích cöïc. Khi tín hieäu ñöôïc chaáp nhaän, chu kyø ñaëc
bieät M1 ñöôïc taïo ra. Trong suoát chu kyø ñaëc bieät M1, tín hieäu /IORQ trôû neân tích cöïc ( thay vì
/MREQ bình thöôøng ) ñeå chæ ra raèng thieát bòï yeâu caàu ngaét coù theå ñaët 1 vector 8 bit leân bus döõ
lieäu. Chuù yù raèng hai traïng thaùi ñôïi ñöôïc theâm vaøo chu kyø naøy moät caùch töï ñoäng.

20
CHU KYØ M CUOÁI LEÄNH M1

Traïng thaùi T2 Tw’ Tw’ T3


T1
T cuoái
/Clk

/IN
T

A15÷A0 PC REFRESH

/M1

/MREQ

/IORQ

D7÷D0
I

/WAIT

/RD

Hình 3-6: CHU KYØ NGAÉT REQ/ACK

g. Ñaùp öùng ngaét khoâng che ñöôïc

Hình 3-7 minh hoïa chu kyø request hay chu kyø ack cho ngaét khoâng che ñöôïc. Tín hieäu naøy ñöôïc
laáy maãu cuøng thôøi ñieåm vôùi ñöôøng /INT, nhöng ñöôøng naøy coù ñoä öu tieân cao hôn vaø noù khoâng theå
bò caám do phaàn meàm ñieàu khieån. Chöùc naêng thoâng thöôøng cuûa noù laø cung caáp ñaùp öùng töùc thì
cho caùc tín hieäu quan troïng nhö laø loãi nguoàn cung caáp. CPU ñaùp öùng 1 ngaét khoâng che ñöôïc
töông töï hoaït ñoäng ñoïc boä nhôù bình thöôøng. Söï khaùc bieät duy nhaát laø noäi dung cuûa data bus bò lôø
ñi trong khi boä vi xöû lyù töï ñoäng chöùa PC trong ngaên xeáp ngoaøi vaø nhaûy tôùi vò trí 0066H. Chöông
trình phuïc vuï ngaét khoâng che ñöôïc phaûi baét ñaàu taïi vò trí naøy neáu ngaét ñöôïc söû duïng.

21
CHU KYØ M CUOÁI LEÄNH M1

Traïng thaùi T2 T3 T4 T1
T1
T cuoái
/Clk

/NMI

A15÷A0 PC REFRESH

/M1

/MREQ

/RD

/RFSH

Hình 3-7 : Giaûn ñoà thôøi gian cuûa NMI.

h. Thoaùt khoûi traïng thaùi HALT.

Baát cöù khi naøo moät leänh halt ñöôïc thöïc thi, CPU seõ thöïc hieän 1 chuoãi leänh NOP cho ñeán khi
nhaän ñöôïc moät tín hieäu ngaét (caû hai loaïi ngaét che ñöôïc vaø khoâng che ñöôïc neáu F-F ñöôïc cho
pheùp ). Hai ñöôøng ngaét ñöôïc laáy maãu ôû caïnh leân cuûa chu kyø T4 nhö ñöôïc minh hoïa döôùi hình 3-8.
Neáu nhaän ñöôïc ngaét khoâng che hay ngaét che ñöôïc vaø interrupt F-F ñang ñöôïc set ôû möùc logic
‘1’, thì CPU seõ thoaùt khoûi traïng thaùi HALT ôû caïnh leân cuûa chu kyø clock keá tieáp. Chu kyø sau seõ laø
moät chu kyø ñaùp öùng ngaét töông öùng vôùi loaïi cuûa ngaét thu ñöôïc. Neáu caû hai ñöôïc thu taïi cuøng moät
thôøi ñieåm, thì ngaét khoâng che ñöôïc seõ ñöôïc ñaùp öùng vì noù coù ñoä öu tieân cao nhaát. Muïc ñích cuûa
vieäc thöïc thi leänh NOP trong khi CPU ôû traïng thaùi HALT laø ñeå giöõ cho vieäc laøm töôi boä nhôù
RAM ñoäng ñöôïc thöïc hieän. Moãi chu kyø trong traïng thaùi HALT laø chu kyø M1 bình thöôøng ( laáy
leänh ).Tín hieäu traû lôøi HALT tích cöïc trong thôøi gian naøy ñeå chæ ra raèng boä xöû lyù ñang ôû trong
traïng thaùi HALT.

22
M M1 M1
1
T1 T2 T3 T4 T1

/Clk

/HALT

/INT
HAY
/NMI

Leänh Halt ñöôïc nhaän taïi thôøi ñieåm naøy.

Hình 3-8: Thoaùt khoûi traïng thaùi HALT

i. POWER-DOWN ACKNOWLEDGE CYCLE.

Khi Clock caáp cho CMOS Z80 CPU bò döøng laïi ôû 1 trong 2 möùc cao hay thaáp, CMOS Z80
CPU döøng hoaït ñoäng cuûa noù vaø duy trì taát caû caùc thanh ghi vaø caùc tín hieäu ñieàu khieån. Nhö vaäy,
ICC2 (Standby supply current ) ñöôïc baûo ñaûm chæ khi Clock heä thoáng bò döøng taïi möùc thaáp trong
thôøi gian T4 cuûa chu kyø maùy sau khi thöïc thi leänh HALT. Giaûn ñoà thôøi gian cho chöùc naêng power-
down khi thi haønh leänh HALT ñöôïc chæ ra trong hình 3-9.

T1 T2 T3 T4 T1 T2 T3 T4
/Clk

/M1

/HALT

Hình 3-9: Power – Down Acknowledge

23
j. Chu kyø thoaùt khoûi traïng thaùi Power-Down (Power-Down Release Cycle)

Clock heä thoáng phaûi ñöôïc cung caáp cho CMOS Z80 CPU ñeå thoaùt khoûi traïng thaùi power-down.
Khi Clock heä thoáng ñöôïc cung caáp cho ngoõ vaøo, CMOS Z80 CPU seõ khôûi ñoäng laïi hoaït ñoäng töø
ñieåm maø taïi ñoù traïng thaùi power-down ñaõ ñöôïc thi haønh. Giaûn ñoà thôøi gian cho vieäc thoaùt khoûi
cheá ñoä power-down ñöôïc chæ ra trong hình 3-10, 3-11, 3-12. Khi leänh HALT ñöôïc thöïc thi ñeå ñi
vaøo traïng thaùi power-down, CMOS Z80 CPU seõ ñöôïc ñöa vaøo traïng thaùi HALT. Moät tín hieäu
ngaét ( /NMI hay /INT ) hay moät tín hieäu /RESET ñöôïc caáp cho CPU sau khi xung clock heä thoáng
ñöôïc ñöa vaøo ñeå thoaùt khoûi traïng thaùi power-down.

T1 T2 T3 T4 T1
/Clk

/NMI

/M1

/HALT

Hình 3-10: Power – Down Release Cycle No.1

T1 T2 T3 T4
/Clk

/RESET
/M1

/HALT

Hình 3-11: Power – Down Release Cycle No.2

T1 T2 T3 T4 T1 T2 Twa Twa
/Clk

/RESET
/M1

/HALT

Hình 3-12: Power – Down Release Cycle No.3


24
U
2.2.7.TAÄP LEÄNH Z80 CPU.

a. Giôùi thieäu.

Z80 CPU coù theå thöïc thi 158 leänh khaùc nhau bao goàm caû 78 leänh cuûa 8080A CPU. Caùc leänh coù
theå ñöôïc chia thaønh caùc nhoùm chính sau :
• Load vaø Exchange
• Block transfer vaø Search
• Arithmetic vaø Logical
• Rotate vaø shift
• Bit manipulation ( set, reset, test )
• Jump, call, vaø Return
• Input hay Out put
• Basic CPU control

b. Caùc kieåu leänh.

Leänh Load chuyeån data giöõa caùc thanh ghi CPU vôùi nhau vaø giöõa thanh ghi CPU vôùi boä nhôù
ngoaøi. Taát caû caùc leänh phaûi xaùc ñònh nguoàn vaø ñích. Ví duï nhö vieäc truyeàn data töø thanh ghi C
ñeán thanh ghi B. Nhoùm naøy bao goàm caû Load töùc thôøi tôùi thanh ghi CPU hoaëc boä nhôù ngoaøi baát
kyø. Caùc kieåu khaùc cuûa leänh Load cho pheùp truyeàn giöõa caùc thanh ghi CPU vaø boä nhôù. Leänh
exchange coù theå chuyeån noäi dung cuûa hai thanh ghi.
Moät taäp duy nhaát cuûa nhoùm leänh truyeàn khoái ñöôïc cung caáp beân trong Z80. Vôùi moät leänh ñôn
giaûn, moät khoái boä nhôù vôùi kích thöôùc baát kyø coù theå ñöôïc chuyeån ñeán vò trí khaùc trong boä nhôù. Caùc
leänh chuyeån khoái coù lôïi khi phaûi xöû lyù moät chuoãi döõ lieäu lôùn. Vôùi 1 leänh ñôn, khoái boä nhôù ngoaøi
vôùi chieàu daøi tuøy thích coù theå tìm ñöôïc 1 kyù töï 8 bit baát kyø. Khi kyù töï ñöôïc tìm thaáy hay gaëp cuoái
khoái , leänh seõ töï ñoäng chaám döùt. Caû hai leänh chuyeån vaø tìm khoái ñeàu coù theå bò ngaét trong luùc thöïc
thi do ñoù khoâng chieám giöõ CPU trong chuoãi thôøi gian daøi.
Leänh logic vaø soá hoïc taùc ñoäng leân data trong thanh ghi tích luõy, thanh ghi ña duïng vaø boä nhôù
ngoaøi. Keát quaû cuûa caùc pheùp toaùn ñöôïc ñaët trong thanh ghi tích luõy vaø côø ñaëc tröng ñöôïc set tuøy
theo keát quaû cuûa caùc pheùp toaùn. Moät ví duï veà pheùp toaùn soá hoïc laø coäng noäi dung thanh ghi tích
luõy vôùi noäi dung boä nhôù ngoaøi. Keát quaû cuûa pheùp coäng ñöôïc ñaët vaøo thanh ghi tích luõy. Nhoùm
naøy goàm pheùp coäng vaø tröø caùc thanh ghi 16 bit.
Nhoùm leänh rotate vaø shift cho pheùp quay phaûi(traùi) hay dòch phaûi(traùi) baát kyø thanh ghi hay boä
nhôù naøo coù hay khoâng coù côø carry.
Leänh thao taùc bit cho pheùp bit baát kyø trong thanh ghi tích luõy, thanh ghi ña duïng hay boä nhôù ngoaøi
ñöôïc set, reset hay test vôùi 1 leänh ñôn. Ví duï, MSB cuûa thanh ghi H coù theå reset. Nhoùm naøy ñaëc
bieät höõu duïng trong caùc öùng duïng ñieàu khieån.
Leänh jump, call, return ñöôïc duøng ñeå di chuyeån giöõa hai vò trí khaùc nhau. Kieåu khaùc cuûa leänh call
laø leänh restart. Leänh naøy chöùa ñòa chæ môùi nhö 1 phaàn cuûa maõ leänh 8 bit. Chöông trình nhaûy ñöôïc
thi haønh bôûi söï naïp tröïc tieáp thanh ghi HL, IX, IY leân PC, do ñoù cho pheùp ñòa chæ nhaûy laø haøm
phöùc hôïp cuûa leänh ñang ñöôïc thi haønh.
Nhoùm leänh Input/Output trong Z80 cho pheùp truyeàn trong 1 khoaûng roäng giöõa boä nhôù ngoaøi hay
thanh ghi ña duïng vôùi thieát bò I/O beân ngoaøi. Trong moãi tröôøng hôïp, ñòa chæ coång ñöôïc cung caáp
treân 8 bit thaáp cuûa bus ñòa chæ trong khi thöïc thi I/O. Söï thuaän lôïi khi duøng thanh ghi C nhö con troû
25
chæ tôùi thieát bò I/O laø cho pheùp caùc coång I/O khaùc nhau chia seû driver phaàn meàm chung. Ñieàu
khoâng theå khi ñòa chæ laø 1 phaàn cuûa maõ leänh neáu chöông trình ñöôïc chöùa trong ROM. Ñaëc ñieåm
khaùc cuûa leänh Input laø chuùng set thanh ghi côø töï ñoäng do ñoù khoâng yeâu caàu xaùc ñònh traïng thaùi
cuûa data nhaäp vaøo. Z80 CPU chöùa leänh ñôn coù theå chuyeån khoái döõ lieäu (leân ñeán 256 byte) moät
caùch töï ñoäng tôùi hay töø coång I/O baát kyø ñeán vò trí boä nhôù baát kyø. Söï keát hôïp vôùi taäp caùc caëp thanh
ghi ña duïng, leänh naøy cho toác ñoä truyeàn khoái I/O cao. Giaù trò cuûa taäp leänh I/O naøy ñöôïc chöùng
minh bôûi Z80 coù theå cung caáp caùc yeâu caàu ñònh daïng ñóa meàm ( coù nghóa laø CPU cung caáp
header, ñòa chæ, data, vaø cho pheùp maõ CRC ) treân ñóa maät ñoä cao döïa treân ngaét caên baûn.
Keát luaän, leänh ñieàu khieån CPU caên baûn cho pheùp caùc chöùc naêng vaø cheá ñoä khaùc nhau. Nhoùm
leänh naøy goàm setting hay resetting caùc F-F cho pheùp ngaét hay caøi ñaët cheá ñoä ñaùp öùng ngaét.

c. Caùc cheá ñoä ñònh ñòa chæ

Haàu heát caùc leänh Z80 hoaït ñoäng treân döõ lieäu trong thanh ghi CPU, boä nhôù ngoaøi, hay coång
I/O. Caùc cheá ñoä ñònh ñòa chæ chæ ra caùch maø ñòa chæ cuûa döõ lieäu ñöôïc taïo ra trong moãi leänh laø nhö
theá naøo. Phaàn döôùi cho moät toùm taét sô löôïc cho caùc loaïi ñònh ñòa chæ duøng trong Z80 :

Ñònh ñòa chæ töùc thôøi :

Trong caùch ñònh ñòa chæ naøy byte theo sau maõ leänh trong boä nhôù chöùa toaùn haïng thöïc.

Maõ leänh 1 hay 2 byte


Toaùn haïng
D7 D0

Ví duï: naïp thanh ghi tích luõy vôùi haèng soá, ôû ñaây haèng soá laø byte ngay sau maõ leänh.

Ñònh ñòa chæ töùc thôøi môû roäng :

Caùch ñònh ñòa chæ naøy laø söï môû roäng cuûa caùch ñònh ñòa chæ töùc thôøi trong ñoù hai byte theo sau
maõ leänh laø caùc toaùn haïng.

Maõ leänh 1 hay 2 byte


Toaùn haïng Vò trí thaáp
Toaùn haïng Vò trí cao
Ví duï: load caëp thanh ghi HL ( thanh ghi 16 bit ) vôùi 16 bit döõ lieäu ( 2 byte ).

Ñònh ñòa chæ trang khoâng :

Z80 coù leänh 1 byte ñaëc bieät Call ñeå nhaûy tôùi vò trí baát kyø trong 8 vò trí trong trang khoâng cuûa
boä nhôù. Leänh naøy ñaët PC tôùi ñòa chæ hieäu quaû trong trang khoâng. Söï tieän duïng cuûa leänh naøy laø chæ
caàn moät byte ñôn vaø 1 ñòa chæ 16 bit xaùc ñònh vò trí chöông trình con, do ñoù tieát kieäm ñöôïc boä
nhôù.

26
Maõ leänh 1 byte
B7 B0 Ñòa chæ coù giaù trò laø ( B5 B4 B3 000) 2

Ñònh ñòa chæ töông ñoái :

Ñònh ñòa chæ töông ñoái duøng moät byte döõ lieäu theo sau maõ leänh ñeå xaùc ñònh ñoä dôøi töø chöông
trình hieän taïi tôùi nôi maø chöông trình Jump coù theå xaûy ra. Ñoä dôøi ñöôïc thöïc hieän baèng caùch coäng
soá buø hai vaøo ñòa chæ cuûa maõ leänh:

Maõ leänh Jump relative (1 byte maõ leänh )


Toaùn haïng Coäng thay soá buø 2 8 bit tôùi ñòa chæ ( A+2)

Söï tieän lôïi cuûa ñònh ñòa chæ töông ñoái laø noù cho pheùp nhaûy tôùi vò trí gaàn ñoù maø chæ caàn hai byte
boä nhôù. Do ñoù, nhöõng leänh naøy coù theå giaûm thieåu nhu caàu boä nhôù. Ñoä dôøi coù theå töø +127 ñeán -
128 töø ñòa chæ A+2. Vì vaäy toång ñoä dôøi cuûa leänh nhaûy töông ñoái laø +129 ñeán -126.

Ñònh ñòa chæ môû roäng :

Ñònh ñòa chæ môû roäng cung caáp hai byte (16 bit) ñòa chæ trong caáu truùc leänh. Döõ lieäu coù theå laø
ñòa chæ ñích chöông trình coù theå nhaûy tôùi hoaëc noù coù theå laø ñòa chæ cuûa toaùn haïng.

Maõ leänh 1 hay 2 byte


Ñòa chæ thaáp ñeán toaùn haïng thaáp
Ñòa chæ cao ñeán toaùn haïng cao

Ñònh ñòa chæ môû roäng duøng nhaûy töø vò trí naøy tôùi vò trí khaùc trong boä nhôù hay naïp vaø chöùa döõ lieäu
trong vò trí boä nhôù baát kyø. Khi ñònh ñòa chæ môû roäng ñöôïc duøng ñeå xaùc ñònh ñòa chæ nguoàn hay ñích
cuûa toaùn haïng, kyù hieäu (nn) seõ ñöôïc duøng ñeå chæ ra noäi dung boä nhôù taïi nn, nn laø ñòa chæ 16 bit
ñöôïc chæ ra trong caáu truùc leänh. Ñieàu naøy coù nghóa laø hai byte boä nhôù nn ñöôïc duøng nhö laø con troû
chæ ñeán vò trí boä nhôù. Daáu ngoaëc coù nghóa laø giaù trò trong chuùng ñöôïc duøng nhö laø con troû chæ ñeán
vò trí boä nhôù. Ví duï (1200) chæ noäi dung cuûa boä nhôù taïi vò trí 1200.

Ñònh ñòa chæ chæ soá :

Trong loaïi ñònh ñòa chæ naøy, byte döõ lieäu theo sau maõ leänh chöùa ñoä dôøi ñöôïc coäng vôùi noäi dung
cuûa thanh ghi chæ soá (Maõ leänh xaùc ñònh thanh ghi chæ muïc ñöôïc duøng ) ñeå taïo ra con troû tôùi boä
nhôù.

Maõ leänh 2 byte maõ leänh


Maõ leänh 2 byte maõ leänh
Söï thay Ñòa chæ treân thanh ghi chæ muïc ñeå taïo pointer ñeán boä nhôù

Ví duï cuûa leänh chæ muïc laø load noäi dung cuûa vò trí boä nhôù ( thanh ghi chæ muïc + ñoä dôøi ) vaøo trong
thanh ghi tích luõy. Ñoä dôøi laø soá buø hai coù daáu. Ñònh ñòa chæ coù chæ soá ñôn giaûn hoùa chöông trình

27
duøng baûng döõ lieäu coù thanh ghi chæ muïc chæ ñeán ñaàu baûng. Hai thanh ghi chæ muïc ñöôïc cung caáp
vì lyù do thöôøng caàn hai hay nhieàu baûng. Hai thanh ghi chæ muïc trong Z80 laø IX vaø IY. Ñeå ñònh ñòa
chæ chæ muïc ta duøng ( IX + d ) hay ( IY + d ). ÔÛ ñaây d laø ñoä dôøi naèm sau maõ leänh. Daáu ngoaëc chæ
ra raèng giaù trò ñöôïc duøng nhö laø con choû chæ ñeán boä nhôù ngoaøi.

Ñònh ñòa chæ thanh ghi :

Nhieàu maõ leänh cuûa Z80 chæ roõ thanh ghi naøo ñöôïc duøng. Ví duï load döõ lieäu trong thanh ghi B sang
thanh ghi C.

Ñònh ñòa chæ ngaàm ñònh :

Ñònh ñòa chæ ngaàm ñònh laø aùm chæ ñeán caùc pheùp toaùn maø maõ leänh töï ñoäng ngaàm ñònh moät hay
nhieàu thanh ghi CPU nhö laø nôi chöùa caùc toaùn haïng. Ví duï nhö taäp caùc pheùp toaùn soá hoïc thanh ghi
tích luõy luoân ñöôïc ngaàm ñònh laø nôi chöùa keát quaû.

Ñònh ñòa chæ giaùn tieáp thanh ghi :

Loaïi ñònh ñòa chæ naøy caàn caëp thanh ghi 16 bit ( nhö laø HL ) ñeå chæ tôùi vò trí baát kyø trong boä
nhôù. Loaïi leänh naøy raát maïnh vaø noù ñöôïc duøng trong 1 khoaûng roäng caùc öùng duïng .
Maõ leänh 1 hay 2 byte

Ví duï load thanh ghi tích luõy vôùi döõ lieäu trong boä nhôù ñöôïc troû bôûi noäi dung thanh ghi HL Ñònh
ñòa chæ chæ muïc laø moät theå cuûa ñònh ñòa chæ thanh ghi giaùn tieáp, khaùc nhau ôû choã ñoä dôøi ñöôïc coäng
theâm trong ñònh ñòa chæ chæ muïc. Ñònh ñòa chæ thanh ghi giaùn tieáp cho pheùp truy xuaát boä nhôù töùc
thôøi ñôn giaûn nhöng höõu hieäu. Leänh tìm vaø truyeàn khoái trong Z80 laø loaïi môû roäng cuûa ñònh ñòa chæ
naøy, ôû ñoù thanh ghi ñöôïc taêng, giaûm vaø so saùnh moät caùch töï ñoäng, Kyù hieäu cho bieát vieäc ñònh ñòa
chæ thanh ghi giaùn tieáp laø daáu ngoaëc ñôn bao quanh teân thanh ghi (ñöôïc duøng nhö laø pointer). Ví
duï kyù hieäu (HL) chæ raèng noäi dung thanh ghi HL ñöôïc duøng nhö laø moät pointer chæ tôùi oâ nhôù.
Thoâng thöôøng ñònh ñòa chæ giaùn tieáp thanh ghi duøng ñeå xaùc ñònh caùc toaùn haïng 16 bit. Trong
tröôøng hôïp naøy, noäi dung thanh ghi chæ ñeán byte thaáp hôn cuûa toaùn haïng trong khi noäi dung thanh
ghi coäng 1 chæ ñeán byte cao cuûa toaùn haïng.

Ñònh ñòa chæ bit :

Z80 chöùa moät löôïng lôùn taäp caùc leänh lieân quan ñeán bit: set, reset vaø test. Nhöõng leänh naøy cho
pheùp baát kyø vò trí boä nhôù naøo hoaëc thanh ghi CPU söû duïng pheùp toaùn bit thoâng qua 1 trong 3 cheá
ñoä ñònh ñòa chæ tröôùc ñoù ( thanh ghi, thanh ghi giaùn tieáp vaø chæ muïc ). 3 bit trong maõ leänh chæ roõ
thanh ghi naøo ñöôïc duøng.

Söï keát hôïp caùc cheá ñoä ñònh ñòa chæ:

28
Nhieàu leänh daøi hôn moät toaùn haïng ( nhö laø leänh soá hoïc hay load ). Trong tröôøng hôïp naøy hai
kieåu ñònh ñòa chæ coù theå ñöôïc tieán haønh. Ví duï, load coù theå duøng ñònh ñòa chæ töùc thôøi ñeå xaùc ñònh
nguoàn vaø ñònh ñòa chæ thanh ghi giaùn tieáp hay ñònh ñòa chæ chæ muïc ñeå xaùc ñònh ñích.

d. Maõ hoùa leänh.

Phaàn naøy moâ taû leänh vaø baûng maõ leänh cho töøng leänh cuûa Z80. Trong ngoân ngöõ Assembly töø
leänh gôïi nhôù ñöôïc duøng cho töøng leänh. Taát caû caùc maõ leänh ñöôïc lieät keâ ôû daïng soá HEX. Nhöõng
maõ leänh 1 byte caàn hai soá Hex trong khi hai byte maõ leänh caàn 4 soá Hex.
Töø leänh gôïi nhôù cuûa Z80 bao goàm maõ leänh vaø 0, 1, hay 2 toaùn haïng. Leänh khoâng coù toaùn haïng
töùc laø toaùn haïng cuûa noù ñöôïc ngaàm ñònh. Leänh logic chæ goàm 1 toaùn haïng khoâng ñoåi ( ví duï leänh
OR ) ñöôïc ñaïi dieän bôûi 1 töø leänh gôïi nhôù. Leänh goàm 2 toaùn haïng khaùc nhau ñöôïc ñaïi dieän bôûi 2
töø leänh gôïi nhôù.

Load vaø Exchange :

Baûng 4-1 ñònh nghóa maõ leänh cho taát caû leänh load 8 bit trong Z80 CPU. Baûng naøy cuõng chæ ra
kieåu ñònh ñòa chæ cuûa moãi leänh. Nguoàn cuûa döõ lieäu coù theå tra ôû haøng treân cuøng trong khi ñích ñöôïc
tra ôû coät beân traùi. Ví duï, Load thanh ghi C töø thanh ghi B duøng maõ leänh 48H. Maõ leänh ñöôïc ñònh ôû
daïng soá Hex vaø CPU laáy maõ leänh töø boä nhôù ngoaøi trong thôøi gian M1, sau ñoù CPU töï ñoäng giaûi
maõ vaø truyeàn vaøo thanh ghi.
Töø leänh gôïi nhôù cho nhoùm naøy laø LD ( LD Ñích, nguoàn ).
Ví duï LD (HL), D laø naïp noäi dung thanh ghi D vaøo ñòa chæ maø thanh ghi HL chæ tôùi. Daáu ngoaëc
quanh HL coù nghóa laø noäi dung cuûa HL ñöôïc duøng ñeå chæ ñeán vò trí boä nhôù naøo ñoù. Taát caû caùc
leänh Load cuûa Z80 ñích luoân vieát tröôùc nguoàn. Moãi leänh ñeàu coù taøi lieäu giuùp ñôõ vaø chöông trình
vieát ôû daïng ngoân ngöõ assembly Z80 thì deã daøng ñeå baûo trì.
Chuù yù trong baûng moät vaøi maõ leänh Load duøng trong Z80 laø 2 byte. Ñaây laø phöông phaùp taän duïng
hieäu quaû boä nhôù khi leänh 8 bit, 16 bit, 24 bit, 32 bit ñöôïc thi haønh trong Z80. Do ñoù, nhöõng leänh
taän duïng boä nhôù nhö pheùp toaùn soá hoïc vaø logic chæ caàn 8 bit.

IMPLIED THANH GHI THANH GHI CHÆ MUÏC Ext Imme


GIAÙN TIEÁP Addr

I R A B C D E H L (HL) (BC) (DE) (IX+d) (IY+d) (nn)


A ED ED 7F 78 79 7A 7B 7C 7D 7E A 1A FD DD DD DD
57 5F 7E 7E 3A 3E
d d nn n
B 47 40 41 42 43 44 45 46 DD FD DD
46 46 06
d d n
C 4F 48 49 4A 4B 4C 4D 4E DD FD DD
4E 4E 0E
d d n
D 57 50 51 52 53 54 55 56 DD FD DD
56 56 16
d d n
E 5F 58 59 5A 5B 5C 5D 5E DD FD DD
5E 5E 1E

29
d d n
H 67 60 61 62 63 64 65 66 DD FD DD
66 66 26
d d n
L 6F 68 69 6A 6B 6C 6D 6E DD FD DD
6E 6E 36
d d n
(HL) 77 70 71 72 73 74 75 DD
7E
d
(BC) 02
(DE) 12
(IX+ DD DD DD DD DD DD DD DD
d) 77 70 71 72 73 74 75 36
d d d d d d d d
n
(IY+ FD FD FD FD FD FD FD
d) 77 70 71 72 73 74 75
d d d d d d d
(nn) 32
n
n
I ED
47
R ED
4F
Taát caû leänh Load duøng ñònh ñòa chæ chæ muïc ñeå xaùc ñònh nguoàn vaø ñích cuøng vôùi 3 byte boä nhôù
vôùi byte thöù 3 laø ñoä dôøi d. Ví duï:
LD E, ( IX +8 )

Ñòa chæ A DD Maõ leänh


A+1 5E Maõ leänh
A+2 08 Toaùn haïng thay theá

Leänh ñònh ñòa chæ môû roäng cuõng laø leänh 3 byte. Ví duï, leänh load vaøo thanh ghi A noäi dung cuûa
ñòa chæ 6F32H trong boä nhôù ñöôïc vieát : LD A, ( 6F32H) vaø :

Ñòa chæ A 3A Maõ leänh


A+1 32 Ñòa chæ thaáp
A+2 6F Ñòa chæ cao

Chuù yù raèng byte thaáp cuûa ñòa chæ luoân laø toaùn haïng ñaàu.
Leänh load töùc thôøi cho thanh ghi 8 bit ña duïng laø leänh 2 byte. Leänh Load giaù trò 36H vaøo thanh
ghi H : LD H,36H vaø

Ñòa chæ A 26 Maõ leänh


A+1 36 Toaùn haïng

30
Load ñòa chæ boä nhôù duøng ñònh ñòa chæ chæ muïc cho ñích vaø ñònh ñòa chæ töùc thôøi cho nguoàn caàn 4
byte. Ví duï LD ( IX-15), 21H caàn

Ñòa chæ A DD Maõ leänh


A+1 36 Maõ leänh
A+2 F1 Ñoä dôøi
A+3 21 Load toaùn haïng

Chuù yù raèng vôùi baát kyø caùch ñònh ñòa chæ chæ muïc thì ñoä dôøi luoân theo sau maõ leänh.
Baûng 4-2 lieät keâ leänh load 16 bit. Chuù yù raèng ñònh ñòa chæ môû roäng coù theå duøng cho taát caû caùc
caëp thanh ghi. Hoaït ñoäng giaùn tieáp thanh ghi cho con troû ngaên xeáp laø leänh PUSH vaø POP. Ñieàu
khaùc bieät trong leänh Load 16 bit laø con troû ngaên xeáp ñöôïc taêng giaûm töï ñoäng khi moãi byte ñöôïc
ñaåy vaøo hay laáy ra töø ngaên xeáp. Ví duï : PUSH AF laø leänh 1 byte vôùi maõ leänh F5H. Khi leänh naøy
ñöôïc thöïc thi thì seõ taïo ra :
Giaûm SP
LD (SP),A
Giaûm SP
LD (SP),F
Do ñoù ngaên xeáp ngoaøi xuaát hieän nhö sau :

(SP) F ←Ñænh ngaên xeáp


(SP+1) A
• •
• •

Leänh POP thì ngöôïc vôùi PUSH. Chuù yù raèng taát caû leänh PUSH vaø POP duøng pheùp toaùn 16 bit vaø
byte cao luoân ñöôïc ñaåy tröôùc vaø laáy sau :
PUSH BC laø ñaåy B vaø sau ñoù laø ñaåy C
PUSH DE laø ñaåy D vaø sau ñoù laø ñaåy E
PUSH HL laø ñaåy H vaø sau ñoù laø ñaåy L
POP HL laø laáy L vaø sau ñoù laø laáy H
Leänh duøng ñòa chæ töùc thôøi môû roäng caàn 2 byte döõ lieäu theo sau maõ leänh.
Ví duï :
LD DE, 0659H
seõ laø :
Ñòa chæ A E6 Maõ leänh
A+1 07 toaùn haïng
Trong kieåu ñònh ñòa chæ môû roäng töùc thôøi, byte thaáp luoân xuaát hieän tröôùc tieân ngay sau maõ leänh.
Hình 4-3 lieät keâ leänh Exchange trong Z80. Maõ leänh 08H cho pheùp ngöôøi laäp trình ñoåi giöõa 2
caëp thanh ghi tích luõy, côø trong khi D9H cho pheùp ngöôøi laäp trình ñoåi giöõa 6 thanh ghi ña duïng.
Nhöõng maõ leänh naøy chæ daøi 1 byte ñeå toái thieåu thôøi gian caàn thieát thi haønh leänh Exchange do ñoù
hai bank coù theå ñöôïc duøng ñeå thôøi gian ñaùp öùng ngaét laø nhanh nhaát.

31
Nguoàn
THANH GHI IMM EXT REG
EXT ADDR INDIR
AF BC DE HL SP IX IY nn (nn) (SP)
AF F1
R BC C1
E DE D1
G HL E1
SP
IX DD
E1
IY FD
E1
Ext (nn) ED ED 22 ED ED FD
addr 43 53 n 73 22 22
n n n n n n
n n n n n
Reg (SP) F5 C5 D5 E5 DD FD
Ind E5 E5

Leänh
PUSH Leänh POP
Baûng 4-2 : Nhoùm LD 16 bit, PUSH vaø POP

IMPLIED ADDRESSING
AF BC,DE,HL HL IX IY
AF 08
BC 09
IMPLIED DE
HL
DE EB
REG (SP) E8 DD FD
INDR E3 E3

Baûng 4-3 : Exchange EX vaø EXX

Leänh tìm vaø truyeàn khoái

Baûng 4-4 lieät keâ söï tieän lôïi cuûa leänh truyeàn khoái. Taát caû caùc leänh ñoù khôûi ñoäng vôùi 3 thanh ghi :
HL : chæ tôùi vò trí nguoàn
DE : chæ tôùi vò trí ñích
BC : ñeám byte
Sau khi ngöôøi laäp trình ñaõ khôûi ñoäng 3 thanh ghi, baát cöù leänh naøo trong 4 leänh ñeàu coù theå
ñöôïc duøng. Leänh LDI ( Load vaø taêng ) ñaåy 1 byte töø vò trí ñöôïc troû bôûi HL tôùi vò trí ñöôïc troû bôûi
DE. Caëp thanh ghi HL vaø DE ñöôïc töï ñoäng taêng vaø saün saøng chæ ñeán vò trí sau. Byte ñeám ( caëp
32
thanh ghi BC ) cuõng giaûm taïi thôøi ñieåm naøy. Leänh naøy thích hôïp khi phaûi truyeàn khoái data nhöng
khaùc kieåu xöû lyù cho moãi laàn truyeàn. Leänh LDIR ( Load, taêng vaø laëp ) laø leänh LDI môû roäng. Taùc
vuï taêng vaø Load töông töï ñöôïc laëp laïi cho ñeán khi byte ñeám giaûm xuoáng baèng 0. Do ñoù, leänh ñôn
naøy coù theå truyeàn khoái döõ lieäu töø vò trí naøy ñeán vò trí khaùc.
Chuù yù raèng khi duøng thanh ghi 16 bit, kích thöôùc cuûa khoái coù theå leân ñeán 64 Kb vaø coù theå ñöôïc
chuyeån töø vò trí naøy ñeán vò trí khaùc trong boä nhôù.
Leänh LDD vaø LDDR raát gioáng vôùi LDI vaø LDIR. Chæ coù 1 söï khaùc bieät laø caëp thanh ghi HL vaø
DE bò giaûm sau khi moãi laàn chuyeån do ñoù khoái truyeàn khôûi ñoäng töø ñòa chæ cao nhaát hôn laø ñòa
chæ thaáp nhaát cuûa khoái naøy.

Reg Indr
(HL)
Reg (ED) “LDI” Load (DE) →(HL)
Indr A0 Taêng HL vaø DE, giaûm BC
(DE) (ED) “LDIR” Load (DE) →(HL)
B0 Taêng HL vaø DE, giaûm BC laëp cho ñeán khi BC=0
(ED) “LDD” Load (DE) →(HL)
A8 Taêng HL vaø DE, giaûm BC
(ED) “LDDR” Load (DE) →(HL)
B8 Taêng HL vaø DE, giaûm BC laëp cho ñeán khi BC=0
Hình 4-4 : NHOÙM LEÄNH TRUYEÀN KHOÁI (BLOCK TRASFER GROUP)

Hình 4-5 chæ roõ maõ leänh cuûa 4 khoái leänh tìm kieám. Ñaàu tieân, CPI ( So saùnh vaø taêng ) so saùnh
döõ lieäu vôùi giaù trò maø thanh ghi HL chæ ñeán. Keát quaû cuûa vieäc so saùnh ñöôïc chöùa vaøo 1 trong caùc
bit côø vaø caëp thanh ghi HL taêng leân sau ñoù vaø byte ñeám ( caëp thanh ghi BC ) thì giaûm xuoáng.
Leänh CPIR chæ laø leänh CPI môû roäng trong ñoù söï so saùnh ñöôïc laëp cho ñeán khi 1 söï truøng nhau
ñöôïc tìm thaáy hay byte ñeám baèng 0. Do ñoù, leänh ñôn naøy coù theå tìm trong boä nhôù moät kyù töï 8 bit
baát kyø.
CPD ( so saùnh vaø giaûm ) vaø CPDR ( so saùnh, giaûm vaø laëp ) laø leänh gioáng nhau. Chæ coù 1 söï
khaùc bieät laø giaûm HL sau moãi laàn so saùnh do vaäy chuùng doø boä nhôù theo chieàu ngöôïc laïi. ( Tìm
kieám ñöôïc baét ñaàu taïi vò trí cao nhaát trong khoái boä nhôù ).

Vò trí tìm
Reg Indr
(HL)
(ED) “CPI”
A1 Taêng HL , giaûm BC
(ED) “CPR”
B1 Taêng HL giaûm BC laëp cho ñeán khi BC=0 hoaëc tìm thaáy.
(ED) “CPD” Load (DE) →(HL)
A9 Giaûm HL vaø BC
(ED) “CPDR” Giaûm HL vaø BC
B9 laëp cho ñeán khi BC=0 hoaëc tìm thaáy.
Hình 4-5 : NHOÙM LEÄNH TÌM KIEÁM (BLOCK SEARCH GROUP)

33
Nhoùm leänh Logic vaø soá hoïc.
Hình 4-6 lieät keâ taát caû caùc leänh soá hoïc 8 bit coù theå ñöôïc duøng vôùi thanh ghi tích luõy. Trong taát
caû caùc leänh, tröø INC vaø DEC, pheùp toaùn 8 bit ñöôïc thöïc thi giöõa döõ lieäu trong thanh ghi tích luõy
vaø döõ lieäu nguoàn. Keát quaû cuûa pheùp toaùn ñöôïc ñaët trong thanh ghi tích luõy tröø leänh CP khoâng aûnh
höôûng tôùi thanh ghi tích luõy. Caùc pheùp toaùn aûnh höôûng leân thanh ghi côø ñuôïc lieät keâ trong baûng.
Leänh INC vaø DEC chæ roõ thanh ghi hay vò trí boä nhôù nhö laø nguoàn vaø ñích. Khi thanh ghi chæ muïc
ñöôïc duøng nhö toaùn haïng nguoàn, ñoä dôøi phaûi ñöôïc theâm vaøo. Vôùi caùch ñònh ñòa chæ töùc thôøi moät
toaùn haïng cuï theå seõ ñöôïc theâm vaøo. Ví du:ï
AND 07H
seõ xuaát hieän nhö sau :

Ñòa chæ A E6 Maõ leänh


A+1 07 Toaùn haïng

Giaû söû thanh ghi tích luõy chöùa giaù trò F3H, keát quaû laø 03H seõ ñöôïc ñaët trong thanh ghi tích luõy:

Thanh ghi tích luõy tröôùc khi thöïc hieän pheùp toaùn 1111 0011 = F3H
Pheùp toaùn 0000 0111 = 07H
Keát quaû thanh ghi tích luõy 0000 0011 = 03H

Leänh ADD tieán haønh pheùp coäng nhò phaân giöõa döõ lieäu nguoàn vôùi döõ lieäu trong thanh ghi tích luõy.
Leänh tröø laøm pheùp tröø nhò phaân. Khi coäng coù nhôù ( ADC ) hay tröø coù nhôù ( SBC ) côø Carry cuõng
seõ ñöôïc coäng hay tröø. Côø vaø leänh hieäu chænh thaäp phaân (DAA) trong Z80 cho caùc pheùp toaùn soá
hoïc ñöôïc cho nhö sau:
Ñoä chính xaùc cao cho soá BCD.
Ñoä chính xaùc cao cho soá nhò phaân coù daáu vaø khoâng daáu.
Ñoä chính xaùc cao cho soá buø hai coù daáu.
Caùc leänh khaùc trong nhoùm naøy laø leänh Logical AND, OR, XOR vaø CP
Coù 5 leänh soá hoïc ña duïng thi haønh treân thanh tích luõy hay côø Carry vaø ñöôïc lieät keâ trong hình 4-7.
Leänh hieäu chænh thaäp phaân coù theå hieäu chænh cho pheùp tröø vaø pheùp coäng, nhö trong caùc pheùp toaùn
soá hoïc treân soá BCD ñôn giaûn. Côø N ñöôïc duøng ñeán ñeå cho pheùp thöïc hieän pheùp toaùn naøy. Côø N
ñöôïc set khi pheùp toaùn soá hoïc cuoái laø pheùp tröø. Leänh NEG buø hai toaùn haïng trong thanh ghi tích
luõy. Cuoái cuøng chuù yù raèng moät leänh reset carry khoâng coù trong Z80, pheùp toaùn naøy thöïc hieän deã
daøng baèng caùc leänh khaùc nhö laø leänh logic AND cuûa thanh ghi tích luõy vôùi chính noù.
Hình 4-8 lieät keâ caùc pheùp toaùn soá hoïc 16 bit giöõa caùc thanh ghi 16 bit. Coù 5 nhoùm leänh bao
goàm coäng vaø tröø coù Carry. ADC vaø SBC aûnh höôûng ñeán taát caû caùc côø. Coù hai nhoùm: pheùp toaùn
tính ñòa chæ hay pheùp toaùn soá hoïc 16 bit.

THANH GHI ÑÒA CHÆ REG CHÆ MUÏC IMMED


INDR
A B C D E H L (HL) (IX+d) (IY+d) n
ADD 87 80 81 82 83 84 85 86 DD FD C8
86 86 n
34
d d
ADD 8F 88 89 8A 8B 8C 8D 8E DD FD CE
Carry 8E 8E n
ADC d d
SUB 97 90 91 92 93 94 95 96 DD FD D8
96 96 n
d d
SBC 9F 98 99 9A 9B 9C 9D 9E DD FD DE
9E 9E n
d d
AND A7 A0 A1 A2 A3 A4 A5 A6 DD FD E8
A6 A6 n
d d
XOR AF A8 A9 AA AB AC AD AE DD FD EE
AE AE n
d d
OR B7 B0 B1 B2 B3 B4 B5 B6 DD FD F8
B6 B6 n
d d
CP BF B8 B9 BA BB BC BD BE DD FD FE
BE BE n
d d
INC 3C 04 0C 14 1C 24 2C 34 DD FD
34 34
d d
DEC 30 05 00 15 10 25 20 36 DD FD
35 35
d d

Hình 4-6 : PHEÙP TÍNH LOGIC VAØ SOÁ HOÏC 8 BIT

DAA 27
CPL 2F
NEG ED
44
CCP 3F
SCP 37
Hình 4-7 : PHEÙP TÍNH AF ÑA DUÏNG

BC DE HL SP IX IY
HL 09 19 29 39

35
ADD IX DD DD DD DD
09 19 39 29
IY FD FD FD FD
09 19 39 29
ADC HL ED ED ED ED
4A 5A 6A 7A
SBC HL ED ED ED ED
42 52 62 72
INC 03 13 23 33 DD FD
23 23
DEC 0B 1B 2B 3B DD FD
2B 2B
Hình 4-8 : PHEÙP TÍNH SOÁ HOÏC 16 BIT

Nhoùm leänh quay vaø dòch.


Khaû naêng quan troïng cuûa Z80 laø khaû naêng quay vaø dòch döõ lieäu trong thanh ghi tích luõy, thanh
ghi ña duïng baát kyø, hay baát kyø vò trí boä nhôù naøo. Taát caû caùc maõ leänh quay vaø dòch ñöôïc chæ ra
trong hình 4-9. Trong Z80 coù nhieàu leänh dòch logic vaø soá hoïc. Caùc thao taùc naøy raát coù lôïi trong
khoaûng öùng duïng roäng bao goàm nhaân vaø chia soá nguyeân. Hai leänh quay BCD laø RRD vaø RLD cho
pheùp 1 digit trong thanh ghi tích luõy quay vôùi 2 digits trong boä nhôù ñöôïc chæ bôûi caëp thanh ghi HL.
Nhöõng leänh naøy raát coù hieäu quaû vôùi soá BCD.

A B C D E H L (HL) (IX+D) (IY+d)


‘RCL’ CB CB CB CB CB CB CB CB DD FD
07 00 01 02 03 04 05 06 CB CB
d d
06 06
‘RRC’ CB CB CB CB CB CB CB CB DD FD
0F 08 09 0A 0B 0C 0D 0E CB CB
d d
0E 0E
‘RL’ CB CB CB CB CB CB CB CB DD FD
17 10 11 12 13 14 15 16 CB CB
d d
16 16
‘RR’ CB CB CB CB CB CB CB CB DD FD
1F 18 19 1A 1B 1C 1D 1E CB CB
d d
1E 1E
‘SLA’ CB CB CB CB CB CB CB CB DD FD
27 20 21 22 23 24 25 26 CB CB
d d
26 26
‘SRA’ CB CB CB CB CB CB CB CB DD FD
2F 28 29 2A 2B 2C 2D 2E CB CB
d d
2E 2E
‘SRL’ CB CB CB CB CB CB CB CB DD FD
3F 38 39 3A 3B 3C 3D 3E CB CB

36
d d
3E 3E
‘SRL’ ED
6F
‘SRL’ ED
67

A
RLCA 07
RRCA 0P CY b7 ← b0
RLA 17
RRA 1F Voøng quay traùi

CY b7 → b0
Voøng quay phaûi

CY b7 → b0 Quay phaûi

CY b7 → b0 Dòch phaûi soá hoïc

CY b7 → b0 Dòch phaûi Logic

37
CY b7 ← b0 Quay traùi

CY b7 ← b0 Dòch traùi soá hoïc

b3 – b0 b7 – b4 b3 – b0 (HL)

ACC Quay traùi soá hoïc

b3 – b0 b7 – b4 b3 – b0 (HL)

ACC Quay phaûi soá hoïc

Hình 4-9: DÒCH VAØ QUAY ( ROTATE AND SHIFT)

Thao taùc treân bit.

Khaû naêng set, reset, vaø test caùc bit rieâng bieät trong thanh ghi hay boä nhôù laø caàn thieát trong haàu
heát caùc chöông trình. Nhöõng bit naøy coù theå laø côø trong caùc chöông trình.
Z80 coù khaû naêng set, reset, vaø test baát kyø bit naøo trong thanh ghi tích luõy, trong caùc thanh ghi ña
duïng hay trong boä nhôù vôùi moät leänh ñôn. Hình 4-10 lieät keâ 240 leänh cho muïc ñích naøy. Ñònh ñòa
chæ thanh ghi coù theå chæ roõ caùc pheùp toaùn thöïc thi treân thanh ghi tích luõy hay thanh ghi ña duïng.
Ñònh ñòa chæ giaùn tieáp thanh ghi vaø ñònh ñòa chæ chæ muïc coù theå thöïc hieän caùc pheùp toaùn treân boä
nhôù ngoaøi. Pheùp toaùn test bit set côø Zero ( Z) neáu keát quaû test laø zero.

Jump, Call vaø Return.

Hình 4-11 lieät keâ taát caû leänh jump, call vaø return seõ ñöôïc Z80 CPU thi haønh. Leänh Jump laø
leänh reõ nhaùnh trong chöông trình, ñeán nôi maø PC seõ ñöôïc naïp vôùi giaù trò 16 bit ñöôïc chæ roõ bôûi 1
trong 3 cheá ñoä ñònh ñòa chæ ( Ñònh ñòa chæ töùc thôøi môû roäng, quan heä, giaùn tieáp thanh ghi ). Chuù yù
raèng nhoùm Jump coù moät vaøi ñieàu kieän khaùc nhau, nhöõng ñieàu kieän naøy phaûi ñöôïc xaùc ñònh tröôùc
khi leänh Jump thöïc thi. Neáu caùc ñieàu kieän naøy khoâng xaûy ra, chöông trình seõ tieáp tuïc thöïc hieän
caùc leänh tieáp theo. Caùc ñieàu kieän phuï thuoäc vaøo thanh ghi côø. Ñònh ñòa chæ môû roäng töùc thôøi ñöôïc
duøng ñeå nhaûy tôùi vò trí baát kyø trong boä nhôù. Leänh naøy caàn 3 byte ( 2 ñeå xaùc ñònh ñòa chæ 16 bit )
vôùi vò trí byte thaáp cuûa ñòa chæ naèm tröôùc, theo sau laø byte ñòa chæ cao.
Ví duï, leänh nhaûy khoâng ñieàu kieän tôùi ñòa chæ 3E32H:
38
Ñòa chæ A C3 Maõ leänh
A+1 32 ñòa chæ thaáp
A+2 3E ñòa chæ cao

Leänh nhaûy lieân heä chæ duøng 2 byte.Byte thöù 2 laø soá buø hai coù daáu chính laø ñoä dôøi tính töø PC
hieän taïi. Ñoä dôøi naøy coù giaù trò trong khoaûng töø +129 ñeán -126 vaø ñöôïc tính töø ñòa chæ cuûa maõ leänh.
Coù ba loaïi nhaûy giaùn tieáp thanh ghi, laø nhöõng leänh ñöôïc thi haønh baèng caùch naïp caëp thanh ghi
HL hay moät trong hai thanh ghi chæ muïc IX, IY moät caùch giaùn tieáp leân PC. Khaû naêng naøy cho
pheùp tính toaùn tröôùc vò trí maø chöông trình seõ nhaûy ñeán.
Leänh Call laø moät daïng ñaëc bieät cuûa leänh Jump, byte ñòa chæ theo sau leänh Call ñöôïc ñöa vaøo
ngaên xeáp tröôùc khi leänh nhaûy thöïc hieän. Leänh Return ngöôïc laïi vôùi leänh Call vì döõ lieäu taïi ñænh
ngaên xeáp laáy ra vaø ñaët tröïc tieáp vaøo PC ñeå taïo ñòa chæ nhaûy. Leänh Call vaø Return cho pheùp caùc
chöông trình con ñôn giaûn vaø ngaét ngang chöông trình baèng phaàn meàm. Trong hoï Z80 coù hai leänh
quay veà ñaëc bieät. Quay veà töø chöông trình con phuïc vuï ngaét (RETI) vaø quay veà töø chöông trình
con phuïc vuï ngaét khoâng che (RETN) ñöôïc CPU xöû lyù nhö laø moät leänh nhaûy khoâng ñieàu kieän vôùi
maõ leänh laø C9H. Söï khaùc bieät naèm ôû choãø RETI ñöôïc duøng ñeå keát thuùc chöông trình phuïc vuï ngaét
vaø taát caû caùc chip ngoaïi vi cuûa Z80 seõ chaáp nhaän vieäc thi haønh leänh naøy ñeå cho vieäc ñieàu khieån
caùc ngaét coù ñoä öu tieân loàng nhau ñöôïïc thöïc hieän chính xaùc. Leänh naøy ñi caëp vôùi thieát bò caùc thieát
bò ngoaïi vi cuûa Z80 ñeå thi haønh nhöõng leänh quay veà ñôn giaûn töø caùc ngaét. Chöông trình sau seõ
baùo cho thieát bò ngaét raèng chöông trình phuïc vuï ngaét ñaõ hoaøn taát :
Khoâng cho ngaét : Caám ngaét tröôùc khi thoaùt khoûi chöông trình con.
LD A, n : Baùo cho ngoaïi vi raèng chöông trình phuïc
OUT n,A vuï ñaõ hoaøn taát
Cho pheùp ngaét
Quay veà.
Baûy byte naøy coù theå ñöôïc thay theá bôûi moät byte leänh EI vaø hai byte cuûa leänh RETI trong Z80.
Ñaây laø ñieàu quan troïng khi thôøi gian phuïc vuï ngaét laø toái thieåu.

REGISTER ADDRESSING REG INDEXED


INDR
A B C D E H L (HL) (IX+d) (IY+d)
0 CB CB CB CB CB CB CB CB DD FD
47 40 41 42 43 44 45 46 CB CB
d d
46 46
1 CB CB CB CB CB CB CB CB DD FD
4F 48 49 4A 4B 4C 4D 4E CB CB
d d
4E 4E
TES 2 CB CB CB CB CB CB CB CB DD FD
T 57 50 51 52 53 54 55 56 CB CB
d d
56 56
BIT 3 CB CB CB CB CB CB CB CB DD FD

39
5F 58 59 5A 5B 5C 5D 5E CB CB
d d
5E 5E
4 CB CB CB CB CB CB CB CB DD FD
67 60 61 62 63 64 65 66 CB CB
d d
66 66
5 CB CB CB CB CB CB CB CB DD FD
6F 68 69 6A 6B 6C 6D 6E CB CB
d d
6E 6E
6 CB CB CB CB CB CB CB CB DD FD
77 70 71 72 73 74 75 76 CB CB
d d
76 76
7 CB CB CB CB CB CB CB CB DD FD
7F 78 79 7A 7B 7C 7D 7E CB CB
d d
7E 7E
0 CB CB CB CB CB CB CB CB DD FD
87 80 81 82 83 84 85 86 CB CB
d d
86 86
1 CB CB CB CB CB CB CB CB DD FD
8F 88 89 8A 8B 8C 8D 8E CB CB
d d
8E 8E
RES 2 CB CB CB CB CB CB CB CB DD FD
T 97 90 91 92 93 94 95 96 CB CB
d d
96 96
BIT 3 CB CB CB CB CB CB CB CB DD FD
9F 98 99 9A 9B 9C 9D 9E CB CB
d d
9E 9E
‘RES 4 CB CB CB CB CB CB CB CB DD FD
’ A7 A0 A1 A2 A3 A4 A5 A6 CB CB
d d
A6 A6
5 CB CB CB CB CB CB CB CB DD FD
AF A8 A9 AA AB AC AD AE CB CB
d d
AE AE
6 CB CB CB CB CB CB CB CB DD FD
B7 B0 B1 B2 B3 B4 B5 B6 CB CB
d d
B6 B6
7 CB CB CB CB CB CB CB CB DD FD
BF B8 B9 BA BB BC BD BE CB CB
40
d d
BE BE
0 CB CB CB CB CB CB CB CB DD FD
C7 C0 C1 C2 C3 C4 C5 C6 CB CB
d d
C6 C6
1 CB CB CB CB CB CB CB CB DD FD
CF C8 C9 CA CB CC CD CE CB CB
d d
CE CE
2 CB CB CB CB CB CB CB CB DD FD
D7 D0 D1 D2 D3 D4 D5 D6 CB CB
d d
D6 D6
SET 3 CB CB CB CB CB CB CB CB DD FD
DF D8 D9 DA DB DC DD DE CB CB
d d
DE DE
BIT 4 CB CB CB CB CB CB CB CB DD FD
E7 E0 E1 E2 E3 E4 E5 E6 CB CB
d d
E6 E6
‘ 5 CB CB CB CB CB CB CB CB DD FD
EF E8 E9 EA EB EC ED EE CB CB
d d
EE EE
6 CB CB CB CB CB CB CB CB DD FD
F7 F0 F1 F2 F3 F4 F5 F6 CB CB
d d
F6 F6
7 CB CB CB CB CB CB CB CB DD FD
FF F8 F9 FA FB FC FD FE CB CB
d d
FE FE

Hình 4-10 : NHOÙM LEÄNH THAO TAÙC BIT

41
Un- Carry Non Zero Non Parity Parit Sign Sign Neg
cond Carry Zero Even y Neg Pos S=0
Odd
Jump ‘JP’ Imme (nn) C3 DA D2 CA C2 EA E2 FA F2
d Ext n n n n n n N n n
n n n n n n N n n
Jump ‘JR’ Relati PC→e 18 38 30 28 20
ve e-2 e-2 e-2 e-2 e-2
Jump ‘JP’ Reg (HL) EB
Jump ‘JP’ Indr (IX) DD
E9
Jump ‘JP’ (IY) FD
E9
‘Call’ Imme nn CD 0C D4 CC C4 EC E4 FC F4
d Ext n n n n n n N n n
n n n n n n N n n
Giaûm B, Relat PC+e
nhaûy neáu ive
khoâng zero
‘DJNZ
Return ‘Ret’ Reg (SP) C9 D8 D0 C8 C0 E8 E0 F8 F0
Indr (SP+1)
Return töø Int Reg (SP) ED
‘RETI’ Indr (SP+1) 4D
Return töø Reg (SP) ED
ngaét khoâng Indr (SP+1) 45
che ‘Retn’
Hình 4-11 : NHOÙM LEÄNH RETURN, CALL VAØ JUMP

Leänh DJNZ e laøm ñôn giaûn chöông trình ñieàu khieån voøng laëp, leänh naøy coù 2 byte, giaûm thanh
ghi B vaø nhaûy neáu thanh ghi B chöa baèng ‘0’.
Hình 4-12 lieät keâ 8 maõ leänh cho leänh khôûi ñoäng laïi. Leänh naøy goàm 1 byte goïi ñeán 1 trong 8 ñòa
chæ baát kyø trong danh saùch. Baûng sau laø töø leänh gôïi nhôù cho caùc leänh goïi. Caùc leänh naøy ñöôïc duøng
thöôøng xuyeân ñeå toái thieåu hoùa nhu caàu boä nhôù.

MAÕ LEÄNH
0000H C7 ‘RST 0 ‘
ÑÒA CHÆ 0008H CF ‘RST 8 ‘
CALL 0010H D7 ‘RST 16 ‘
0018H DF ‘RST 24 ‘
0020H E7 ‘RST 32‘
0028H EF ‘RST 40 ‘
0030H F7 ‘RST 48 ‘
0038H FF ‘RST 56 ‘
Hình 4-12 : NHOÙM LEÄNH KHÔÛI ÑOÄNG LAÏI ( RESTART GROUP)

42
Input/Output.

Z80 coù taäp leänh môû roäng INPUT vaø OUTPUT ñöôïc chæ ra trong hình 4-13 vaø 4-14. Vieäc ñònh
ñòa chæ cuûa thieát bò INPUT vaø OUTPUT coù theå duøng moät trong 2 caùch: ñònh ñòa chæ tuyeät ñoái hay
giaùn tieáp thanh ghi, söû duïng thanh ghi C. Chuù yù raèng trong cheá ñoä ñònh ñòa chæ giaùn tieáp thanh ghi
döõ lieäu coù theå ñöôïc chuyeàn giöõa thieát bò I/O vôùi baát kyø thanh ghi naøo. Theâm vaøo ñoù, 8 leänh
truyeàn khoái ñöôïc duøng. Nhöõng leänh naøy gioáng nhö truyeàn khoái boä nhôù tröø khi duøng caëp thanh ghi
HL ñeå chæ tôùi khoái nguoàn ( leänh OUTPUT ) hay ñích ( leänh INPUT ) trong khi thanh ghi B ñöôïc
duøng nhö laø byte ñeám. Thanh ghi C giöõ ñòa chæ coång nôi maø leänh INPUT vaø OUTPUT caàn. Do ñoä
daøi cuûa thanh ghi B laø 8 bit, khoái ñöôïc truyeàn coù theå leân ñeán 256 byte.
Trong leänh IN A,n vaø OUT n,A , ñòa chæ cuûa thieát bò I/O naèm ôû nöûa thaáp cuûa bus ñòa chæ (
A7÷A0) trong khi noäi dung thanh ghi tích luõy ñöôïc truyeàn treân nöûa cao cuûa bus ñòa chæ. Trong taát
caû caùc leänh Input vaø Output vôùi caùch ñònh ñòa chæ giaùn tieáp thanh ghi, noäi dung thanh ghi C ñöôïc
ñöa leân byte thaáp cuûa bus ñòa chæ ( ñòa chæ thieát bò ) trong khi noäi dung thanh ghi B ñöôïc ñua leân
byte cao cuûa bus ñòa chæ.

IMMED REG
IND
(n) (c)
A D8 ED
N 78
B ED
40
REG C ED
48
INPUT “IN” ADDRESS D ED
50
Ñích E ED
nhaäp 58
H ED
60
L ED
68
“INT”-INPUT A REG ED
Inc HL, Dec B A2
“INIR”-INP Inc HL INDIR (HL) ED
Khoái
Dec B REPEAT If B≠0 B2
leänh
“IND”-INPUT & Inc ED
nhaäp
Dec HL, Dec B AA
“INDR”-INPUT Dec HL, Dec B ED
REPEAT If B≠0 BA
Hình 4-13: NHOÙM LEÄNH NHAÄP ( INPUT GROUP )

43
THANH GHI REG
IND
A B C D E H L (HL)
11 OUT IMME (n) D3
D n
REG (c) ED ED ED ED ED ED ED
IND 79 41 49 51 59 61 69
11 OUT – REG (c) ED
OUTPUT Inc IND A3
HL, Dec B
11 OUT – REG (c) ED
OUTPUT DecB, IND B3
REPEAT If B≠0
11 OUT – REG (c) ED
OUTPUT DecHL IND AB
&B
11 OUT – REG (c) ED
OUTPUT DecHL IND BB
&B REPEAT If
B≠0

Port ñòa chæ ñích Khoái


leänh
xuaát
Hình 4-14 : NHOÙM LEÄNH XUAÁT ( OUT PUT GROUP )

Nhoùm leänh ñieàu khieån CPU :

Hình 4-15 mieâu taû saùu leänh ñieàu khieån CPU. Leänh NOP laø leänh khoâng laøm gì caû. Leänh HALT
hoaõn hoaït ñoäng CPU cho ñeán khi thu ñöôïc moät ngaét, trong khi DI vaø EI ñöôïc duøng ñeå khoùa vaø
cho pheùp ngaét. Coù ba cheá ñoä ngaét :
Cheá ñoä 0 : thieát bò ngaét coù theå ñöa baát kyø leänh naøo leân bus döõ lieäu vaø cho pheùp CPU thi haønh
noù.
Cheá ñoä 1 : laø cheá ñoä ñôn giaûn, CPU töï ñoäng thi haønh moät leänh RST (khôûi ñoäng laïi) tôùi vò trí
0038H do ñoù phaàn cöùng ngoaøi laø khoâng caàn thieát ( Noäi dung cuõ cuûa PC ñöôïc ñaåy leân ngaên xeáp ).
Cheá ñoä 2 : raát höõu duïng, noù cho pheùp goïi giaùn tieáp tôùi vò trí boä nhôù baát kyø. Vôùi cheá ñoä naøy,
CPU thieát laäp ñòa chæ boä nhôù 16 bit coù 8 bit cao laø noäi dung cuûa thanh ghi I vaø 8 bit thaáp ñöôïc
cung caáp bôûi thieát bò ngaét. Ñòa chæ naøy chæ ñeán byte thöù nhaát trong chuoãi hai byte lieân tieáp trong
baûng ñòa chæ cuûa chöông trình phuïc vuï ngaét. CPU töï ñoäng laáy ñòa chæ baét ñaàu vaø thi haønh moät leänh
CALL tôùi ñòa chæ naøy.

44
Chæ ñeán baûng ngaét, thanh ghi I laø ñòa
chæ cao, ñaùp öùng ngoaïi vi laø ñòa chæ
Ñòa chæ phuïc vuï thaáp.
ngaét

NOP 00
HALT 76
DISABLE INT ‘(DI)’ F3
DISABLE INT ‘(EI)’ FB
SET INT MODE 0 ED 8080A MODE
‘IM0’ 46
SET INT MODE 1 ED CALL tôùi 0036H
‘IM1’ 56
SET INT MODE 2 ED CALL giaùn tieáp duøng thanh ghi I vaø 8bit
‘IM2’ 5E töø thieát bò nhö con troû

Hình 4-15: KIEÅM SOAÙT CPU.

2.2.8. Moâ taû taäp leänh Z80.

a. Giôùi thieäu: Ngoân ngöõ Assembly Z80.

Ngoân ngöõ assembly cung caáp ngöõ nghóa khi laäp trình, khoâng caàn ñeå yù ñeán caáu truùc leänh maùy.
Noù cho pheùp duøng ñòa chæ töôïng tröng ñeå phaân bieät vò trí boä nhôù vaø töø leänh gôïi nhôù ( maõ leänh vaø
toaùn haïng ) ñeå ñaïi dieän cho leänh. Nhaõn ñöôïc duøng trong chöông trình ñeå ñaùnh daáu ñieåm baét ñaàu
cuûa leänh. Toaùn haïng sau moãi leänh ñaïi dieän cho nôi chöùa, caùc thanh ghi hay caùc haèng. Ngoân ngöõ
assembly hoã trôï tröïc tieáp cho caùc leänh döôùi daïng maõ maùy. Chöông trình ñöôïc vieát baèng ngoân ngöõ
assembly thì ñöôïc goïi laø chöông trình nguoàn. Moãi caâu vieát treân moät haøng vaø coù theå chöùa töø 1 ñeán
4 muïc : Nhaõn, pheùp toaùn, toaùn haïng, chuù thích. Chöông trình nguoàn ñöôïc dòch ñeå thu ñöôïïc chöông
trình döôùi daïng ngoân ngöõ maùy (chöông trình ñoái töôïng), chöông trình ñoái töôïng coù theå ñöôïc thi
haønh tröïc tieáp bôûi Z80 CPU.

Caùc côø chæ thò traïng thaùi.

Thanh ghi côø ( F vaø F’) cung caáp thoâng tin cho ngöôøi duøng veà traïng thaùi Z80 ôû baát kyø thôøi ñieåm
naøo. Vò trí bit cho moãi côø ñöôïc chæ ra nhö sau :

S Z X N X P/V N C
45
Trong ñoù :
C : côø carry
N : Coäng hay tröø
P/V : côø Parity hay traøn
H : côø nuûa carry
Z : Côø zero
S : côø daáu
X : khoâng duøng.
Moät trong hai thanh ghi côø Z80 bao goàm 6 bit mang thoâng tin veà caùc traïng thaùi ñöôïc set hay
reset bôûi caùc pheùp toaùn. ( bit 3 vaø bit 5 khoâng ñöôïc duøng ) 4 bit coù theå kieåm tra ( C, P/V, Z vaø S )
duøng laøm ñieàu kieän cho caùc leänh Jump, Call hay Return. Hai côø khoâng kieåm tra ñöôïc laø ( H vaø N
) vaø ñöôïc duøng cho caùc pheùp toaùn soá hoïc BCD.

Côø carry ( C ) :

Bit côø Carry ñöôïc set hay reset phuï thuoäc vaøo pheùp toaùn ñöôïc thi haønh. Leänh ‘ADD’ vaø leänh
‘Subtract’ coù theå set côø Carry.
Trong caùc leänh RLA, RRA, RLS, vaø RRS bit carry ñöôïc duøng nhö laø moái lieân keát giöõa LSB vaø
MSB cho caùc thanh ghi hay boä nhôù baát kyø. Trong caùc leänh RLCA, RLC vaø SLA côø carry chöùa
giaù trò cuoái cuøng ñöôïc dòch ra töø bit 7 cuûa thanh ghi hay boä nhôù. Trong caùc leänh RRCA, RRC,
SRA, SRL carry chöùa giaù trò cuoái cuøng ñöôïc dòch ra töø bit 0 cuûa thanh ghi hay boä nhôù. Trong caùc
leänh logic AND, OR, XOR carry seõ bò reset.
Côø carry cuõng coù theå ñöôïc set ( SFC ) vaø buø ( CCF ).

Côø coäng / tröø ( N ) :

Côø naøy ñöôïc duøng khi hieäu chænh thaäp phaân thanh ghi tích luõy ( DAA ) ñeå phaân bieät leänh ADD vaø
SUBTRACT. Khi duøng leänh ADD, N seõ ñöôïc ñaët ôû möùc logic 0. Khi duøng leänh SUBTRACT N seõ
ñöôïc ñaët ôû möùc logic 1.

Côø chaün leû / traøn ( P/V) :

Côø naøy ñöôïc set phuï thuoäc vaøo pheùp toaùn ñöôïc thi haønh.
Vôùi caùc pheùp toaùn soá hoïc, côø naøy baùo traøn khi keát quaû trong thanh ghi tích luõy lôùn hôn +127 hay
nhoû hôn -128. Ñieàu kieän traøn coù theå ñöôïc xaùc ñònh nhôø vaøo caùc bit daáu cuûa caùc toaùn haïng.
Theâm vaøo ñoù caùc pheùp toaùn khaùc daáu seõ khoâng gaây traøn. Khi coäng caùc toaùn haïng cuøng daáu vaø
keát quaû laø daáu khaùc, côø traøn ñöôïc set.
Ví duï :
+120 = 0111 1000 ADDEND
+105 = 0110 1001 AUGEND
+225 = 1110 0001 (-95) SUM
Hai soá coäng laïi vaø keát quaû vöôït quaù +127 vaø 2 toaùn haïng döông coù keát quaû laø soá aâm (-95), ñaây laø
keát quaû sai. Côø traøn ñöôïc set.
Ñoái vôùi pheùp tröøø, traøn coù theå xaûy ra khi caùc toaùn haïng khaùc daáu. Caùc toaùn haïng cuøng daáu seõ
khoâng bao giôø gaây traøn.
46
Ví duï :
+127 0111 1111 MINUEND
(-) -64 1100 0000 SUBTRAHEND
+191 1011 1111 DIFFERENCE

Côø baùn Carry ( H ) :

Côø baùn carry ( H ) seõ ñöôïc set hay reset phuï thuoäc vaøo carry vaø borrow giöõa bit 3 vaø 4 cuûa
pheùp toaùn soá hoïc 8 bit. Côø naøy ñöôïc duøng khi hieäu chænh thaäp phaân thanh ghi tích luõy ( DAA ) ñeå
laøm ñuùng keát quaû cuûa pheùp toaùn coäng hay tröø soá BCD. Côø H seõ laø set(1) hay reset (0) theo baûng
sau :

H Coäng Tröø
1 Carry töø bit 3 ñeán bit 4 Möôïn töø bit 4
0 Khoâng coù Carry töø bit 3 ñeán bit 4 Khoâng möôïn töø bit 4

Côø zero ( Z ) :

Côø zero ñöôïc set hay reset neáu keát quaû cuûa leänh laø 0.
Ñoái vôùi caùc pheùp toaùn logic vaø soá hoïc 8 bit, côø Z seõ ñöôïc set leân 1 neáu noäi dung thanh ghi tích luõy
laø 0.
Ñoái vôùi leänh so saùnh, côø Z seõ ñöôïc set leân 1 neáu noäi dung cuûa thanh ghi tích luõy vaø noäi dung cuûa
boä nhôù ñöôïc chæ bôûi caëp thanh ghi HL gioáng nhau.
Khi kieåm tra bit trong thanh ghi hay boä nhôù, côø Z seõ chöùa traïng thaùi buø cuûa bit ñöôïc chæ ñònh (
xem Bit b,s ).
Khi ñang nhaäp hay xuaát 1 byte giöõa boä nhôù vôùi thieát bò I/O ( INI, IND, OUTI, OUTD ) neáu keát
quaû cuûa B-1 laø 0 thì côø Z ñöôïc set. Ñoái vôùi byte ñöôïc nhaäp töø thieát bò I/O duøng IN r,(C) , côø Z seõ
ñöôïc set ñeå cho bieát byte nhaäp baèng zero.

Côø daáu ( S ) :

Côø daáu chöùa traïng thaùi cuûa bit coù troïng soá lôùn nhaát cuûa thanh ghi tích luõy ( Bit 7 ).Moät soá döông
ñöôïc phaân bieät bôûi ‘0’ ôû bit 7 vaø soá aâm laø ‘1’.
Khi nhaäp byte töø thieát bò I/O vaøo thanh ghi, IN r,(C) côø S seõ chæ hoaëc soá döông (S=0) hoaëc soá aâm
(S=1).

b. Moâ taû leänh Z80:

Chuù yù: Thôøi gian thöïc thi (E.T) cho moãi leänh ñöôïc tính baèng μs vôùi giaû thieát taàn soá xung clock laø
4 Mhz. Toång chu kyø maùy ñöôïc chæ ra cuøng vôùi toång chu kyø T.
Ví duï :
M Cycle : 2 T status : 7 (4,3) 4 Mhz E.T : 1.75

47
Cho bieát raèng leänh goàm 2 chu kyø maùy. Chu kyø ñaàu goàm 4 chu kyø xung clock(chu kyøT). Chu kyø
thöù hai goàm 3 chu kyø xung clock, toång coäng laø 7 chu kyø xung clock. Leänh naøy ñöôïc thi haønh trong
1.75 μs.
Daïng qui öôùc cuûa thanh ghi ñöôïc chæ ra trong moãi leänh vôùi bit coù troïng soá lôùn nhaát naèm beân traùi
vaø bit coù troïng soá nhoû nhaát naèm beân phaûi.
Chuù thích:
Phaàn chi tieát veà taäp leänh xin xem trong taøi lieäu Z80 CPU User’s Manual (chöông
Instruction Description).

2.3. Thieát keá chi tieát.

Döïa vaøo ñaëc ñieåm cuûa coång maùy in vaø caáu taïo cuûa Z80 CPU, ñeå ñaùp öùng yeâu caàu cuûa baøi
toaùn, coù theå chia quaù trình thieát keá laøm 2 giai ñoaïn:

Giai ñoaïn 1: Thieát keá 1 KIT Z80 chaïy ñoäc laäp vôùi caùc chöùc naêng cô baûn.
Thaønh phaàn cuûa KIT naøy nhö sau: Z80 CPU, ROM chöông trình, boä nhôù chính RAM, caùc maïch
giaûi maõ ñòa chæ, caùc maïch ñeäm tuyeán, caùc maïch giao tieáp ñeå ñieàu khieån moät soá coång xuaát nhaäp
ñôn giaûn.

Giai ñoaïn 2: Thay ROM chöông trình ñaõ ñöôïc thieát keá ôû böôùc treân baèng moät RAM coù chöùc
naêng töông töï. RAM naøy seõ chöùa chöông trình töø maùy tính gôûi ñeán thoâng qua moät maïch giao tieáp,
thaønh phaàn chuû yeáu cuûa maïch giao tieáp naøy laø moät vi maïch gheùp noái song song (8255), caùc maïch
phuï trôï khaùc seõ ñoùng vai troø tieáp nhaän vaø xöû lyù caùc tín hieäu ñieàu khieån ñöôïc gôûi tôùi töø maùy tính.

2.3.1 Thieát keá KIT Z80 chaïy ñoäc laäp.

Böôùc 1:
Choïn RAM coù dung löôïng 32 Kb (62256) laøm boä nhôù chính.
Choïn ROM coù dung löôïng 32 Kb (27256) laøm boä nhôù chöông trình.
Nhö vaäy caùc ñöôøng ñòa chæ cuûa boä nhôù chính seõ goàm A0 - A14. Caùc ñöôøng ñòa chæ naøy seõ ñöôïc
noái tröïc tieáp ñeán caùc ñöôøng ñòa chæ töông öùng cuûa Z80 CPU. Ñoàng thôøi caùc ñöôøng data töø D0 - D7
cuõng seõ ñöôïc noái tröïc tieáp ñeán caùc ñöôøng data töông öùng cuûa Z80 CPU.
Ñeå caùch ly Addr bus cuûa ROM chöông trình vôùi Addr bus cuûa Z80 CPU, duøng 2 IC ñeäm tuyeán
döõ lieäu 1 chieàu 74LS244. Lyù do caùch ly laø ñeå traùnh tröôøng hôïp va chaïm tuyeán ñòa chæ trong thôøi
gian truy xuaát ROM chöông trình töø maùy tính vaø trong thôøi gian Z80 truy xuaát chöông trình khi
hoaït ñoäng.

Böôùc 2: Thieát keá maïch giaûi maõ ñòa chæ.


Ñeå giaûi maõ ñòa chæ cho maïch öùng duïng ñoàng thôøi duøng cho vieäc môû roäng KIT sau naøy, maïch
ñöôïc thieát keá dö ra moät soá ñöôøng ñòa chæ.
Caùc IC giaûi maõ 74LS139 vaø 74LS138 ñöôïc duøng.
ROM chöông trình seõ coù ñòa chæ trong khoaûng töø 0000H - 7FFFH.
Boä nhôù RAM seõ coù ñòa chæ trong khoaûng töø 8000H - FFFFH.

48
Böôùc 3: Thieát keá maïch nhaän vaø phaùt caùc möùc logic ñeán caùc coång xuaát nhaäp ñôn giaûn.
Duøng 1 IC ñeäm tuyeán 2 chieàu 74LS245 (nhöng chæ söû duïng 1 chieàu) ñeå nhaän caùc möùc logic töø
caùc SW ñöôïc ñaët ôû ngoõ vaøo. CS cuûa IC naøy ñöôïc noái ñeán ñöôøng ñòa chæ 04H (CS1).
Ñeå xuaát caùc möùc logic töø CPU ra caùc thieát bò ngoaøi (ôû ñaây laø caùc LED chæ thò), duøng 1 IC caøi
74LS574. CS cuûa IC naøy ñöôïc noái ñeán ñöôøng ñòa chæ 00H (CS0).
Ñöôøng data bus cuûa 2 IC 74LS574 (U14) vaø 74LS245 (U15) ñöôïc noái vôùi data bus cuûa Z80
CPU thoâng qua IC ñeäm tuyeán 2 chieàu 74LS245 (U13).

2.3.2. Thieát keá phaàn giao tieáp vôùi maùy tính.

Thay ROM chöông trình baèng 1 RAM (RAM chung) töông öùng (62256), caùch ly Addr bus cuûa
RAM naøy vaø Addr bus cuûa Z80 baèng 2 IC ñeäm 1 chieàu 74LS244 cho muïc ñích ñieàu khieån sau
naøy.

Duøng vi maïch gheùp noái song song 8255 ñeå choát caùc ñöôøng ñòa chæ khi truy xuaát RAM chung töø
maùy tính (lyù do phaûi choát caùc ñöôøng ñòa chæ laø: ñöôøng data cuûa coång maùy in chæ coù 8 bit, trong khi
ñoù laïi coù ñeán 15 ñöôøng ñòa chæ (A0 - A14)).

Duøng IC ñeäm 1 chieàu 74LS244 ñeå caùch ly data bus cuûa maùy tính vaø KIT ñoàng thôøi cho muïc
ñích ñieàu khieån döõ lieäu.

Moät IC Multiplex (74LS157) ñöôïc söû duïng cho muïc ñích ñoïc döõ lieäu veà maùy tính, 74LS157 laø
moät Quad 2-input Multiplexer coù 4 bit ôû loái ra, 4 bit naøy ñöôïc noái ñeán caùc bit töông öùng cuûa thanh
ghi traïng thaùi ôû coång maùy in.
Do caùc tín hieäu ñieàu khieån ra töø coång maùy in quaù ít (4 ñöôøng), IC 74LS374 ñöôïc duøng ñeå choát
8 bit data, caùc ñöôøng ra töø 74LS374 ñöôïc duøng trong vieäc ñieàu khieån caùc IC 8255, 74LS157,
RAM chung, 74LS244 ñeäm tuyeán ñòa chæ.

2.4. Nguyeân lyù hoaït ñoäng.

2.4.1. Ñöa chöông trình ra RAM chung.

Giaû söû raèng ta ñaõ coù moät file nhò phaân (coù phaàn môû roäng laø.bin; file naøy laø moät chöông trình
cuûa Z80 CPU ñaõ ñöôïc dòch ra daïng maõ maùy), nhieäm vuï laø phaûi ñöa file naøy theo töøng byte moät
vaøo RAM chung cuûa KIT (töông ñöông vôùi Rom chöông trình cuûa KIT Z80). Ñeå laøm ñöôïc vieäc
naøy phaûi tuaân theo caùc böôùc sau:

Böôùc 1: Caám Z80.


Tích cöïc chaân RESET cuûa Z80. Luùc naøy ñöôøng data bus cuûa Z80 ôû traïng thaùi trôû khaùng cao.
Caùc IC 74LS244 (U4 & U5) bò caám neân caùc ngoõ ra cuûa IC naøy cuõng ôû traïng thaùi trôû khaùng cao.
Do ñoù keát quaû laø moät phaàn maïch bò coâ laäp.

Böôùc 2: Caám RAM chung.


RAM chung seõ ñöôïc caám nhaèm muïc ñích ñöa data bus veà traïng thaùi trôû khaùng cao.
49
Vieäc naøy ñöôïc thöïc hieän baèng caùch caøi 1 bit thaáp töông öùng qua IC 74LS374 ñeå ñöa CS cuûa
RAM chung xuoáng möùc logic '0'.

Böôùc 3: Khôûi ñoäng 8255.


Ñeå khôûi ñoäng 8255 tröôùc heát phaûi choïn caùc tín hieäu ñieàu khieån thích hôïp (CS, A0, A1), caùc tín
hieäu naøy ñöôïc gôûi ñeán theo data bus cuûa coång maùy in vaø ñöôïc choát baèng moät xung caøi ñöôïc phaùt
ra töø ngoõ ra INIT cuûa coång maùy in.
Töø ñieàu khieån ñöôïc ñöa vaøo 8255 qua IC ñeäm tuyeán 74LS244 ñoàng thôøi vôùi vieäc phaùt xung
WR treân ngoõ ra AF cuûa coång maùy in.
8255 ñöôïc khôûi ñoäng ôû cheá ñoä sau: Mode 0, PA laø port xuaát, PC laø port xuaát.

Böôùc 4: Xaùc ñònh ñòa chæ ñeå truy xuaát RAM chung.
Choïn CS 8255 baèng moät bit töông öùng trong soá 8 bit data cuûa coång maùy in, phaùt xung caøi treân
ngoõ ra INIT cuûa coång maùy in.
Baét ñaàu töø ñòa chæ 0000H, ñöa byte thaáp cuûa ñòa chæ ra data bus cuûa coång maùy in, phaùt tieáp
xung WR, ñöa tieáp byte cao cuûa ñòa chæ ra data bus cuûa coång maùy in, phaùt xung WR. Luùc naøy ñòa
chæ ñeå truy xuaát RAM chung ñaõ ñöôïc ñaët taïi ngoõ ra cuûa 8255.

Böôùc 5: Ghi data vaøo RAM chung.


Choïn CS RAM chung baèng moät bit töông öùng treân data bus cuûa coång maùy in, phaùt xung caøi
treân ngoõ ra INIT cuûa coång maùy in. Ñöa byte data töông öùng vôùi ñòa chæ ñaõ phaùt leân data bus cuûa
coång maùy in, phaùt xung WR ñeå ghi vaøo RAM chung.

Böôùc 6: Ñoïc data veà töø RAM chung vaø kieåm tra.
Giöõ nguyeân giaù trò ñòa chæ, choïn OE cuûa RAM chung baèng 1 bit töông öùng ñeå tieán haønh ñoïc
byte vöøa ñöôïc ghi. Ñaàu tieân ñaët pin A/B cuûa 74LS157 ôû möùc logic '0' ñeå ñoïc 4 bit thaáp cuûa data
bus vaøo thanh ghi traïng thaùi, caát giaù trò vöøa ñoïc ñöôïc, tieáp ñoù ñaët pin naøy ôû möùc logic cao ñeå ñoïc
tieáp 4 bit cao vaøo thanh ghi traïng thaùi, tieán haønh khoâi phuïc byte data vöøa ñoïc, so saùnh vôùi byte ñaõ
phaùt. Neáu byte phaùt ñi truøng byte thu veà thì tieán haønh böôùc tieáp theo, neáu khoâng phaùt laïi byte
naøy. Neáu phaùt laïi 3 laàn maø vaãn coøn sai thì ngöøng vaø baùo loãi. Caùc loãi coù theå xaûy ra laø:
Coù byte trong vuøng RAM chung bò hö, tröôøng hôïp naøy caàn thay RAM, hoaëc phaàn cöùng hoûng
(caùc IC 8255 74LS244, 74LS374, 74LS157, 74LS08, 74LS04), hoaëc ñôn giaûn hôn laø chöa caáp
nguoàn cho KIT.
Taêng ñòa chæ vaø data töông öùng.
Laëp laïi böôùc 5 vaø böôùc 6 cho ñeán khi hoaøn taát.
Chuù yù: ÔÛ cuøng 1 thôøi ñieåm chæ coù 1 trong 2 IC hoaëc 8255 hoaëc RAM chung ñöôïc choïn ñeå traùnh
söï va chaïm data bus.

Böôùc 7: Laøm pheùp ñoïc giaû ñeå bieán PA & PC trôû thaønh ngoõ vaøo.
Ñeå khôûi ñoäng laïi 8255 tröôùc heát phaûi choïn caùc tín hieäu ñieàu khieån thích hôïp (CS, A0, A1), caùc
tín hieäu naøy ñöôïc gôûi ñeán theo data bus cuûa coång maùy in vaø ñöôïc choát baèng moät xung caøi ñöôïc
phaùt ra töø ngoõ ra INIT cuûa coång maùy in.
Töø ñieàu khieån ñöôïc ñöa vaøo 8255 qua IC ñeäm tuyeán 74LS244 ñoàng thôøi vôùi vieäc phaùt xung
WR treân ngoõ ra AF cuûa coång maùy in.
8255 ñöôïc khôûi ñoäng ôû cheá ñoä sau: Mode 0, PA laø port nhaäp, PC laø port nhaäp.

50
2.4.2. Chaïy chöông trình töø RAM chung.

Sau khi ñaõ ñöa chöông trình ra RAM chung, ta seõ thieát laäp caùc ñieàu kieän thích hôïp ñeå KIT baét
ñaàu hoaït ñoäng theo chöông trình ñaõ ñöôïc ñöa vaøo RAM chung (Rom chöông trình). Trình töï thöïc
hieän nhö sau:

Böôùc 1: Caám taát caû caùc CS cuûa caùc IC 8255, RAM chung, 74LS244 (U1), 74LS374 thoâng qua
caùc tín hieäu ñieàu khieån thích hôïp.

Böôùc 2: Tích cöïc pin G1 & G2 cuûa 74LS244 (U4 & U5) ñeå thoâng tuyeán ñòa chæ töø Z80 CPU ñeán
RAM chung.

Böôùc 3: Ñöa chaân RESET & WAIT cuûa Z80 CPU leân möùc logic '1'. Luùc naøy KIT seõ hoaït ñoäng
theo chöông trình ñaõ ñöôïc ghi vaøo RAM chung.

2.4.3. Chaïy töøng böôùc (Debug).

Ñeå coù theå ñaët Z80 CPU vaøo cheá ñoä chaïy töøng böôùc vôùi söï can thieäp tröïc tieáp töø maùy tính sau
khi ñaõ ñöa chöông trình ra RAM chung ta laàn löôït thöïc hieän caùc böôùc sau:

Böôùc 1: Caám taát caû caùc CS cuûa caùc IC 8255, RAM chung, 74LS244 (U1), 74LS374 thoâng qua
caùc tín hieäu ñieàu khieån thích hôïp.

Böôùc 2: Tích cöïc pin G1 & G2 cuûa 74LS244 (U4 & U5) ñeå thoâng tuyeán ñòa chæ töø Z80 CPU ñeán
RAM chung.

Böôùc 3: Ñöa EWT (pin 13 cuûa IC 74LS74 leân möùc logic cao).

Böôùc 4: Ñöa chaân RESET & WAIT cuûa Z80 CPU leân möùc logic '1'. Luùc naøy KIT seõ ôû traïng
thaùi baét ñaàu hoaït ñoäng theo chöông trình ñaõ ñöôïc ghi vaøo RAM chung (ôû cheá ñoä Debug). Trình töï
hoaït ñoäng cuûa KIT Z80 vaø quaù trình xöû lyù nhö sau:

Khi Z80 truy xuaát Rom chöông trình (ôû ñaây laø RAM chung) tín hieäu CSROM seõ ôû möùc tích cöïc
thaáp, tín hieäu naøy qua coång ñaûo seõ ñöôïc ñöa ñeán chaân 11 (ngoõ vaøo CLK cuûa IC 74LS74_U8B),
chaân 9 (ngoõ ra Q) cuûa 74LS74 seõ leân möùc logic cao, chaân 8 (ngoõ ra /Q) seõ ôû möùc logic thaáp, möùc
logic naøy ñöôïc ñöa vaøo chaân 4 cuûa 74LS74 laøm ngoõ ra Q (chaân 11 U8A) ôû möùc logic cao, ngoõ ra
/Q ôû möùc logic thaáp, ngoõ ra /Q ñöôïc ñöa vaøo chaân WAIT cuûa Z80 CPU, do ñoù Z80 CPU seõ ñöôïc
ñöa vaøo traïng thaùi chôø cho ñeán khi chaân WAIT ñöôïc ñöa leân möùc logic cao.
Rom chöông trình seõ ñöôïc Z80 truy xuaát trong 2 tröôøng hôïp:
1. Laáy maõ leänh (chu kyø M1).
2. Ñoïc döõ lieäu.
ÔÛ chu kyø laáy maõ leänh seõ coù tín hieäu M1 ñi keøm (möùc tích cöïc thaáp). Tín hieäu naøy seõ ñöôïc PC
nhaän bieát qua ñöôøng Busy.

51
Nhö vaäy, thoâng qua caùc tín hieäu CSROM vaø M1, coù theå can thieäp vaøo töøng leänh cuûa Z80. Cuï
theå:
Ñeå ñoïc traïng thaùi cuûa caùc thanh ghi Z80 CPU theo töøng leänh ta thöïc hieän caùc böôùc cô baûn sau:
Giaû söû raèng breakpoint ñöôïc ñaët ôû doøng thöù n trong file coù phaàn môû roäng laø.asm. Khi thöïc hieän
chaïy ôû cheá ñoä Debug, chöông trình dòch seõ dòch file naøy ñeå coù moät file töông öùng coù phaàn môû
roäng laø.bin vaø moät file thöù hai coù phaàn môû roäng laø.lst (file naøy duøng khi ngöôøi söû duïng muoán in
hoaëc xem maõ maùy cuûa töøng leänh trong toaøn boä chöông trình).
Ví duï: Ta coù moät chöông trình vieát baèng ngoân ngöõ assembly Z80 nhö sau:
org 0000h
ld sp,0FFFEh
loop:
ld a,11h
out (00h),a
jp loop

Giaû söû file naøy ñöôïc caát döôùi teân example.asm


Giaù trò trong file example.bin seõ laø:
31 FE FF 3E 11 D3 00 C3 03 00
Giaù trò trong file example.lst seõ laø:
org 0000h
0000 31FEFF ld sp,0FFFEh
lodp:
0003 3E11 ld a,11h
0005 D300 out (00h),a
0007 C30300 jp loop

Nhö vaäy doøng thöù n trong file *.asm seõ töông öùng vôùi doøng thöù m trong file *.lst theo coâng
thöùc sau: m=n+(n div 60)*2 (sôû dó coù coâng thöùc naøy laø vì cöù 60 doøng trong file *.asm thì töông
öùng seõ coù 2 doøng ñöôïc theâm vaøo trong file *.lst). Taïi doøng thöù m trong file *.lst ta seõ ñoïc ñöôïc ñòa
chæ töông öùng cuûa moät leänh. Do ñoù breakpoint seõ töông öùng vôùi moät ñòa chæ cuï theå: breakpoint
<=> xxxxh.
Chöông trìbh Debug seõ baét ñaàu taïi ñòa chæ xxxxh ñaõ ñöôïc xaùc ñònh trong böôùc treân.
Khi Z80 truy xuaát Rom chöông trình, ta laàn löôït xeùt moät trong hai tröôøng hôïp:
a. Tröôøng hôïp truy xuaát boä nhôù: Coù tín hieäu choïn CSROM nhöng khoâng coù tín hieäu M1.
b. Tröôøng hôïp CPU laáy maõ leänh: Chia laøm 2 loaïi:
- Loaïi thöù nhaát: Leänh chæ coù 1 chu kyø M1.
- Loaïi thöù hai: Leänh coù 2 chu kyø M1. Chu kyø M1 thöù nhaát luoân baét ñaàu baèng moät trong 4 giaù trò
sau: DDH, CBH, FDH, EDH.
Nhö vaäy ta seõ phaân bieät ñöôïc ñaâu laø nôi baét ñaàu cuûa moät leänh. Trong tröôøng hôïp CPU laáy maõ
leänh, tín hieäu CSROM xuaát hieän ñoàng thôøi vôùi tín hieäu M1.
Khi Z80 truy xuaát Rom chöông trình chaân WAIT seõ töï ñoäng xuoáng möùc logic '0' nhôø phaàn cöùng
nhö ñaõ giôùi thieäu ôû treân. Trong tröôøng hôïp CPU truy xuaát (ñoïc) boä nhôù, ta khoâng xöû lyù gì caû maø
chæ caàn set chaân WAIT leân möùc logic '1' ñeå CPU tieáp tuïc chaïy bình thöôøng cho ñeán khi coù tín
hieäu truy xuaát boä nhôù tieáp theo CPU seõ töï ñoäng bò ñaët laïi vaøo traïng thaùi chôø. Trong tröôøng hôïp
CPU caàn laáy maõ leänh, ñaàu tieân phaûi xaùc ñònh maõ leänh coù bao nhieâu byte nhôø ñoïc giaù trò ñaàu cuûa

52
maõ leänh. Neáu maõ leänh coù 2 bytes thì vieäc xöû lyù maõ leänh thöù hai seõ gioáng nhö trong tröôøng hôïp
truy xuaát boä nhôù. Vieäc xöû lyù leänh ñöôïc tieán haønh nhö sau:
Khi coù tín hieäu M1, ñaàu tieân ta seõ ñoïc ñòa chæ ñang ñöôïc ñöa vaøo Rom chöông trình, so saùnh
ñòa chæ naøy vôùi ñòa chæ xxxxh (töông öùng vôùi ñieåm breakpoint), neáu chöa baèng thì set chaân WAIT
cho Z80 CPU tieáp tuïc chaïy cho ñeán khi ñòa chæ ñoïc veà ñuùng baèng ñòa chæ xxxxh, luùc naøy ta seõ tieán
haønh ñoïc traïng thaùi cuûa caùc thanh ghi, trình töï ñoïc nhö sau:

Böôùc 1: Caám CS RAM chung baèng caùch ñöa /OER (pin 15 cuûa 74LS374_U3) xuoáng möùc logic
'0' vaø ñöa /CER (pin 6 cuûa 74LS374_U3) leân möùc logic '1'.

Böôùc 2: Ñöa giaù trò C3 (maõ leänh cuûa leänh nhaûy JP HiAddrLoAddr) leân data bus, sau ñoù set
chaân WAIT leân möùc logic '1', Z80 CPU seõ tieáp tuïc chaïy vaø hoaït ñoäng tieáp theo seõ laø ñoïc byte
thaáp vaø byte cao cuûa ñòa chæ ñi theo sau maõ leänh Jump (C3LLHH), laàn löôït ñöa byte thaáp vaø byte
cao cuûa ñòa chæ leân data bus thay cho döõ lieäu töø Rom chöông trình. Ñòa chæ naøy chính laø ñòa chæ
ñaàu tieân cuûa ñoaïn chöông trình ñoïc thanh ghi maø ta ñaõ ñöa vaøo RAM chung ôû böôùc treân. Maõ leänh
tieáp theo maø Z80 CPU caàn laáy chính laø byte ñaàu tieân cuûa ñoaïn chöông trình naøy, cho pheùp CS
RAM chung baèng caùch ñöa /OER leân möùc logic '1', /CER xuoáng möùc logic '0', sau ñoù set chaân
WAIT leân möùc logic '1' ñeå CPU tieáp tuïc chaïy. Noäi dung cuûa ñoaïn chöông trình ñoïc thanh ghi bao
goàm:
- Caát noäi dung caùc thanh ghi vaøo stack.
- Laàn löôït ñöa noäi dung caùc thanh ghi A, B, C, D, E, H, L, IX, IY, SP ra ñòa chæ 0000h (ñòa chæ
naøy chính laø ñòa chæ ñaàu tieân cuûa RAM chung), khi CPU truy xuaát ñeán ñòa chæ naøy chính laø luùc
ñoïc noäi dung caùc thanh ghi veà PC. Duøng caùc leänh EX, EXX ñeå hoaùn chuyeån noäi dung caùc thanh
ghi AF', BC', DE', HL' sau ñoù ñöa noäi dung caùc thanh ghi naøy ra RAM chung ñeå ñoïc veà PC nhö ñaõ
trình baøy. Hoaùn vò laïi caùc thanh ghi AF', BC', DE', HL'.
- Khoâi phuïc noäi dung caùc thanh ghi.

Böôùc 3: Sau khi ñaõ ñoïc noäi dung caùc thanh ghi vaø in ra maøn hình, ñöa giaù trò C3 (maõ leänh cuûa
leänh nhaûy JP HiAddrLoAddr) leân data bus, sau ñoù set chaân WAIT leân möùc logic '1', Z80 CPU seõ
tieáp tuïc chaïy vaø hoaït ñoäng tieáp theo seõ laø ñoïc byte thaáp vaø byte cao cuûa ñòa chæ ñi theo sau maõ
leänh Jump, laàn löôït ñöa byte thaáp vaø byte cao cuûa ñòa chæ trôû veà (chính laø ñòa chæ cuûa leänh maø
CPU ñaõ bò chaën laïi tröôùc ñoù) leân data bus thay cho döõ lieäu töø Rom chöông trình.

Böôùc 4: Thöïc hieän leänh, chaën CPU ôû leänh tieáp theo vaø tieáp tuïc ñoïc noäi dung caùc thanh ghi theo
töøng leänh.
Nhö vaäy vieäc ñoïc noäi dung caùc thanh ghi seõ ñöôïc tieán haønh tröôùc khi CPU laáy maõ leänh thöù
nhaát.
Ñeå thöïc hieän leänh CALL nhö moät leänh ñôn cuûa Z80 trong cheá ñoä Debug ta tieán haønh nhö sau:
Ñoïc maõ leänh, neáu maõ leänh chöa phaûi laø C9 (maõ leänh RET) thì tieáp tuïc set chaân WAIT leân möùc
logic '1' ñeå CPU tieáp tuïc chaïy bình thöôøng, neáu maõ leänh ñuùng baèng C9 thì thöïc hieän ñoïc traïng
thaùi caùc thanh ghi töông töï nhö khi thöïc hieän moät leänh ñôn.

Moâ taû quaù trình Debug.

53
Ñaàu tieân chöông trình seõ töï ñoäng tìm doøng töông öùng trong file *.lst (coù noäi dung gioáng vôùi doøng
hieän taïi trong cöûa soå maøn hình soaïn thaûo). Trong file *.lst coù löu giöõ ñòa chæ cuûa leänh, do vaäy deã
daøng tìm ñöôïc ñòa chæ töông öùng cuûa doøng leänh hieän taïi. Z80 CPU seõ ñöôïc cho chaïy töø ñaàu
chöông trình ñeán ñòa chæ naøy, nhôø vaøo vieäc thöôøng xuyeân ñoïc veà PC giaù trò cuûa ñòa chæ ñöôïc ñöa
ñeán RAM chung trong moãi laàn coù söï truy xuaát cuûa CPU. Baét ñaàu töø ñaây, sau moãi leänh noäi dung
cuûa caùc thanh ghi seõ ñöôïc ñoïc veà PC. CPU seõ laáy maõ leänh keá tieáp sau khi ñaõ thöïc hieän xong moät
leänh, trong thôøi gian chôø laáy maõ leänh keá ñòa chæ cuûa leänh seõ ñöôïc ñoïc veà PC, döïa vaøo ñòa chæ naøy,
doø tìm trong file *.lst ta seõ tìm ñöôïc soá haøng töông öùng cuûa doøng leänh. Khi cho Z80 CPU tieáp tuïc
thöïc hieän leänh cuõng chính laø luùc phaûi ñaûo maøu cuûa doøng leänh hieän taïi töông öùng treân maøn hình.
Quaù trình Debug seõ keát thuùc khi ngöôøi söû duïng nhaán phím ESC treân baøn phím.

2.4.4. Ñoïc döõ lieäu töø Ram trong khi KIT Z80 ñang hoaït ñoäng.

Böôùc 1: Döøng Z80 CPU ngay khi vöøa thöïc hieän xong moät leänh.

Böôùc 2: Caám CS RAM chung baèng caùch ñöa /OER (pin 15 cuûa 74LS374_U3) xuoáng möùc logic
'0' vaø ñöa /CER (pin 6 cuûa 74LS374_U3) leân möùc logic '1'.

Böôùc 3: Ñöa giaù trò C3 (maõ leänh cuûa leänh nhaûy JP HiAddrLoAddr) leân data bus, sau ñoù set
chaân WAIT leân möùc logic '1', Z80 CPU seõ tieáp tuïc chaïy vaø hoaït ñoäng tieáp theo seõ laø ñoïc byte
thaáp vaø byte cao cuûa ñòa chæ ñi theo sau maõ leänh Jump, laàn löôït ñöa byte thaáp vaø byte cao cuûa ñòa
chæ leân data bus thay cho döõ lieäu töø Rom chöông trình. Ñòa chæ naøy chính laø ñòa chæ ñaàu tieân cuûa
ñoaïn chöông trình dump boä nhôù maø ta ñaõ ñöa vaøo RAM chung ôû böôùc treân. Maõ leänh tieáp theo maø
Z80 CPU caàn laáy chính laø byte ñaàu tieân cuûa ñoaïn chöông trình naøy, cho pheùp CS RAM chung
baèng caùch ñöa /OER leân möùc logic '1', /CER xuoáng möùc logic '0', sau ñoù set chaân WAIT leân möùc
logic '1' ñeå CPU tieáp tuïc chaïy. Noäi dung cuûa ñoaïn chöông trình ñoïc thanh ghi bao goàm:
- Caát noäi dung caùc thanh ghi vaøo stack.
- Ñöa noäi dung cuûa vuøng ñòa chæ ñöôïc chæ ñònh ra data bus.
- Khoâi phuïc noäi dung caùc thanh ghi.

Böôùc 4: Sau khi ñaõ ñoïc noäi dung boä nhôù ñöôïc chæ ñònh vaø in ra maøn hình, ta tieáp tuïc ñöa giaù trò
C3 (maõ leänh cuûa leänh nhaûy JP HiAddrLoAddr) leân data bus khi coù yeâu caàu laáy maõ leänh töø CPU,
sau ñoù set chaân WAIT leân möùc logic '1', Z80 CPU seõ tieáp tuïc chaïy vaø hoaït ñoäng tieáp theo seõ laø
ñoïc byte thaáp vaø byte cao cuûa ñòa chæ ñi theo sau maõ leänh Jump, laàn löôït ñöa byte thaáp vaø byte
cao cuûa ñòa chæ trôû veà (chính laø ñòa chæ cuûa leänh maø CPU ñaõ bò chaën laïi tröôùc ñoù) leân data bus
thay cho döõ lieäu töø Rom chöông trình.

Böôùc 5: Thieát laäp caùc ñieàu kieän thích hôïp ñeå KIT tieáp tuïc hoaït ñoäng bình thöôøng.

WX WX

Chöông III: Giôùi thieäu phaàn soaïn thaûo vaên baûn.

54
3.1. Caùc thaønh phaàn chính cuûa main menu:

3.1.1. File:
New: Môû moät file môùi.
Open (F3): Môû moät file ñaõ coù.
Save (F2): Caát file ñang môû.
Save As: Caát file ñang môû döôùi moät teân khaùc.
Exit (Alt-X): Thoaùt khoûi chöông trình.

3.1.2 Run:
Run (Ctrl-F9): Dòch chöông trình, ñöa file ñaõ dòch ra RAM chung cuûa KIT. Chaïy chöông trình
töø RAM chung.
Trace into (F7): Chaïy chöông trình töøng böôùc töø maùy tính (töøng leänh moät).
Step over (F8): Chaïy chöông trình töøng böôùc töø maùy tính (xem chöông trình con nhö moät leänh,
khoâng chaïy caùc leänh trong thaân chöông trình con).

3.1.3. Debug:
Toggle breakpoint (Ctrl-F8): Cho pheùp thieát laäp ñieåm döøng.
Delete breakpoint all: Xoùa ñieåm döøng.

3.1.4 Help:
Introdution for use: Höôùng daãn söûa chöõa.
Instruction Description: Höôùng daãn taäp leänh Z80.
About: Caùc thoâng tin khaùc.

3.2. Höôùng daãn söû duïng trong maøn hình soaïn thaûo.

Chaïy chöông trình lvtn.exe. Cöûa soå maøn hình soaïn thaûo seõ ñöôïc môû.
Caùc phím dòch chuyeån laø caùc phím thoâng thöôøng (Å,Æ,Ç,È), Home (chuyeån veà ñaàu doøng),
End (veà cuoái doøng), PgUp (trang tröôùc), PgDn (trang sau), Delete (xoaù kyù töï ôû vò trí con troû).

Vieát chöông trình öùng duïng baèng ngoân ngöõ Assembly cuûa Z80 hoaëc môû moät file coù saün ( vôùi
phaàn môû roäng.asm).
Do trong tieän ích Debug vaø Dump coù söû duïng Stack ñeå baûo toaøn noäi dung caùc thanh ghi, neân
doøng ñaàu tieân cuûa chöông trình bao giôø cuõng phaûi laø doøng khai baùo stack (vd: ld sp,0FFFEh).
Sau khi ñaõ vieát xong chöông trình caàn phaûi löu laïi vôùi phaàn môû roäng.asm. Sau ñoù coù theå chaïy
chöông trình theo 2 caùch:

Caùch thöù nhaát: Chaïy tröïc tieáp.


Ñeå chaïy tröïc tieáp chöông trình, chæ caàn nhaán Ctrl-F9. Luùc naøy chöông trình seõ ñöôïc dòch vaø
baïn caàn phaûi nhaäp teân file vaøo khi xuaát hieän thoâng baùo yeâu caàu nhaäp teân file. Löu yù:
Chæ caàn nhaäp teân file, khoâng caàn nhaäp phaàn môû roäng.

55
Khi baïn ñaõ nhaäp xong teân file, ôû doøng tieáp theo seõ xuaát hieän thoâng baùo vôùi noäi dung baïn coù
muoán taïo file listing hay khoâng, file naøy ñöôïc duøng khi baïn muoán in, hoaëc seõ ñöôïc duøng trong
cheá ñoä chaïy Debug. Baïn coù theå traû lôøi "Y" hoaëc "N" tuøy yù (trong tröôøng hôïp muoán chaïy Debug
baïn nhaát thieát phaûi traû lôøi "Y").
Khi chöông trình ñaõ ñöôïc dòch xong vaø khoâng coù loãi, file *.bin seõ ñöôïc taïo vaø file naøy seõ ñöôïc
töï ñoäng ñöa ra RAM chung, sau ñoù Z80 CPU seõ ñöôïc khôûi ñoäng vaø baét ñaàu chaïy theo chöông
trình ñaõ ñònh.
Trong khi Z80 ñang thöïc thi, treân maøn hình seõ xuaát hieän thoâng baùo hoûi baïn coù muoán xem noäi
dung boä nhôù treân KIT hay khoâng (chuù yù: ñòa chæ boä nhôù treân KIT baét ñaàu töø 8000h - FFFFh), neáu
muoán baïn phaûi nhaán F3. Luùc naøy baïn phaûi nhaäp vaøo ñòa chæ ñaàu vaø cuoái vuøng nhôù maø baïn muoán
hieån thò noäi dung leân maøn hình. Noäi dung boä nhôù seõ hieån thò khi baïn ñaõ thöïc hieän xong caùc thao
taùc treân. Chuù yù raèng trong thôøi gian ñoïc noäi dung boä nhôù chöông trình seõ taïm thôøi bò treo cho ñeán
khi vieäc ñoïc noäi dung boä nhôù hoaøn taát.
Neáu muoán trôû veà maøn hình soaïn thaûo baïn chæ caàn nhaán ESC. Trong tröôøng hôïp naøy KIT Z80
vaãn tieáp tuïc ñöôïc thöïc thi nhöng baïn seõ khoâng coøn ñoïc ñöôïc noäi dung boä nhôù nöõa.

Caùch thöù hai: Chaïy Debug.


Ñeå chaïy Debug chöông trình, ñaàu tieân baïn phaûi thieát laäp moät ñieåm döøng. Tröôùc heát ñöa con
troû ñeán vò trí caàn ñaët ñieåm döøng, sau ñoù nhaán Ctrl-F8, doøng hieän taïi seõ ñoåi maøu, ñieåm döøng ñöôïc
xaùc laäp.
Chuù yù: Ñieåm döøng caàn thieát phaûi naèm sau doøng khai baùo stack thì môùi ñöôïc xem laø hôïp leä.
Sau ñoù baïn nhaán F7 hoaëc F8 ñeå tieán haønh chaïy töøng böôùc chöông trình. Luùc naøy chöông trình
seõ ñöôïc dòch vaø baïn caàn phaûi nhaäp teân file vaøo khi xuaát hieän thoâng baùo yeâu caàu nhaäp teân file.
Löu yù:
Chæ caàn nhaäp teân file, khoâng caàn nhaäp phaàn môû roäng.
Khi baïn ñaõ nhaäp xong teân file, ôû doøng tieáp theo seõ xuaát hieän thoâng baùo vôùi noäi dung baïn coù
muoán taïo file listing hay khoâng, file naøy ñöôïc duøng khi baïn muoán in, vaø ñöôïc duøng trong cheá ñoä
chaïy Debug. Baïn phaûi traû lôøi "Y".
Khi chöông trình ñaõ ñöôïc dòch xong vaø khoâng coù loãi, file *.bin seõ ñöôïc taïo vaø file naøy seõ ñöôïc
töï ñoäng ñöa ra RAM chung, sau ñoù Z80 CPU seõ ñöôïc khôûi ñoäng vaø baét ñaàu chaïy cho ñeán khi baét
gaëp ñòa chæ töông öùng vôùi ñieåm döøng ñaõ ñöôïc thieát laäp. Neáu luùc naøy baïn nhaán F7 thì chöông trình
seõ thöïc thi töøng leänh moät ñoàng thôøi treân maøn hình seõ hieån thò noäi dung cuûa taát caû caùc thanh ghi.
Neáu baïn nhaán F8, moät leänh CALL seõ ñöôïc xöû lyù nhö moät leänh ñôn, coù nghiaõ laø thaân cuûa chöông
trình con seõ khoâng ñöôïc thöïc hieän (chöông trình seõ khoâng ñoïc traïng thaùi caùc thanh ghi khi thöïc
hieän caùc leänh trong thaân chöông trình con).
Neáu muoán thoaùt khoûi cheá ñoä Debug baïn chæ caàn nhaán ESC, khi ñoù chöông trình seõ tieáp tuïc chaïy
vaø baïn coù theå tieán haønh ñoïc traïng thaùi caùc thanh ghi gioáng nhö trong tröôøng hôïp chaïy chöông
trình bình thöôøng.

WX WX

56
Chöông IV. Giaûi thuaät

4.1. Giaûi thuaät chöông trình ñöa data ra RAM chung

Start

Init

Init 8255

Entry Filename

N
ERROR File Exist?

Y
End Open file

Read one byte

Y
Eof?

Close file
N
Get To Active Out Addrlow byte

Finish Out Addrhigh byte

End Write RAM 2 1

57
2 1
Read RAM

Count++
N
N
Count= 3? Exact?

Y
Y

ERROR Addr++

End

4.2. Giaûi thuaät cho chöông trình con INIT

Start

D0-D7='1'

Taïo xung INIT

End

58
4.3. Chöông trình con khôûi ñoäng 8255

Start

Khôûi ñoäng 8255


PA=PC=Output

Taïo xung WR

End

4.4. Chöông trình con xuaát ñòa chæ

Start

AddrLow=XXH
AddrHi=XXH

Tx=AddrLow

Taïo xung WR

Ñöa Tx ra PA

Tx=AddrHi

Taïo xungWR

Ñöa Tx ra PC

End

59
4.5. Chöông trình con ghi / ñoïc RAM vaø kieåm tra DATA

Start

Choïn CS RAM

Ñöa data leân bus

Taïo xung WR

/OE='1' Choïn /OE RAM

Ñoïc vaøo thanh ghi


traïng thaùi 4 bit thaáp

Caát 4 bit thaáp

Ñoïc vaøo thanh ghi


traïng thaùi 4 bit cao

Khoâi phuïc byte

N
Byte phaùt ñuùng?

Y
End

60
4.6. Ñoaïn chöông trình Assembly Z80 CPU duøng Dump boä nhôù

Start

Caát vaøo thanh ghi


AF , IX , IY , BC , DE

Naïp vaøo IX ñòa chæ cuoái


Naïp vaøo IY ñòa chæ ñaàu

Phaùt noäi dung cuûa IY ra


RAM chung

Taêng IY

IY = IX ?

Khoâi phuïc noäi dung caùc thanh


ghi AF , IX , IY , BC , DE

Leänh Jump

End

61
4.7. Giaûi thuaät Dump boä nhôù

Start

Nhaäp vaøo ñòa chæ ñaàu


Nhaäp vaøo ñòa chæ cuoái

Baùo loãi

N
Ñòa chæ
hôïp leä ?

Döøng Z80 CPU ôû chu kyø M1 ñaàu tieân ñöôïc tìm thaáy

Ñöa leänh Jump ra data bus

Counter = 1 : Ñöa giaù trò C3H ra data bus


Counter = 2 : Byte ñòa chæ thaáp cuûa ñoaïn Dump trong boä nhôù Ram chung
Counter = 3 : Byte ñòa chæ cao cuûa ñoaïn Dump trong boä nhôù Ram chung

Counter = 4÷12 set WAIT = ‘1’ cho Z80 chaïy bình thöôøng

Counter = caùc giaù trò khaùc → set chaân WAIT ñeå Z80 chaïy tieáp

62
Counter = 13 : Ñöa byte thaáp cuûa ñòa chæ cuoái caàn Dump ra data bus
Counter = 14 : Ñöa byte cao cuûa ñòa chæ cuoái caàn Dump ra data bus

Counter = 15÷16 set WAIT=’1’ cho Z80 chaïy bình thöôøng

Counter = 17 : Ñöa byte thaáp cuûa ñòa chæ ñaàu caàn Dump
Counter = 18 : Ñöa byte cao cuûa ñòa chæ ñaàu caàn Dump

Ñoïc maõ leänh

N
C3 ?

N
Y
32 ?

Y
Set chaân WAIT leân 1 ñeå Z80 tieáp
tuïc chaïy laïi ñieåm ñaõ döøng
Ñoïc giaù trò töø data bus

C2 ? Cho CPU chaïy tieáp End


N

Ñöa byte thaáp cuûa voøng laëp ra data bus


Ñöa byte cao cuûa voøng laëp ra data bus

63
4.8. Ñoaïn chöông trình Assembly Z80 CPU
duøng ñoïc noäi dung caùc thanh ghi

Start

Caát caùc thanh ghi


AF , BC

Ñöa noäi dung caùc thanh ghi A,


B , C , D , E , H , L , R , IX , IY ,
SP ra RAM chung

Hoaùn vò caùc thanh ghi baèng leänh


EX , EXX

Ñöa noäi dung caùc thanh ghi A’,


B’ , C’ , D’ , E’ , H’ , L’ , F’ ra
RAM chung

Hoaùn vò caùc thanh ghi

Khoâi phuïc noäi dung caùc thanh ghi

End

64
4.9. Giaûi thuaät ñoïc noäi dung caùc thanh ghi

Start

Counter = 1 : Ñöa giaù trò C3H ra data bus


Counter = 2 : Ñöa byte thaáp cuûa ñoaïn chöông trình ñoïc & ghi
Counter = 3 : Ñöa byte cao cuûa ñoaïn chöông trình ñoïc & ghi

Counter = 9,14,19,24,29,34,39,45,51,58,66,71,79,84,92,97,102,
107,112, 117,122,129,138,139
Ñoïc caùc giaù trò : A,B,C,D,E,H,L,I,R,F,IX,IY
A’,B’,C’,D’,E’,H’,L’,F’,SP

Counter = caùc giaù trò khaùc → set chaân WAIT ñeå Z80 chaïy tieáp

Counter = 142 : Ñöa giaù trò C3H ra data bus


Counter = 143 : Ñöa byte thaáp cuûa maõ leänh saép thöïc hieän ra data bus
Counter = 144 : Ñöa byte cao cuûa maõ leänh saép thöïc hieän ra data bus

End

65
4.10. Giaûi thuaät chöông trình xöû lyù phím F7 & F8
(Debug)

Start

Dòch chöông trình ñang


soaïn thaûo ra daïng *.bin

N
F7 or F8 ?

Goïi haøm Debug Goïi haøm Run

End

66
4.11. Giaûi thuaät chöông trình xöû lyù kyù töï

Start

Caát kyù töï vaøo chuoãi

Ñöa kyù töï ra maøn hình

Xöû lyù caùc phím : LEFT, UP,


RIGHT, DOWN, HOME, END,
DEL, BACKSPACE, PAGEUP,
PAGEDOWN, ENTER, TAB

Caäp nhaät caùc chöõ soá :


haøng, coät

End

67
4.12. Giaûi thuaät taïo cöûa soå soaïn thaûo

Start

Taïo cöûa soå soaïn thaûo goàm :


• Thanh menu
• Maøn hình soaïn thaûo

Xöû lyù kyù töï Ñoïc phaám nhaán

Caäp nhaät
maøn hình N

Phím chöùc
naêng ?

Thöïc hieän chöùc naêng

Alt_X ?

End

68
4.13. Giaûi thuaät chöông trình xöû lyù caùc phím chöùc naêng

Start

F1 ?

Ñöa thoâng baùo giuùp ñôõ


söûa chöõa ra maøn hình

N
F2 ?

Löu file ñang soaïn thaûo

F3 ?

Môû file

N
ESC ?

Y 1

Trôû veà maøn hình soaïn


thaûo

69
1

N
Ctrl_F9 ?

RUN

N
Ctrl_F8 ?

End

Set Breakpoint

70
Chöông V. Chöông trình nguoàn

5.1. Chöông trình ñöa data ra Ram chung, Debug, Dump, Run.

/*===================LUAÄN VAÊN TOÁT NGHIEÄP=====================


- Chöông trình ñöôïc vieát treân Turbo C++ Version 3.0.
- Ñeà taøi: Giao tieáp giöõa PC & KIT Z80 qua LPT1.
- Giaùo vieân höôùng daãn: Thaày Nguyeãn Xuaân Minh.
- Ngöôøi vieát: Löu Ñình Duõng.
- Ngaøy vieát: 11-03-1999.
- Caäp nhaät laàn cuoái: 30-06-1999
- Chuù yù: Doøng ñaàu tieân cuûa chöông trình phaûi ñöôïcc khai baùo baèng leänh:
- ld sp,xxxxh
============================================================*/
#include <dos.h>
#include <stdio.h>
#include <io.h>
#include <conio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
/*== Typedefs =================================================*/
typedef unsigned char byte;
typedef
struct addr{
byte lo;
byte hi;
};
/*== Caùc pin töông öùng cuûa 74LS374==================================
NC CS8255 /OER CS244 EWT /CER A1 A0
D7 D6 D5 D4 D3 D2 D1 D0
============================================================*/
/*== Constants =================================================*/
#define BasicADDR 0x378 /*Ñòa chæ coång maùy in*/
#define DataREG BasicADDR /*Ñòa chæ thanh ghi data*/
#define StateREG BasicADDR + 1 /*Ñòa chæ thanh ghi traïng thaùi*/
#define CTRLREG BasicADDR + 2 /*Ñòa chæ thanh ghi ñieàu khieån*/
//============================================================
#define Init374 0xD7/*ENB=1,CS8255=1,/OER=0,CS244=1,EWT=0,/CER=1,A1=1,A0=1*/
/*1101 0111*/
#define Init8255 0x97/*ENB=1,CS8255=0,/OER=0,CS244=1,EWT=0,/CER=1,A1=1,A0=1*/
/*1001 0111*/
#define WRPortA 0x94/*ENB=1,CS8255=0,/OER=0,CS244=1,EWT=0,/CER=1,A1=0,A0=0*/
/*1001 0100*/
71
#define WRPortC 0x96/*ENB=1,CS8255=0,/OER=0,CS244=1,EWT=0,/CER=1,A1=1,A0=0*/
/*1001 0110*/
#define RDPortA 0x94/*ENB=1,CS8255=0,/OER=0,CS244=1,EWT=0,/CER=1,A1=0,A0=0*/
/*1001 0100*/
#define RDPortC 0x96/*ENB=1,CS8255=0,/OER=0,CS244=1,EWT=0,/CER=1,A1=1,A0=0*/
/*1001 0110*/
#define ENBRAM 0xD3/*ENB=1,CS8255=1,/OER=0,CS244=1,EWT=0,/CER=0,A1=1,AO=1*/
/*1101 0011*/
#define GetStart 0x67/*ENB=0,CS8255=1,/OER=1,CS244=0,EWT=0,/CER=1,A1=1,AO=1*/
/*0110 0111*/
//=============================================================
#define GetDebug 0x4F/*ENB=0,CS8255=1,/OER=0,CS244=0,EWT=1,/CER=1,A1=1,A0=1*/
/*0100 1111*/
#define ClearEWT 0x67/*ENB=0,CS8255=1,/OER=1,CS244=0,EWT=0,/CER=1,A1=1,A0=1*/
/*0110 0111*/
#define EnbRAM 0x6F/*ENB=0,CS8255=1,/OER=1,CS244=0,EWT=1,/CER=1,A1=1,A0=1*/
/*0110 1111*/
#define RDPA 0x8C/*ENB=1,CS8255=0,/OER=0,CS244=0,EWT=1,/CER=1,A1=0,A0=0*/
/*1000 1100*/
#define RDPC 0x8E/*ENB=1,CS8255=0,/OER=0,CS244=0,EWT=1,/CER=1,A1=1,A0=0*/
/*1000 1110*/
#define RDREG 0xCF/*ENB=1,CS8255=1,/OER=0,CS244=0,EWT=1,/CER=1,A1=1,A0=1*/
/*1100 1111*/
#define RDData 0xEF/*ENB=1,CS8255=1,/OER=1,CS244=0,EWT=1,/CER=1,A1=1,A0=1*/
/*1110 1111*/
//=============================================================
/*Giaù trò thöïc*/ /*N/d CTRLREG*/
#define InitCTRL 0x10 /*SLCTIN=1;INIT=0;AF=1;STB=1 -> 0001 0000*/
#define GenSLCTIN 0x18 /*SLCTIN=0;INIT=0;AF=1;STB=1 -> 0001 1000*/
#define SubGen 0x1A /*SLCTIN=0;INIT=0;AF=0;STB=1 -> 0001 1010*/
#define GENSTB 0x11 /*SLCTIN=1;INIT=0;AF=1;STB=0 -> 0001 0001*/
#define GENINIT 0x14 /*SLCTIN=1;INIT=1;AF=1;STB=1 -> 0001 0100*/
#define GENAF 0x12 /*SLCTIN=1;INIT=0;AF=0;STB=1 -> 0001 0010*/
#define GENSTBLOW 0x19 /*SLCTIN=0;INIT=0;AF=1;STB=0 -> 0001 1001*/
#define GENSTBHI 0x11 /*SLCTIN=1;INIT=0;AF=1;STB=0 -> 0001 0001*/
//=============================================================
#define Mode0_Out 0x80 /*PA=PB=PC=Output,Mode 0, 1000 0000*/
#define Mode0_In 0x9B /*PA=PB=PC=Input, Mode 0, 1001 1011*/
//Caùc ñoä roäng xung
#define Tlatch 3/1000
#define Twr 3/1000
#define Tgen 3/1000
#define Set 3/1000
//*==Caùc giaù trò khaùc=============================================*/
#define TxNumber 144

72
#define countDump 18
#define TEXT_ATTR 0x1E
#define MENU_ATTR 0x70
#define HIGH_ATTR 0x20
#define MSG_ATTR 0x3E
#define RED_ATTR 0x4F
#define ROSE_ATTR 0x5F
#define END_STR 0x00
#define CALL 0xCD
#define RET 0xC9
#define JUMP 0xC3
/*==Caùc haøm propotype===========================================*/
void Latch374(void);
void INIT(void);
void WRITE(void);
void INIT8255(void);
void OutPortA(byte);
void OutPortC(byte);
void WriteRAM(byte);
byte ReadLow(void);
byte ReadHigh(void);
byte ReadRAM(void);
void WriteRAM(byte!;
int cmp(byte,byte);
void Read8255(void);
void Pseudo(void);
void GetToStart(void);
void ERROR1(byte,byte,byte,byte);
void ERROR2(void);
void Stereo(int);
void GetToDebug(void);
void SetWAIT(void);
byte RDError(void);
byte RDBusy(void);
byte RD_LoAddr(void);
byte RD_HiAddr(void);
byte ReadReg(byte,byte,byte,byte);
void GetCont(void);
void GetToCont(void);
byte Check(FILE *,char *);
addr OutKIT(byte,byte,FILE *);
void ReadRegister(char VarName);
void SetWAITDebug(byte);
void ErrorReg(byte,byte);
void PrintAddr(byte,byte,int);

73
byte KiemTra(byte,byte);
void EnableRAM(void);
byte FirstM1(void);
int FileLst(char Lst[81],byte,byte);
void UpdateScreen(void);
int LineToAddr(char Lst[81]);
void error_debug(void);
void msg_debug(void);
void msg_toolbar(void);
void msg_finish(void);
void error_file(char *);
byte CallRet_Ins(void);
byte Dump(byte,byte,byte,byte,byte,byte,byte,byte);
addr SearchM1(void);
byte ReadMem(void);
void PrintMemory(byte,int,byte,byte);
void Menu_Mem(void);
addr input_addr_dump_start(void);
addr input_addr_dump_end(void);
void msgError1(void);
void msgWait(void);
void ServiceCall(void);
/*===========================================================*/
/*=====================CHÖÔNG TRÌNH CHÍNH===================*/
/*===========================================================*/
extern char text[500][81];
extern unsigned win_index;
extern int arr_bp;
extern unsigned x, y;
extern char string_y[5],string_x[3];
char toolbar_debug[44]={" F7 Trace into F8 Step over ESC Quit"};
int ArrReg[25];
main1(char Filename[81],byte LuaChon,int Key)
{ /*==============*/
/*==Phaàn khai baùo==*/
/*==============*/
addr DiaChi,StartAddr,TempAddr,AddrDump,BinAddr;
addr AddrStart,AddrEnd;
byte ReturnAddrLo,ReturnAddrHi;
byte LoAddr,HiAddr;
byte ErrorYes,BusyYes;
byte TempLoAddr=0x00,TempHiAddr=0x00;
byte AddrFlag=0;
byte FError=0,DumpError=0;
byte KT;

74
byte InvalidM1=1,CycleM1,CycleOld;
byte Flag_bp=1;
byte Flag_call=0;
byte InvalidFlag=0;
byte DStartLoAddr,DStartHiAddr,DEndLoAddr,DEndHiAddr;
int m,CurrentLine,OldLine,TempLine,SubLine;
int Dia_chi,Addr4byte=0,Hi;
int j,k;
FILE *fp;
char TenFile[81];
byte CheckOk;
/*=================*/
/*==Phaàn chöông trình==*/
/*=================*/
INIT(); // Khôûi ñoäng 374: Reset Z80, caám caùc CS.
INIT8255(); // Khôûi ñoäng 8255: Mode 0, PA=PB=PC: Output.
fp = fopen(Filename,"rb"); // Open Filename.bin.
CheckOk=Check(fp,Filenaae); // Kieåm tra file coù hôïp leä khoâng?.
if (CheckOk==0) return(0);
/* Ñòa chæ baét ñaàu load data ra RAM chung */
StartAddr.hi=0X00;
StartAddr.lo=0X00;
/* Haøm OutKIT traû veà byte ñ/c thaáp + byte ñ/c cao
cuûa phaàn baét ñaàu chöông trình ñoïc thanh ghi */
DiaChi=OutKIT(StartAddr.lo,StartAddr.hi,fp);
if ( (DiaChi.lo==0)&&(DiaChi.hi==0) ) return(0);
/* Ñ/c baét ñaàu cuûa c/t ñoïc t/ghi */
ReturnAddrLo=DiaChi.lo;
ReturnAddrHi=DiaChi.hi;
fclose(fp);
/* Ñöa chöông trình ñoïc thanh ghi ra RAM chung (rdreg.bin) */
fp = fopen("rdreg.bin","rb");
CheckOk=Check(fp,"rdreg.bin");
if (CheckOk==0) return(0);
/* Baét ñaàu taïi ñ/c ReturnAddrHiReturnAddrLo */
TempAddr=OutKIT(ReturnAddrLo,ReturnAddrHi,fp);
if ( (TempAddr.lo==0)&&(TempAddr.hi==0) ) return(0);
fclose(fp);
/* Ñöa chöông trình dump memory ra RAM chung (dump.bin) */
fp = fopen("dump.bin","rb");
CheckOk=Check(fp,"dump.bin");
if (CheckOk==0) return(0);
/* Bat dau tai d/c TempAddr.HiTempAddr.Lo */
BinAddr=OutKIT(TempAddr.lo,TempAddr.hi,fp);
if ( (BinAddr.lo==0)&&(BinAddr.hi) ) return(0);

75
fclose( fp );
/* Ñoïc giaû 8255 ñeå caùc port A,B,C trôû thaønh ngoõ vaøo */
Read8255();
Pseudo();
/*==============================*/
/*==Chaïy ôû cheá ñoä Debug (LuaChon=1)==*/
/*==============================*/
if ( LuaChon==1 )
{
msg_toolbar(); // In thoâng baùo cuoái maøn hình.
/* Thay file.bin (Filename) = file.lst */
m=strlen(Filename);
memcpy(TenFile,Filename,m-3);
TenFile[m-3]=END_STR;
strcat(TenFile,"lst");
Dia_chi=LineToAddr(TenFile);
if (Dia_chi) // Ñòa chæ hôïp leä.
{
GetToDebug(); // Ñöa Z80 vaøo cheá ñoä WAIT (EWT='1').
clear_screen(0,20,80,4,MSG_ATTR);
msg_debug(); // In thoâng baùo.
do // (while key!=ESC) khi coù tín hieäu truy xuaát RAM chung (CSROM)
{
while ( ( Key!=K_F7 ) && ( Key != K_F8 ) && ( Key != K_ESC ) )
{
Key=get_key();
};
if ( Key==K_ESC ) break;
j=0; // Chôø ñoïc tín hieäu ERROR.
do
{
ErrorYes=RDError(); // Ñoïc tín hieäu ERROR.
if ( ErrorYes ) break; // Neáu coù -> thoaùt.
delay(Set); // Neáu khoâng -> chôø 3 micro second.
j++; /* Neáu chöa coù ERROR thì CPU coù theå ñang trong 2 case:
1. Chu kyø I/O 2. Ñang bò treo */
if ( ( j==10 ) && ( !RDError() ) ) { j=0; SetWAIT(); };
} while ( ErrorYes == 0 );
/* Cho byte cuoái cuøng ( ReadReg() ) */
if ( AddrFlag )
{
outportb(CTRLREG,InitCTRL);
delay(Set);
EnableRAM();
};

76
for (k=1;k<=3;k++)
{
BusyYes=RDBusy();
if ((BusyYes)&&(k>=2)) break; // Ñoïc 2 laàn ñeå choáng nhieãu.
delay(Set);
};
/* Neáu luùc naøy laø chu kyø M1 (BUSY=1) ñaàu tieân thì:
1. Tieán haønh ñoïc traïng thaùi caùc thanh ghi
2. Kieåm tra ñeå nhaûy tôùi breakpoint */
if ( (BusyYes) && (Flag_bp) )
{ /* Ñoïc ñòa chæ = PC ñang ñöôïc ñöa vaøo RAM
Ñ/c naøy = ñieåm thöïc hieän JP HiAddrLoAddr */
LoAddr=RD_LoAddr();
HiAddr=RD_HiAddr();
Hi=HiAddr*256;
Addr4byte=Hi+LoAddr;
CycleM1=FirstM1();
if (Dia_chi==Addr4byte) Flag_bp=0;
};
if ( ( BusyYes ) && (!Flag_bp) )
{
KT=KiemTra( TempLoAddr,TempHiAddr ); // Sai -> KT=1.
/* Neáu leänh naøy chöa thi haønh ñoïc t/ghi hoaëc ñoïc roài nhöng
bò sai hoaëc tröôùc ñoù khoâng phaûi laø caùc g.trò: FD, DD, CB, ED */
if ( ( AddrFlag == 0 ) || ( ( AddrFlag == 1 ) && ( KT ) ) )
{
/* Neáu chu kyø M1 laø hôïp leä ( laø chu kyø M1 thöù nhaát ) */
if ( InvalidM1 )
{
CycleOld=CycleM1;
CycleM1=FirstM1();
/* Ñaùnh daáu chu kyø M1 tieáp sau seõ khoâng hôïp leä */
if ( CycleM1==1 ) InvalidM1=0;
/* F8+CALL: SetWAIT() cho ñeán khi gaëp RET */
else if ( (Key==K_F8) && (CycleOld==CALL) ) Flag_call=1;
if (Flag_call)
{
SetWAIT();
ServiceCall();
Flag_call=0;
};
/* Neáu chöa thöïc hieän leänh hieän taïi laàn naøo */
if ( AddrFlag == 0 )
{
do

77
{
AddrFlag = 1;
/* Ñoïc ñòa chæ = PC ñang ñöôïcc ñöa vaøo RAM
Ñ/c naøy = ñieåm t/hieän JP HiAddrLoAddr */
LoAddr=RD_LoAddr();
HiAddr=RD_HiAddr();
delay(Set); // delay() roài ñoïc laïi cho chính xaùc.
TempLoAddr=RD_LoAddr();
TempHiAddr=RD_HiAddr();
} while ((TempLoAddr!=LoAddr) || (TempHiAddr!=HiAddr));
}
// Phaùt laïi neáu thöïc hieän sai leänh tröôùc ñoù.
else if ( ( AddrFlag == 1 ) && ( KT ) )
{
LoAddr=TempLoAddr;
HiAddr=TempHiAddr;
};
/*Chöông trình ñoïc traïng thaùi caùc thanh ghi*/
/*Ñöa LoAddr & HiAddr vaøo ñeå thöïc hieän leänh JP ADDR*/
do
{ //Ñ/c JP veà ,ñ/c JP ñi (ñoaïn c/t ñoïc t/ghi)
FError=ReadReg(LoAddr,HiAddr,ReturnAddrLo,ReturnAddrHi);
} while ( FError==0 );
/*==========================================*/
/*=========Phan hien thi dong dang Debug==========*/
/*===========Input: ñòa chæ (HiAddr,LoAddr)=========*/
/*==========================================*/
/*
1. Môû file filename.lst, truyeàn ñ/c HiAddr,LoAddr.
Tìm line coù ñòa chæ töông öùng, traû veà line (CurrentLine).
2. Ñ/c chuyeån con troû tôùi line t.öùng trong maøn hình editor.
3. Highlight.
*/
clear_screen(0,20,80,4,MSG_ATTR);
/* Thay file.bin (Filename) = file.lst */
m=strlen(Filename);
memcpy(TenFile,Filename,m-3);
TenFile[m-3]=END_STR;
strcat(TenFile,"lst");
CurrentLine=FileLst(TenFile,HiAddr,LoAddr);
set_attr_screen(0,OldLine,80,1,TEXT_ATTR);
/* Do file lst: 60 doøng + 2 doøng
*.lst -> *.asm: line=line-(line-1)/62*2 */
SubLine=(CurrentLine-1)/62*2;
CurrentLine=CurrentLine-SubLine;

78
if ( (CurrentLine<win_index)||(CurrentLine>win_index+18) )
{
win_index=CurrentLine-8;
UpdateScreen();
clear_screen(0,20,80,4,MSG_ATTR);
set_attr_screen(0,0,80,1,MENU_ATTR);
}
TempLine=CurrentLine - win_index;
set_attr_screen(0,TempLine,80,1,MENU_ATTR);
OldLine=TempLine;
PrintAddr(HiAddr,LoAddr,CurrentLine);
Key=get_key();
} // If (InvalidM1).
/* Neáu laø chu kyø M1 thöù 2 */
else if ( ( InvalidM1 == 0 ) && ( AddrFlag == 0 ) )
{
InvalidM1=1;
SetWAIT();
}
} // if ( (AddrFlag == 0) || ( (AddrFlag == 1) && (KT) ) )
/*Neáu laø chu kyø M1 nhöng ñaõ duyeät qua roài thì cho CPU chaïy tieáp*/
else
{
AddrFlag=0;
SetWAIT();
};
} // if ( ( BusyYes ) && (!Flag_bp) )
/* Neáu laø chu kyø ñoïc boä nhôù thì SetWAIT ñeå CPU chaïy tieáp */
else SetWAIT();
} while ( Key != 27 );
/* Chaïy tieáp sau khi thoaùt khoûi cheá ñoä DEBUG */
GetToCont();
} // else if (Dia_chi==0)
else // Baùo loãi + break.
{
error_debug(); return 0;
}
} //end ( if LuaChon == 1 )
/*==============================*/
/*==Chaïy ôû cheá ñoä normal (LuaChon=2)==*/
/*==============================*/
else if ( LuaChon==2 )
{
/*Khôûi ñoäng Z80 ñeå chaïy chöông trình töø RAM chung (normal mode)*/
GetToStart();

79
};
msg_finish();
/*Ñoaïn chöông trình dump boä nhôù*/
do
{
Key=get_key();
while ( ( Key!=K_F3 ) && ( Key != K_ESC ) )
{
Key=get_key();
};
if (Key==K_F3)
{
//Ñ/c caàn dump: DStartLoAddr,DStartHiAddr,DEndLoAddr,DEndHiAddr
GetToDebug(); //Cho pheùp WAIT, caám RAM, chôø ñoïc BUSY
while (!InvalidFlag)
{
AddrStart=input_addr_dump_start();
AddrEnd=input_addr_dump_end();
DStartLoAddr=AddrStart.lo;
DStartHiAddr=AddrStart.hi;
DEndLoAddr = AddrEnd.lo;
DEndHiAddr= AddrEnd.hi;
//AddrEnd++
if (DEndLoAddr == 0xFF)
{
DEndHiAddr++;
DEndLoAddr = 0x00;
}
else DEndLoAddr++;

if (DStartHiAddr>DEndHiAddr) msgError1();
else if ( (DStartHiAddr==DEndHiAddr)&&(DStartLoAddr>DEndLoAddr) )
msgError1();
else InvalidFlag=1;
}
AddrDump=SearchM1(); //Tìm chu kyø M1 hôïp leä
msgWait();
do
{ /*D/c jp veà D/c jp tôùi (ñoaïn ct dump)*/
DumpError=Dump(AddrDump.lo,AddrDump.hi,TempAddr.lo,TempAddr.hi,
DStartLoAddr,DStartHiAddr,DEndLoAddr,DEndHiAddr);
} while ( DumpError==0 ); /*ñ/c ñaàu boä nhôù, ñ/c cuoái boä nhôù*/
GetToCont();
InvalidFlag=0;
}

80
} while (Key!=K_ESC);
return 0;
}

/*===========================================================*/
/*==Caùc chöông trình con=========================================*/
/*===========================================================*/

/*==Chöông trình con phaùt aâm thanh==*/


void Stereo(int input)
{
int m=1;
while ( m<=3 )
{
sound(input);delay(200);nosound();delay(300);
m++;
}
}

/*==Chöông trình con baùo loãi 01==*/


void ERROR1(byte AddrLow,byte AddrHi,byte DatOut,byte DAT)
{
if ( (AddrLow) || (AddrHi) )
{
Stereo(494);
set_cursor_style(0x20,0x20);
set_attr_screen(23,11,38,7,RED_ATTR);
gotoxy(24,12); puts("⎡");
gotoxy(24,13); puts(" ⏐ ERROR 1: ⏐ ");
gotoxy(24,14); puts(" ⏐ 1. Common RAM 's fail. ⏐ ");
gotoxy(24,15); printf(" ⏐ 2. Data transmit: %02X%02X: %02X ⏐ ",
AddrHi,AddrLow,DatOut);
gotoxy(24,16); printf("⏐ . Data receiver: %02X%02X: %02X ⏐",
AddrHi,AddrLow,DAT);
gotoxy(24,17); puts("⏐ Press ESC to QUIT. ⏐ ");
gotoxy(24,18); puts("⎣ ");
}
else
{
Stereo(494);
set_cursor_style(0x20,0x20);
set_attr_screen(23,11,8,7,RED_ATTR);
gotoxy(24,12); puts("⎡");
gotoxy(24,13); puts("⏐ ERROR 2: ⏐ ");
gotoxy(24,14); puts("⏐ 1. Power off. ⏐ ");

81
gotoxy(24,15); puts("⏐ 2. Jack 25 pin nonconected. ⏐ ");
gotoxy(24,16); puts("⏐ 3. Hard wave error. ⏐ ");
gotoxy(24,17); puts("⏐ Press ESC to QUIT. ⏐ ");
gotoxy(24,18); puts(“⎣");
};
if (getch()==0) getch();
// exit(1);
}

/*==Chöông trình con baùo loãi 02==*/


void ERROR2(void)
{
Stereo(494);
set_cursor_style(0x20,0x20);
set_attr_screen(23,11,38,5,RED_ATTR);
gotoxy(24,12); puts(" ⎡ ");
gotoxy(24,13); puts("⏐ ERROR 3: ⏐ ");
gotoxy(24,14); puts("⏐ File is too long. ⏐ ");
gotoxy(24,15); puts("⏐ Press ESC to QUIT. ⏐ ");
gotoxy(24,16); puts(“⎣ ");
if (getch()==0) getch();
// exit(0);
}

/*==Chöông trình con khôûi ñoäng Z80 ôû cheá ñoä normal==*/


void GetToStart(void)
{
outportb(DataREG,GetStart);
Latch374();
outportb(CTRLREG,InitCTRL); // Ñaët trôû laïi ñöôøng CTRL ôû g.trò b.ñaàu
}

/*==Chöông trình khôûi ñoäng 8255: MODE 0, PA=PB=PC: input==*/


void Read8255(void)
{
outportb(DataREG,Init8255); // Choïn 8255
Latch374();
outportb(DataREG,Mode0_In); // Ghi töø ñ.khieån
WRITE();
outportb(DataREG,Init374); // Ñaët trôû laïi giaù trò ban ñaàu cho 374
Latch374();
}

/*==Chöông trình con laøm pheùp ñoïc giaû==*/


void Pseudo(void)

82
{
outportb(DataREG,RDPortA);
Latch374();
/*Phat xung RD*/
outportb(CTRLREG,GENSTBLOW);
delay(Tgen); // Delay 3 micro second
outportb(CTRLREG,InitCTRL); // Ñaët trôû laïi ñöôøng CTRL ôû g.trò b.ñaàu
outportb(DataREG,RDPortC); // Ñaët trôû laïi giaù trò ban ñaàu cho 374
Latch374();
/*Phat xung RD*/
outportb(CTRLREG,GENSTBLOW);
delay(Tgen); // Delay 3 micro second
outportb(CTRLREG,InitCTRL); // Ñaët trôû laïi ñöôøng CTRL ôû g.trò b.ñaàu
outportb(DataREG,Init374); // Ñaët trôû laïi giaù trò ban ñaàu cho 374
Latch374();
}

/*==Chöông trình con so saùnh byte phaùt (DatOut) & byte thu (DAT)==*/
int cmp(byte R,byte T)
{
if (R==T) return(0);
else return(1);
}

/*==Chöông trình con taïo xung caøi 374==*/


void Latch374(void)
{
outportb(CTRLREG,GENINIT);
delay(Tlatch); // Delay 3 micro second (Tlatch)
outportb(CTRLREG,InitCTRL);
}

/*==Chöông trình con khôûi ñoäng KIT==*/


void INIT(void)
{
outportb(CTRLREG,InitCTRL); // Khôûi taïo caùc xung ñieàu khieån
outportb(DataREG,Init374); // Khôûi taïo KIT
Latch374(); // Phaùt xung caøi
}

/*==Chöông trình con taïo xung WR==*/


void WRITE(void)
{
outportb(CTRLREG,GENAF);
delay(Twr); // Delay 3 micro second (Twr)

83
outportb(CTRLREG,InitCTRL); // Ñaët trôû laïi ñöôøng CTRL ôû g.trò b.ñaàu
}

/*==Chöông trình khôûi ñoäng 8255: MODE 0, PA=PB=PC: output==*/


void INIT8255(void)
{
outportb(DataREG,Init8255);
Latch374();
outportb(DataREG,Mode0_Out);
WRITE();
outportb(DataREG,Init374); //Ñaët trôû laïi giaù trò ban ñaàu cho 374
Latch374();
}

/*==Chöông trình con xuaát byte thaáp cuûa ñòa chæ ra port A==*/
void OutPortA(byte low)
{
outportb(DataREG,WRPortA);
Latch374();
outportb(DataREG,low);
WRITE();
outportb(DataREG,Init374); //Ñaët trôû laïi giaù trò ban ñaàu cho 374
Latch374();
}

/*==Chöông trình con xuaát byte cao cuûa ñòa chæ ra port C==*/
void OutPortC(byte high)
{
outportb(DataREG,WRPortC);
Latch374();
outportb(DataREG,high);
WRITE();
outportb(DataREG,Init374); // Ñaët trôû laïi giaù trò ban ñaàu cho 374.
Latch374();
}

/*==Chöông trình con taïo xung RD cho RAM & 'L' cho 157==*/
byte ReadLow(void)
{
byte lowvalue;
outportb(CTRLREG,GENSTBLOW);
delay(Tgen); // Delay 3 micro second.
lowvalue=inportb(StateREG);
outportb(CTRLREG,InitCTRL); // Ñaët trôû laïi ñöôøng CTRL ôû giaù trò ban ñaàu.
return(lowvalue);

84
}

/*==Chöông trình con taïo xung RD cho RAM & 'H' cho 157==*/
byte ReadHigh(void)
{
byte highvalue;
outportb(CTRLREG,GENSTBHI);
delay(Tgen); // Delay 3 micro second.
highvalue=inportb(StateREG);
outportb(CTRLREG,InitCTRL); // Ñaët trôû laïi ñöôøng CTRL ôû giaù trò ban ñaàu.
return(highvalue);
}

/*==Chöông trình ñoïc giaù trò töø RAM==*/


byte ReadRAM(void)
{
byte value,lo,hi;
outportb(DataREG,ENBRAM);
Latch374();
/*Ñoïc 4 bit thaáp*/
lo=ReadLow();
lo=lo & 0xF0; // 1111 0000: Xoaù 4 bit thaáp cuûa thanhh ghi traïng thaùi.
lo=lo/16; // Dòch phaûi 4 bit.
/*Ñoïc 4 bit cao*/
hi=ReadHigh();
hi=hi & 0xF0; // 1111 0000: Xoaù 4 bit thaáp cuûa thanhh ghi traïng thaùi.
value=hi+lo;
outportb(DataREG,Init374); // Ñaët trôû laïi giaù trò ban ñaàu cho 374.
Latch374();
return(value);
}

/*==Chöông trình con ghi RAM==*/


void WriteRAM(byte data)
outportb(DataREG,ENBRAM);
Latch374();
outportb(DataREG,data);
WRITE();
outportb(DataREG,Init374); // Ñaët trôû laïi giaù trò ban ñaàu cho 374.
Latch374();
}
/*===========================================*/
/*==Caùc chöông trình con phuïc vuï cho cheá ñoä chaïy Debug==*/
/*===========================================*/

85
/*==Chöông trình con khôûi ñoäng Z80 ôû cheá ñoä DEBUG==*/
void GetToDebug(void)
{
outportb(DataREG,GetDebug); // Cho pheùp WAIT, caám RAM, chôø ñoïc BUSY.
Latch374();
outportb(CTRLREG,InitCTRL);
}

/*==Chöông trình con cho pheùp RAM sau khi xuaát datadebug töø PC ra==*/
void EnableRAM(void)
{
outportb(DataREG,EnbRAM);
Latch374();
}

/*==Chöông trình con ñoïc traïng thaùi caùc thanh ghi==*/


byte ReadReg(byte LowAddr,byte HighAddr,byte RAddrLo,byte RAddrHi)
{
int countTx=0;
int i,k;
char Kytu;
byte ErrorYes,BusyYes;
byte FlagError=1;
/*Laøm cho heát soá laàn CSROM ñònh tröôùc = TxNumber*/
do
{
countTx++;
i=0;
do
{
ErrorYes=RDError();
if ( ErrorYes ) break;
delay(Set);
i++;
/* if ( ( i==2 ) && ( ErrorYes == 0 ) ) { i=0; SetWAIT(); }; */
if ( ( i==10 ) && ( !RDError() ) ) { i=0; SetWAIT(); };
} while ( ErrorYes == 0 );
if ( ( countTx == 2 ) || ( countTx == 3 ) || ( countTx == 4 )
|| ( countTx == 143) || ( countTx == 144) )
{
outportb(CTRLREG,InitCTRL);
delay(Set);
};
if ( countTx == 4 ) EnableRAM();
for (k=1;k<=3;k++)

86
{
BusyYes=RDBusy();
if ((BusyYes)&&(k>=2)) break; // Ñoïc 2 laàn ñeå choáng nhieãu.
delay(Set);
};
if ( BusyYes )
{
switch ( countTx )
{
case 1: SetWAITDebug(JUMP); break;
case 142: SetWAITDebug(JUMP); break;
/*Caùc tröôøng hôïp read memory*/
case 2,3,7,8,9,12,13,14,17,18,19,22,23,24,27,28,29,32,33,34,37,38,
39,43,44,45,49,50,51,56,57,58,64,65,66,69,70,71,77,78,79,82,83,84,
90,91,92,95,96,97,100,101,102,105,106,107,110,111,112,115,116,117,
120,121,122,127,128,129,136,137,138,139,143,144:
{
/*Nhaûy veà ñaàu chöông trình neáu coù loãi*/
ErrorReg(LowAddr,HighAddr);
return(0);
}
default: SetWAIT();
};
}
/* Xöû lyù chu kyø ñoïc/ghi boä nhôù */
else
{
switch ( countTx )
{
case 2: SetWAITDebug(RAddrLo); break;
case 3: SetWAITDebug(RAddrHi); break;
case 9: Kytu='A'; ReadRegister(Kytu); SetWAIT(); break;
case 14: Kytu='B'; ReadRegister(Kytu); SetWAIT(); break;
case 19: Kytu='C'; ReadRegister(Kytu); SetWAIT(); break;
case 24: Kytu='D'; ReadRegister(Kytu); SetWAIT(); break;
case 29: Kytu='E'; ReadRegister(Kytu); SetWAIT(); break;
case 34: Kytu='H'; ReadRegister(Kytu); SetWAIT(); break;
case 39: Kytu='L'; ReadRegister(Kytu); SetWAIT(); break;
case 45: Kytu='I'; ReadRegister(Kytu); SetWAIT(); break;
case 51: Kytu='R'; ReadRegister(Kytu); SetWAIT(); break;
case 58: Kytu='F'; ReadRegister(Kytu); SetWAIT(); break;
case 66: Kytu='X'; ReadRegister(Kytu); SetWAIT(); break;
case 71: Kytu='x'; ReadRegister(Kytu); SetWAIT(); break;
case 79: Kytu='Y'; ReadRegister(Kytu); SetWAIT(); break;
case 84: Kytu='y'; ReadRegister(Kytu); SetWAIT(); break;

87
case 92: Kytu='a'; ReadRegister(Kytu); SetWAIT(); break;
case 97: Kytu='b'; ReadRegister(Kytu); SetWAIT(); break;
case 102: Kytu='c'; ReadRegister(Kytu); SetWAIT(); break;
case 107: Kytu='d'; ReadRegister(Kytu); SetWAIT(); break;
case 112: Kytu='e'; ReadRegister(Kytu); SetWAIT(); break;
case 117: Kytu='h'; ReadRegister(Kytu); SetWAIT(); break;
case 122: Kytu='l'; ReadRegister(Kytu); SetWAIT(); break;
case 129: Kytu='f'; ReadRegister(Kytu); SetWAIT(); break;
case 138: Kytu='P'; ReadRegister(Kytu); SetWAIT(); break;
case 139: Kytu='S'; ReadRegister(Kytu); SetWAIT(); break;
case 143: SetWAITDebug(LowAddr); break;
case 144: SetWAITDebug(HighAddr); break;
default: SetWAIT();
}; // end switch.
}; // end else.
} while ( countTx < TxNumber );
return(FlagError);
}

/*==Chöông trình xöû lyù loãi khi ñoïc traïng thaùi caùc thanh ghi==*/
/*================Nhaûy veà ñ/c cu=================*/
void ErrorReg(byte LoDC,byte HiDC)
{
int countTx=0;
int i,k;
byte ErrorYes,BusyYes;
while ( countTx < 3 )
{
countTx++;
i=0;
do
{
ErrorYes=RDError();
if ( ErrorYes ) break;
delay(Set);
i++;
if ( ( i==10 ) && ( !RDError() ) ) { i=0; SetWAIT(); };
} while ( ErrorYes == 0 );
if ( ( countTx == 2 ) || ( countTx == 3 ) ) outportb(CTRLREG,InitCTRL);
for (k=1;k<=3;k++)
{
BusyYes=RDBusy();
if ((BusyYes)&&(k>=2)) break; // Ñoïc 2 laàn ñeå choáng nhieãu.
delay(Set);
};

88
if ( BusyYes )
{
if ( countTx == 1 ) SetWAITDebug(JUMP);
}
else if ( countTx == 2 ) { SetWAITDebug(LoDC); }
else if (countTx == 3) SetWAITDebug(HiDC);
} // end while.
}

/*==Chöông trình con ñoïc tín hieäu BUSY==*/


byte RDBusy(void)
{
int BusyVar;
byte BusyFlag;
/*Xeùt thanh ghi traïng thaùi*/
BusyVar=inportb(StateREG);
BusyVar=BusyVar & 0x80; // 1000 0000: Laáy bit BUSY.
if (BusyVar==128) BusyFlag=1;
else BusyFlag=0;
return(BusyFlag);
}

/*==Chöông trình con ñoïc tín hieäu ERROR==*/


byte RDError(void)
{
int ErrorVar;
byte ErrorFlag;
/*Xeùt thanh ghi traïng thaùi*/
ErrorVar=inportb(StateREG);
ErrorVar=ErrorVar & 0x08; // 0000 1000: Laáy bit ERROR.
if (ErrorVar==8) ErrorFlag=1;
else ErrorFlag=0;
return(ErrorFlag);
}

/*==Chöông trình con set tín hieäu WAIT (data from RAM)==*/
/*EWT='0' + dat EWT='1' + taïo xung SLCTIN*/
void SetWAIT(void)
{
outportb(DataREG,ClearEWT);
Latch374();
outportb(DataREG,EnbRAM);
Latch374();
/*Taïo xung SLCTIN*/
outportb(CTRLREG,GenSLCTIN);

89
delay(Set); // Ñeå tín hieäu cho pheùp RAM coù thôøi gian caøi ra laâu hôn.
outportb(CTRLREG,InitCTRL);
}

/*==Chöông trình con set tín hieäu WAIT (data from PC)==*/
/*EWT='0' + dat EWT='1' + taïo xung SLCTIN*/
void SetWAITDebug(byte dataTx)
{
outportb(DataREG,ClearEWT);
Latch374();
outportb(DataREG,GetDebug);
Latch374();
/*Taïo xung SLCTIN + giöõ AF='0'*/
outportb(CTRLREG,SubGen);
delay(Tlatch); // Delay 3 micro second (Tlatch).
outportb(DataREG,dataTx);
outportb(CTRLREG,GENAF);
}

/*==Chöông trình con cho KIT tieáp tuïc chaïy sau khi keát thuùc Debug==*/
void GetCont(void)
{
outportb(DataREG,ClearEWT);
Latch374();
/*Taïo xung SLCTIN*/
outportb(CTRLREG,GenSLCTIN);
delay(Tlatch); // Delay 3 micro second (Tlatch).
outportb(CTRLREG,InitCTRL);
}

/*==Chöông trình con cho Kit tieáp tuïc chaïy sau khi Debug or Dump==*/
void GetToCont(void)
{
byte ErrorYes;
do
{
ErrorYes=RDError();
} while ( ErrorYes == 0 );
outportb(CTRLREG,InitCTRL);
GetCont();
}

/*==Chöông trình con ñoïc byte thaáp cuûa ñöôøng ADDR==*/


byte RD_LoAddr(void)
{

90
byte valueLoAddr,loAddr,hiAddr;
/*ENB=1,CS8255=0,/OER=0,CS244=0,EWT=1,/CER=1,A1=0,A0=0*/
outportb(DataREG,RDPA);
Latch374();
/*Ñoïc 4 bit thaáp*/
loAddr=ReadLow();
loAddr=loAddr & 0xF0; //1111 0000: Xoùa 4 bit thaáp cuûa thanh ghi traïng thaùi.
loAddr=loAddr / 0x10; // Dòch phaûi 4 bit (div 16).
/*Ñoïc 4 bit cao*/
hiAddr=ReadHigh();
hiAddr=hiAddr & 0xF0; //1111 0000: Xoaù 4 bit thaáp cuûa thanh ghi traïng thaùi.
valueLoAddr=hiAddr+loAddr;
return(valueLoAddr);
}

/*==Chöông trình con ñoïc byte cao cuûa ñöôøng ñòa chæ==*/
byte RD_HiAddr(void)
{
byte valueHiAddr,loAddr,hiAddr;
/*ENB=1,CS8255=0,/OER=0,CS244=0,EWT=1,/CER=1,A1=1,A0=0*/
outportb(DataREG,RDPC);
Latch374();
/*Ñoïc 4 bit thaáp*/
loAddr=ReadLow();
loAddr=loAddr & 0xF0;//1111 0000: Xoaù 4 bit thaáp cuûa thanh ghi traïng thaùi.
loAddr=loAddr / 0x10; // Dòch phaûi 4 bit (div 16).
/*Ñoïc 4 bit cao*/
hiAddr=ReadHigh();
hiAddr=hiAddr & 0xF0;//1111 0000: Xoaù 4 bit thaáp cuûa thanh ghi traïng thaùi.
valueHiAddr=hiAddr+loAddr;
outportb(DataREG,GetDebug); // Ñaët trôû laïi giaù trò ban ñaàu cho 374.
Latch374();
return(valueHiAddr);
}

/*==Chöông trình con kieåm tra tính hôïp leä cuûa file==*/
byte Check(FILE *filePoint,char FName[81])
{
if ( filePoint == NULL )
{
error_file(FName);
Stereo(165);
return 0;
}
else return 1;

91
}

/*==Thoâng baùo loãi==*/


void error_file(char FName[81])
{
set_cursor_style(0x20,0x20);
set_attr_screen(23,11,38,5,RED_ATTR);
gotoxy(24,12); puts(" ÚÄ Ä Ä Ä Ä Ä Ä Ä Ä Ä Ä Ä¿ ");
gotoxy(24,13); puts(" ³ERROR: ³ ");
gotoxy(24,14); printf(" ³ File not found: %12s ³",FName);
gotoxy(24,15); puts(" ³ Press any key to QUIT ³ ");
gotoxy(24,16); puts(" ÀÄ Ä Ä Ä Ä Ä Ä Ä Ä Ä Ä ÄÙ ");
if (getch()==0) getch();
}

/*==================Chöông trình con ñöa data ra KIT=================*/


/*Chöông trình con ñöa data chöùa chöông trình ñoïc t/ghi (rdreg.bin) ra KIT*/
/*Chöông trình con ñöa data chöùa chöông trình dump memory (dump.bin) ra KIT*/
addr OutKIT(byte AddrLow,byte AddrHi,FILE *fp)
{
addr Add;
byte DAT,DatOut;
int Result,count;
/*Ñoïc 1 byte ra DatOut*/
while( fread( (char*) &DatOut, sizeof( DatOut ), 1, fp) )
{
/*(char*) &DatOut ñeå bieán ñoåi ñ.chæ cuûa bieán thaønh
ñ.chæ cuûa vuøng kyù töï vaø toân troïng cuù phaùp cuûa fread*/
count=1;
Result=1;
do
{
count++;
/*Xuat ñòa chæ*/
OutPortA(AddrLow); // Phaùt laïi caû ñòa chæ.
OutPortC(AddrHi);
WriteRAM(DatOut); // Ghi data vaøo RAM chung.
DAT=ReadRAM(); // Ñoïc data töø RAM chung.
Result=cmp(DAT,DatOut); // Kieåm tra byte vöøa phaùt.
}
while ( ( Resu`t ) && ( count <= 3 ) );
if( Result==0 ) //Byte phaùt ñuùng->Taêng ñòa chæ+Ñoïc byte keá.
{
/*Taêng ñòa chæ*/
if( AddrLow == 0xFF )

92
{
AddrLow = 0;
AddrHi++;
if ( AddrHi > 0x7F ) // (0111 1111).
{
ERROR2();
Add.lo=0;
Add.hi=0;
return(Add);
};
} // > 32Kb
else AddrLow++;
} // end if (Result).
/*'Sai'+'baùo loãi'+'thoaùt'*/
else
{
ERROR1(AddrLow,AddrHi,DatOut,DAT);
Add.lo=0;
Add.hi=0;
return(Add);
};
} // end while.
Add.lo=AddrLow;
Add.hi=AddrHi;
return(Add);
}

/**==Chöông trình con ñoïc data töø bus + in ra maøn hình==*/


void ReadRegister(char VarName)
{
byte value,lo,hi;
/*Ñoïc 4 bit thaáp*/
outportb(DataREG,RDREG); //Ñaët trôû laïi giaù trò ban ñaàu cho 374.
Latch374();
lo=ReadLow();
lo=lo & 0xF0; //1111 0000: Xoaù 4 bit thaáp cuûa thanh ghi traïng thaùi.
lo=lo / 0x10; // Dòch phaûi 4 bit.
/*Ñoïc 4 bit cao*/
hi=ReadHigh();
hi=hi & 0xF0; //1111 0000: Xoaù 4 bit thaáp cuûa thanh ghi traïng thaùi.
value=hi+lo;
switch ( VarName )
{
case 'A': ArrReg[0]=value; break;
case 'B': ArrReg[1]=value; break;

93
case 'C': ArrReg[2]=value; break;
case 'D': ArrReg[3]=value; break;
case 'E': ArrReg[4]=value; break;
case 'H': ArrReg[5]=value; break;
case 'L': ArrReg[6]=value; break;
case 'I': ArrReg[7]=value; break;
case 'R': ArrReg[8]=value; break;
case 'F': ArrReg[9]=value; break;
case 'X': ArrReg[10]=value; break;
case 'Y': ArrReg[11]=value; break;
case 'S': ArrReg[12]=value; break;
case 'P': ArrReg[13]=value; break;
case 'a': ArrReg[14]=value; break;
case 'b': ArrReg[15]=value; break;
case 'c': ArrReg[16]=value; break;
case 'd': ArrReg[17]=value; break;
case 'e': ArrReg[18]=value; break;
case 'h': ArrReg[19]=value; break;
case 'l': ArrReg[20]=value; break;
case 'f': ArrReg[21]=value; break;
case 'x': ArrReg[22]=value; break;
case 'y': ArrReg[23]=value; break;
};
delay(Set);
}

/*==Chöông trình con in ñòa chæ & n/d thanh ghi==*/


void PrintAddr(byte HiAddr,byte LoAddr,int CurrentLine)
{
gotoxy(1,21);
printf("É=================The contents of registers============»");
printf(" AF = %02X%02X",ArrReg[0],ArrReg[9]);
printf( " BC = %02X%02X",ArrReg[1],ArrReg[2]);
printf( " DE = %02X%02X",ArrReg[3],ArrReg[4]);
printf( " HL = %02X%02X",ArrReg[5],ArrReg[6]);
printf( " SP = %02X%02X",ArrReg[12],ArrReg[13]);
printf( " PC = %02X%02X º",HiAddr,LoAddr);
printf(" AF'= %02X%02X",ArrReg[14],ArrReg[21]);
printf( " BC'= %02X%02X",ArrReg[15],ArrReg[16]);
printf( " DE'= %02X%02X",ArrReg[17],ArrReg[18]);
printf( " HL'= %02X%02X",ArrReg[19],ArrReg[20]);
printf( " IX = %02X%02X",ArrReg[22],ArrReg[10]);
printf( " IY = %02X%02X º",ArrReg[23],ArrReg[11]);
printf("È==%4d==================================¼",
CurrentLine);

94
}

/**==Chöông trình con kieåm tra PC==**/


byte KiemTra(byte TempLoAddr,byte TempHiAddr)
{
byte KiemTra=0;
byte LoAddr,HiAddr;
/*Ñoïc ñòa chæ = PC ñang ñöôïc ñöa vaøo RAM
Ñ/c naøy = ñieåm t/hieän JP HiAddrLoAddr*/
LoAddr=RD_LoAddr();
HiAddr=RD_HiAddr();
if ( ( LoAddr != TempLoAddr ) || ( HiAddr != TempHiAddr ) )
KiemTra = 1; // Baùo sai.
return(KiemTra);
}

/**==Chöông trình con kieåm tra chu kyø M1 first==**/


/*Ñoïc data töø bus, xem coù phaûi laø 1 trong caùc g.trò: ED, DD, FD, CB*/
byte FirstM1(void)
{
byte value,lo,hi;
byte FlagM1;
/*Ñoïc 4 bit thaáp*/
outportb(DataREG,RDData); //Cho pheùp RAM.
Latch374();
lo=ReadLow();
lo=lo & 0xF0; //1111 0000: Xoaù 4 bit thaáp cuûa thanh ghi traïng thaùi.
lo=lo / 0x10; // Dòch phaûi 4 bit.
/*Ñoïc 4 bit cao*/
hi=ReadHigh();
hi=hi & 0xF0; //1111 0000: Xoaù 4 bit thaáp cuûa thanh ghi traïng thaùi.
value=hi+lo;
/* ED DD FD CB */
if ((value == 237) || (value == 221) || (value == 253) || (value == 203))
FlagM1=1;
else if ( value == CALL ) FlagM1 = CALL;
else if ( value == RET ) FlagM1 = RET;
else FlagM1=0;
outportb(DataREG,GetDebug); // Caám RAM sau khi ñoïc xong.
Latch374();
return(FlagM1);
}

/*==Chöông trình con ñoïc data töø bus, xem coù phaûi laø leänh call or ret?==*/
byte CallRet_Ins(void)

95
{
byte value,lo,hi;
/*Ñoïc 4 bit thaáp*/
outportb(DataREG,RDData); // Cho pheùp RAM.
Latch374();
lo=ReadLow();
lo=lo & 0xF0; // 1111 0000: Xoaù 4 bit thaáp cuûa thanh ghi traïng thaùi.
lo=lo / 0x10; // Dòch phaûi 4 bit.
/*Ñoïc 4 bit cao*/
hi=ReadHigh();
hi=hi & 0xF0; // 1111 0000: Xoaù 4 bit thaáp cuûa thanh ghi traïng thaùi.
value=hi+lo;
outportb(DataREG,GetDebug); //Caám RAM sau khi ñoïc xong.
Latch374();
return(value);
}

/*Chöông trình con tìm ñòa chæ trong filename.lst traû veà soá doøng töông öùng*/
int FileLst(char Lst[81],byte HiAddr,byte LoAddr)
{
FILE *fp;
byte Cont=0;
char Data;
int col=1,countLine=1;
char string[5];
char stringLo[3];
char stringHi[3];
char stringRD[5];
char strTemp[3];
stringLo[0]='0';
stringLo[1]=END_STR;
stringHi[0]='0';
stringHi[1]=END_STR;
/*Ñoåi ñ/c thaønh chuoãi kyù töï t.öùng (v.d: 0f3c)*/
string[0]=END_STR;
stringRD[0]=END_STR;
itoa(LoAddr, strTemp, 16);
if (strlen(strTemp)==1) strcat(stringLo,strTemp);
else strcpy(stringLo,strTemp);
itoa(HiAddr, strTemp, 16);
if (strlen(strTemp)==1) strcat(stringHi,strTemp);
else strcpy(stringHi,strTemp);
strcat(string,stringHi);
strcat(string,stringLo);
fp = fopen(Lst,"rt");

96
Check(fp,Lst); //Kieåm tra file coù hôïp leä khoâng?
/*Kyù töï xuoáng haøng (0x0A)
Ñoïc caùc coät 2,3,4,5 cuûa 1 haøng vaøo chuoãi.*/
while( ( fread( (char*) &Data, sizeof( Data ), 1, fp) ) && (!Cont) )
{
if (Data==0x0A) //Kyù töï keát thuùc.
{
col=1;
countLine++;
}
else
{
if ( (col>=2) && (col<=5) )//Ñoïc 5 byte ñaàu tieân cuûa 1 doøng.
{
stringRD[col-2]=Data; //Theâm kyù töï vöøa ñoïc vaøo chuoãi.
if (col==5)
{ /*So saùnh 2 chuoãi khoâng phaân bieät chöõ in vaø chöõ thöôøng*/
stringRD[4]=END_STR;
if (!stricmp(string,stringRD)) Cont=1;
else stringRD[0]=END_STR;
};
col++;
} else col++;
}
} // end while.
fclose(fp);
if (!Cont) countLine=0;
return(countLine);
}

/*==Chöông trình con ñoåi doøng thaønh ñòa chæ leänh töông öùng==*/
/*Traû veà ñòa chæ t.öùng (neáu coù), traû veà 0 neáu khoâng hôïp leä*/
int LineToAddr(char Lst[81])
{
FILE *fp;
byte Cont=0;
char Data;
unsigned col=1;
int countLine=1,lnumber=0;
char *endptr;
char stringRD[5];
stringRD[0]=END_STR;
fp = fopen(Lst,"rt");
Check(fp,Lst); //Kieåm tra file coù hôïp leä khoâng?
/*Kyù töï xuoáng haøng (0x0A)

97
Ñoïc caùc coät 2,3,4,5 cuûa 1 haøng vaøo chuoãi.*/
while( ( fread( (char*) &Data, sizeof( Data ), 1, fp) ) && (!Cont) )
{
if ( (Data==0x0A)&&(countLine != arr_bp) ) //Kyù töï keát thuùc.
{
col=1;
countLine++;
}
if (countLine==arr_bp)
{
if ( (col>=3) && (col<=6) ) //Ñoïc 4 byte, baét ñaàu töø byte 2.
{
stringRD[col-3]=Data; //Theâm kyù töï vöøa ñoïc vaøo chuoãi.
if (col==6)
{ /*So saùnh 2 chuoãi khoâng phaân bieät chöõ in vaø chöõ thöôøng*/
stringRD[4]=END_STR;
lnumber = strtoul(stringRD, &endptr, 16);
Cont=1;
};
}
col++;
}
} // end while.
fclose(fp);
return(lnumber);
}

/*==Chöông trình con caäp nhaät maøn hình==*/


void UpdateScreen(void)
{
unsigned i;
clear_screen(0,1,80,23,TEXT_ATTR);
for(i=0; i<23; i++)
print_string(0,i+1,text[win_index+i],TEXT_ATTR);
}

/**==Chöông trình con in thoâng baùo loãi neáu khoâng tìm thaáy ñ/c ôû doøng t.öùng==*/
void error_debug(void)
{
set_cursor_style(0x20,0x20);
set_attr_screen(23,11,38,4,RED_ATTR);
gotoxy(24,12); puts(" ÚÄ Ä Ä Ä Ä Ä Ä Ä Ä Ä Ä Ä¿ ");
gotoxy(24,13); puts(" ³ERROR: ³ ");
gotoxy(24,14); puts(" ³ Invalid breakpoint encountered. ³ ");
gotoxy(24,15); puts(" ÀÄ Ä Ä Ä Ä Ä Ä Ä Ä Ä Ä ÄÙ ");

98
if (getch()==0) getch();
}

/**==Chöông trình con in thoâng baùo khi baét ñaàu chaïy debug==*/
void msg_debug(void)
{
set_cursor_style(0x20,0x20);
gotoxy(24,21); puts(" ÚÄ Ä Ä Ä Ä Ä Ä Ä Ä Ä Ä Ä¿ ");
gotoxy(24,22); puts(" ³ Debugging!!! ³ ");
gotoxy(24,23); puts(" ³ Please wait! ³ ");
gotoxy(24,24); puts(“⎣ ");
}

/**==Chöông trình con in thanh coâng cuï phía döôùi maøn hình ôû mode debug==*/
void msg_toolbar(void)
{
unsigned pos;
clear_screen(20,24,60,1,MENU_ATTR);
print_string(20,24,toolbar_debug,TEXT_ATTR);//Toolbar_debug.
set_attr_screen(0,24,80,1,MENU_ATTR);
print_string(67,24,"DEBUG_MODE",0x74);
clear_screen(14,24,4,1,MENU_ATTR); //Chæ soá haøng.
clear_screen(19,24,2,1,MENU_ATTR); //Chæ soá coät.
clear_screen(18,24,1,1,MENU_ATTR); //":"
}

/*==Chöông trình con in thoâng baùo keát thuùc run & debug==*/
void msg_finish(void)
{
clear_screen(11,4,58,15,MSG_ATTR); //1E
set_cursor_style(0x20,0x20);
set_attr_screen(21,9,38,4,ROSE_ATTR);
gotoxy(22,10); puts(" ⎡");
gotoxy(22,11); puts("⏐ Finish, KIT going. ⏐ ");
gotoxy(22,12); puts("⏐ ESC-Return editor F3-Dump ⏐ ");
gotoxy(22,13); puts("⎣ ");
}

/*==Chöông trình con tìm chu kyø M1, traû veà ñ/c ñeå caáp cho Dump==*/
addr SearchM1(void)
{
byte FlagDump=0,i,k;
byte ErrorYes,BusyYes;
addr AddrDump;
/* 1. Tìm chu kyø M1 */

99
do
{
i=0;
do
{
ErrorYes=RDError();
if ( ErrorYes ) break;
delay(Set);
i++;
if ( ( i==10 ) && ( !RDError() ) ) { i=0; SetWAIT(); };
} while ( ErrorYes == 0 );
for (k=1;k<=3;k++)
{
BusyYes=RDBusy();
if ((BusyYes)&&(k>=2)) break; //Ñoïc 2 laàn ñeå choáng nhieãu
delay(Set);
};
if (BusyYes)
{
if (FlagDump) break;
}
else FlagDump=1;
SetWAIT();
} while (1);
AddrDump.lo=RD_LoAddr();
AddrDump.hi=RD_HiAddr();
return(AddrDump);
}

/*==Chöông trình con dump boä nhôù==*/


/*ñ/c nhaûy veà ñ/c nhaûy tôùi (baét ñaàu c/t dump)*/
byte Dump(byte LowAddr,byte HighAddr,byte RAddrLo,byte RAddrHi,
byte DStartLoAddr,byte DStartHiAddr,byte DEndLoAddr,byte DEndHiAddr)
/*ñ/c ñaàu boä nhôù ñ/c cuoái boä nhôù*/
{
int countTx=0;
int i,k;
byte dataDump;
byte ErrorYes,BusyYes;
byte FlagError=1,readFlag=0;
byte DisplayFlag=0;
int Hi,value;
byte valueLo,valueHi;
byte DataMemory;
unsigned Key;

100
int STT=0;
Hi=RAddrHi*256;
value=Hi+RAddrLo;
value +=0x0F; // 000F + RAddrHiRAddrLo: loop.
valueLo=value%256; // byte thaáp cuûa value.
valueHi=value/256; // byte cao cuûa value.
/* Phan 1: Xöû lyù 18 byte ñaàu tieân */
do // while ( countTx < countDump ) ( countDump=18 ).
{
countTx++;
i=0;
do
{
ErrorYes=RDError();
if ( ErrorYes ) break;
delay(Set);
i++;
if ( ( i==10 ) && ( !RDError() ) ) { i=0; SetWAIT(); }; //???
} while ( ErrorYes == 0 );
/* Neáu tröôùc ñoù coù ñöa data ra thì phaûi caám 244. */
if ( ( countTx == 2 ) || ( countTx == 3 ) || ( countTx == 4 ) ||
( countTx == 14 ) || ( countTx == 15 ) || ( countTx == 18 ) )
{
outportb(CTRLREG,InitCTRL);
delay(Set);
/* Cho pheùp RAM chung sau khi ñöa data ra */
if (( countTx == 4 )||( countTx == 15 )) EnableRAM();
};
for (k=1;k<=3;k++)
{
BusyYes=RDBusy();
if ((BusyYes)&&(k>=2)) break; //Ñoïc 2 laàn ñeå choáng nhieãu.
delay(Set);
};
/* Xöû lyù chu kyø laáy maõ leänh */
if ( BusyYes )
{
switch ( countTx )
{
case 1: SetWAITDebug(JUMP); break;
/*Caùc tröôøng hôïp ñoïc boä nhôù nhöng bò nhieãu (coù tín hieäu M1) */
case 2,3,13,14,17,18:
{
//Nhaûy veà ñaàu chöông trình
ErrorReg(LowAddr,HighAddr);

101
return(0);
}
default: SetWAIT();
}
/* Xöû lyù chu kyø ñoïc/ghi boä nhôù */
}
else // if ( BusyYes )
{
switch ( countTx )
{
case 2: SetWAITDebug(RAddrLo); break;
case 3: SetWAITDebug(RAddrHi); break;
case 13: SetWAITDebug(DEndLoAddr); break;
case 14: SetWAITDebug(DEndHiAddr); break;
case 17: SetWAITDebug(DStartLoAddr); break;
case 18: SetWAITDebug(DStartHiAddr); break;
/* byte DStartLoAddr,byte DStartHiAddr,byte DEndLoAddr,byte DEndHiAddr) */
/*ñ/c ñaàu boä nhôù ñ/c cuoái boä nhôù*/
default: SetWAIT(); // Error: Vì khoâng coù tröôøng hôïp khaùc.
}; //end switch
}; //end else
} while ( countTx < countDump ); // countDump=18.
/*Phaàn 2: xöû lyù voøng laëp (Start: 000F + RAddrHiRAddrLo)
Ñoïc maõ leänh C2, thay ñòa chæ 000F baèng ñòa chæ töông öùng (value).
Neáu coù tín hieäu error -> ñoïc data */
outportb(CTRLREG,InitCTRL);
delay(Set);
EnableRAM();
do // while (dataDump != C3)
{
do
{
ErrorYes=RDError();
if ( ErrorYes ) break;
delay(Set);
i++;
if ( ( i==10 ) && ( !RDError() ) ) { i=0; SetWAIT(); };
} while ( ErrorYes == 0 );
if ( ( readFlag==5 ) || ( readFlag==6 ) )
{
outportb(CTRLREG,InitCTRL);
delay(Set);
if (readFlag==6)
{
EnableRAM();

102
readFlag=0;
};
}
for (k=1;k<=3;k++)
{
BusyYes=RDBusy();
if ((BusyYes)&&(k>=2)) break; //Ñoïc 2 laàn ñeå choáng nhieãu.
delay(Set);
};
if ( BusyYes )
{
dataDump=CallRet_Ins(); // Ñoïc data töø bus.
if ( dataDump != 0xC3 ) // Maõ leänh JP.
{
if ( dataDump == 0x32 ) readFlag=1;
else if ( dataDump == 0xC2 ) readFlag=4;
SetWAIT();
}
else
{
SetWAIT();
break;
}
}
/* Xöû lyù chu kyø ñoïc boä nhôù */
else
{
switch (readFlag)
{
case 1: readFlag=2; SetWAIT(); break;
case 2: readFlag=3; SetWAIT(); break;
case 3:
{
if (!DisplayFlag)
{
readFlag=0;
DataMemory=ReadMem();
STT++;
if (STT>160)
{
STT=1;
Key=get_key();
while ( ( Key!=K_ENTER ) && ( Key != K_ESC ) )
{
Key=get_key();

103
};
if ( Key == K_ESC ) { DisplayFlag=1; msg_finish(); };
}
if (!DisplayFlag)
{
PrintMemory(DataMemory,STT,DStartLoAddr,DStartHiAddr);
if ( STT==1 ) STT = ( DStartLoAddr % 0x10 ) + 1;
if (DStartLoAddr == 0xFF)
{
DStartHiAddr++;
DStartLoAddr = 0x00;
}
else DStartLoAddr++;
}
SetWAIT(); break;
}
else { SetWAIT(); break; };
}
case 4: SetWAITDebug(valueLo); readFlag=5; break;
case 5: SetWAITDebug(valueHi); readFlag=6; break;
default: readFlag=0; SetWAIT();
};
} // end else
} while (1);
/* Phaàn 3: ñöa ñòa chæ trôû veà ra data bus */
do
{
ErrorYes=RDError();
if ( ErrorYes ) break;
delay(Set);
i++;
if ( ( i==10 ) && ( !RDError() ) ) { i=0; SetWAIT(); };
} while ( ErrorYes == 0 );
for (k=1;k<=3;k++)
{
BusyYes=RDBusy();
if ((BusyYes)&&(k>=2)) break; // Ñoïc 2 laàn ñeå choáng nhieãu.
delay(Set);
};
if (BusyYes)
{
ErrorReg(LowAddr,HighAddr);
return(0);
}
else SetWAITDebug(LowAddr);

104
do
{
ErrorYes=RDError();
if ( ErrorYes ) break;
delay(Set);
i++;
if ( ( i==10 ) && ( !RDError() ) ) { i=0; SetWAIT(); };
} while ( ErrorYes == 0 );
outportb(CTRLREG,InitCTRL);
delay(Set);
for (k=1;k<=3;k++)
{
BusyYes=RDBusy();
if ((BusyYes)&&(k>=2)) break; // Ñoïc 2 laàn ñeå choáng nhieãu.
delay(Set);
};
if (BusyYes)
{
ErrorReg(LowAddr,HighAddr);
return(0);
}
else SetWAITDebug(HighAddr);
outportb(CTRLREG,InitCTRL);
delay(Set);
EnableRAM();
return(FlagError);
}

/*==Chöông trình con ñoïc memory==*/


byte ReadMem(void)
{
byte value,lo,hi;
/*Ñoïc 4 bit thaáp*/
outportb(DataREG,RDREG); // Ñaët trôû laïi giaù trò ban ñaàu cho 374.
Latch374();
lo=ReadLow();
lo=lo & 0xF0; // 1111 0000: Xoaù 4 bit thaáp cuûa thanh ghi traïng thaùi.
lo=lo / 0x10; // Dòch phaûi 4 bit.
/*Ñoïc 4 bit cao*/
hi=ReadHigh();
hi=hi & 0xF0; // 1111 0000: Xoaù 4 bit thaáp cuûa thanh ghi traïng thaùi.
value=hi+lo;
delay(Set);
return(value);
}

105
/*==Chöông trình con in noäi dung memory==*/
void PrintMemory(byte DataDump,int STT,byte AddrLow,byte AddrHi)
{
set_cursor_style(0x20,0x20);
if ( STT==1 )
{
clear_screen(11,4,58,15,MSG_ATTR);
set_attr_screen(10,4,60,15,ROSE_ATTR);
Menu_Mem();
gotoxy(12,7);
if (AddrLow%16)
{
gotoxy(12,8);
printf("⏐ %02X",AddrHi);
printf("%02X ⏐ ",AddrLow-(AddrLow%16));
gotoxy(21+(3*(AddrLow%16)),8);
}
}
if ( ( AddrLow % 16 ) ) printf("%02X ",DataDump);
else
{
printf("\n ³ %02X",AddrHi);
printf("%02X ⏐ ",AddrLow);
printf("%02X ",DataDump);
}
}

/*==Chöông trình con in form==*/


void Menu_Mem(void)
{
gotoxy(11,5); puts(" ⎡ ");
gotoxy(11,6); puts("⏐ ADDR ⏐ The contents of memory ⏐ ");
gotoxy(11,7); puts(”⎡ ");
gotoxy(11,8); puts(" ⏐ ⏐ ⏐ ");
gotoxy(11,9); puts(" ⎢ ⏐ ⏐ ");
gotoxy(11,10); puts("⏐ ⏐ ⏐ ");
gotoxy(11,11); puts("⏐ ⏐ ⏐ ");
gotoxy(11,12); puts("⏐ ⏐ ⏐ ");
gotoxy(11,13); puts("⏐ ⏐ ⏐ ");
gotoxy(11,14); puts("⏐ ⏐ ⏐");
gotoxy(11,15); puts("⏐ ⏐ ⏐ ");
gotoxy(11,16); puts("⏐ ⏐ ⏐ ");
gotoxy(11,17); puts("⏐ ⏐ ⏐ ");
gotoxy(11,18); puts("⏐ ⏐ Enter - More F3 - Dump ESC - QUIT ⏐ ");

106
gotoxy(11,19); puts(“⎣");
}

/*==Chöông trình con in form nhaäp ñ.chæ (first)==*/

addr input_addr_dump_start(void)
{
addr StartAddr;
clear_screen(10,4,60,15,MSG_ATTR);
set_attr_screen(26,10,28,3,ROSE_ATTR);
set_attr_screen(45,11,4,1,HIGH_ATTR);
gotoxy(28,11); puts(“⎣ Dump⎦”);
gotoxy(28,12); puts("⏐ First address: ⏐");
gotoxy(28,13); puts (“⎣");
gotoxy(46,12);
set_cursor_style(6,7);
scanf("%4X",&StartAddr);
return (StartAddr);
}

/*==Chöông trình con in form nhaäp ñ.chæ (last)==*/


addr input_addr_dump_end(void)
{
addr EndAddr;
set_attr_screen(26,10,28,3,ROSE_ATTR);
set_attr_screen(45,11,4,1,HIGH_ATTR);
gotoxy(28,11); puts("⎡ Dump⎤”);
gotoxy(28,12); puts("⏐ Last address: ⏐");
gotoxy(28,13); puts(“⎣");
gotoxy(46,12);
set_cursor_style(6,7);
scanf("%4X",&EndAddr);
return (EndAddr);
}

/*==Chöông trình con baùo loãi ñ.chæ ñöa vaøo khoâng hôïp leä==*/
void msgError1(void)
{
clear_screen(10,4,60,15,MSG_ATTR);
set_attr_screen(26,10,28,3,RED_ATTR);
gotoxy(28,11); puts("⎡ Error ⎤");
gotoxy(28,12); puts("⏐ Address invalid. ⏐");
gotoxy(28,13); puts(“⎣");
set_cursor_style(0x20,0x20);
if (getch()==0) getch();

107
}

/*==Chöông trình con in thoâng baùo chôø trong khi xöû lyù dump memory==*/
void msgWait(void)
{
clear_screen(10,4,60,15,MSG_ATTR);
set_attr_screen(26,10,28,3,ROSE_ATTR);
gotoxy(28,11); puts("⎡Messager⎤");
gotoxy(28,12); puts("⏐ Please wait ! ⏐");
gotoxy(28,13); puts(“⎣");
set_cursor_style(0x20,0x20);
}

void ServiceCall(void)
{
byte ErrorYes,BusyYes,CycleM1;
byte j,k,InvalidM1=1,Flag=0;
do
{
j=0; // Chôø ñoïc tín hieäu ERROR.
do
{
ErrorYes=RDError(); // Ñoïc tín hieäu ERROR.
if ( ErrorYes ) break; // Neáu coù -> thoaùt.
delay(Set); // Neáu khoâng -> chôø 3 micro second.
j++; //Neáu chöa coù ERROR thì CPU coù theå ñang trong 2 case:
//1. Chu kyø I/O 2. Ñang bò treo
if ( ( j==10 ) && ( !RDError() ) ) { j=0; SetWAIT(); };
} while ( ErrorYes == 0 );
for (k=1;k<=3;k++)
{
BusyYes=RDBusy();
if ((BusyYes)&&(k>=2)) break;//Ñoïc 2 laàn ñeå choáng nhieãu
delay(Set);
};
if (BusyYes)
{
if ( InvalidM1 )
{
if (Flag) break;
CycleM1=FirstM1();
/*Ñaùnh daáu chu kyø M1 tieáp sau seõ khoâng hôïp leä*/
if ( CycleM1==1 ) InvalidM1=0;
else if (CycleM1==RET) Flag=1;
SetWAIT();

108
}
else if ( InvalidM1 == 0 )
{
InvalidM1=1;
SetWAIT();
};
}
else SetWAIT();
} while (1);
}
/*++++++++++++++++++++++++++++EOF++++++++++++++++++++++++++++*/

5.2. Chöông trình con vieát baèng ngoân ngöõ assembler Z80 duøng ñoïc
traïng thaùi caùc thanh ghi.

;StartAddr (XX XX): ñ/c giaû (thuoäc RAM chung) ñeå xuaát
Mnemonics Opcodes
======== ======
push AF ;save AF F5
push BC ;save BC C5
ld (StartAddr),A ;out A 32 XX XX
ld A,B ;out B 78
ld (StartAddr),A 32 XX XX
ld A,C ;out C 79
ld (StartAddr),A 32 XX XX
ld A,D ;out D 7A
ld (StartAddr),A 32 XX XX
ld A,E ;out E 7B
ld (StartAddr),A 32 XX XX
ld A,H ;out H 7C
ld (StartAddr),A 32 XX XX
ld A,L ;out L 7D
ld (StartAddr),A 32 XX XX
ld A,I ;out I ED 57
ld (StartAddr),A 32 XX XX
ld A,R ;out R ED 5F
ld (StartAddr),A 32 XX XX
push AF ;out F F5
pop BC C1
ld A,C 79
ld (StartAddr),A 32 XX XX
push IX ;out X DD E5
pop BC C1
ld A,C 79
109
ld (StartAddr),A 32 XX XX
ld A,B 78
ld (StartAddr),A 32 XX XX
push IY ;out Y FD E5
pop BC C1
ld A,C 79
ld (StartAddr),A 32 XX XX
ld A,B 78
ld (StartAddr),A 32 XX XX
;
ex AF,AF' ;(AF)<->(AF') 08
exx ;(BC)<->(BC') D9
;(DE)<->(DE')
;(HL)<->(HL')
push AF ;save AF' F5
push BC ;save BC' C5
ld (StartAddr),A ;out A' 32 XX XX
ld A,B ;out B' 78
ld (StartAddr),A 32 XX XX
ld A,C ;out C' 79
ld (StartAddr),A 32 XX XX
ld A,D ;out D' 7A
ld (StartAddr),A 32 XX XX
ld A,E ;out E' 7B
ld (StartAddr),A 32 XX XX
ld A,H ;out H' 7C
ld (StartAddr),A 32 XX XX
ld A,L ;out L' 7D
ld (StartAddr),A 32 XX XX
push AF ;out F' F5
pop BC C1
ld A,C 79
ld (StartAddr),A 32 XX XX
pop BC ;restore BC' C1
pop AF ;restore AF' F1
ex AF,AF' ;restore AF' 08
exx ;restore BC',DE',HL' D9
ld (StartAddr),SP
pop BC ;restore BC C1
pop AF ;restore AF F1
;
jmp Addr ;nhay ve d/c xuat phat C3 YY YY

110
5.3. Chöông trình con vieát baèng ngoân ngöõ assembler Z80 duøng dump
memory.

;Cuù phaùp: D XXXX YYYY, vôùi XXXX=1111, YYYY=FFFF


push af ;Save noäi dung caùc thanh ghi l.quan
push ix
push iy
push bc
push de
ld ix,0ffffh ;ñ/c cuoái
ld iy,1111h ;ñ/c ñaàu
loop:
ld a,(iy+00)
ld (0000h),a ;ñoïc veà PC taïi ñaây
inc iy
push iy
push ix
pop de
pop bc
ld a,c
cp e
jp nz,loop
ld a,b
cp d
jp nz,loop
pop de
pop bc
pop iy
pop ix
pop af
jp 0000h

5.4. Chöông trình taïo tieän ích soaïn thaûo vaên baûn & hoã trôï cheá ñoä
chaïy Debug Z80.
#include <errno.h>
#include <process.h>
#include <io.h>
#include <dos.h>
#include <stdio.h>
#include <conio.h>
#include <string.h>
#include "keyboard.h"

111
#include "library.c"
#include "lvtn.h"

#define MAX_X 80
#define MAX_LINE 500
#define TEXT_ATTR 0x1E
#define MENU_ATTR 0x70
#define HIGH_ATTR 0x20
#define TOGGLE_ATTR 0x5F

#define NUM_ITEM 4
//#define NUM_FUNC 4

#define DEFAULT_FILENAME "NONAME.TXT"

#define SAVE 1
#define SAVE_AS 0

char menu_bar[NUM_ITEM][10]={" File ", " Run ", " Debug ", " Help "};
char tool_bar[57]={" F1 Help F7 Trace into F8 Step over F10 Menu "};
char text[MAX_LINE][MAX_X+1];
unsigned x, y, num_line, win_index, saved;
unsigned selection1=0, selection2=0,selection3=0,selection4=0,selection5=0;
int arr_bp=0,sub_bp=0;
char file_name[64];
char string_y[5],string_x[3];
/*
File Run Debug Help
⏐ New ⏐ Run Ctrl+F9 ⏐ Toggle breakpoint Ctrl+F8 ⏐ Introduction for use
⏐ Open... F3 ⏐ Trace into F7 ⏐ Delete breakpoint all ⏐ Instruction description ⏐
⏐ Save F2 ⏐ Step over F8
⏐ Save as... ⏐ ⏐ About... ⏐

⏐ Exit Alt+X ⏐
⏐ File name: noname.txt ⏐

/*Tao MENU */
void init_menu_file(void)
{
gotoxy(3,2); puts(“⎡ ");
gotoxy(3,3); puts("⏐ New ⏐ ");
gotoxy(3,4); puts("⏐ Open... F3 ⏐ ");
gotoxy(3,5); puts("⏐ Save F2 ⏐ ");
gotoxy(3,6); puts("⏐ Save as... ⏐");
gotoxy(3,7); puts("⏐");

112
gotoxy(3,8); puts("⏐ Exit Alt+X ⏐ ");
gotoxy(3,9); puts("⎣ ");
set_attr_screen(2,1,17,8,MENU_ATTR); //Draw toolbox File
} //2,1,14,7,
/////////////////////////////////////////////////////////////////////
void init_menu_run(void)
{
gotoxy(11,2); puts (“⎡");
gotoxy(11,3); puts("⏐ Run Ctrl+F9 ⏐ ");
gotoxy(11,4); puts("⏐ Trace into F7 ⏐ ");
gotoxy(11,5); puts("⏐ Step over F8 ⏐");
gotoxy(11,6); puts("⎣ ");
set_attr_screen(10,1,20,5,MENU_ATTR); //Draw toolbox File
}
/////////////////////////////////////////////////////////////////////
void init_menu_debug(void)
{
gotoxy(18,2); puts(" ⎡");
gotoxy(18,3); puts("⏐ Toggle breakpoint Ctrl+F8 ⏐ ");
gotoxy(18,4); puts("⏐ Delete breakpoint all ⏐ ");
gotoxy(18,5); puts(" ⎣");
set_attr_screen(17,1,34,4,MENU_ATTR); //Draw toolbox File
}
/////////////////////////////////////////////////////////////////////
void init_menu_help(void)
{
gotoxy(27,2); puts(" ⎡ ");
gotoxy(27,3); puts("⏐ Introduction for use ⏐ ");
gotoxy(27,4); puts("⏐ Instruction description ⏐ ");
gotoxy(27,6); puts("⏐ About... ⏐ ");
gotoxy(27,7); puts(" ⎣”);
set_attr_screen(26,1,29,6,MENU_ATTR); //Draw toolbox File
}
/////////////////////////////////////////////////////////////////////
void new_file(void)
{
for(register i=0; i<MAX_LINE; i++) text[i][0]=0;
x=0; y=0; num_line=1; win_index=0; saved=0;
strcpy(file_name,DEFAULT_FILENAME);
} /* DEFAULT_FILENAME "NONAME.TXT" */
/////////////////////////////////////////////////////////////////////
void init_program(void)
{ /* x,y,width,hight,attr*/
unsigned po1;
clear_screen(0,0,80,1,MENU_ATTR); //Xoaù thanh ngang phía treân

113
clear_screen(0,24,80,1,MENU_ATTR); //Xoaù thanh ngang phía döôùi
new_file(); //=3
for( register i=0,x=1; i<NUM_ITEM; i++)
{
gotoxy(x+1,1); //Ñöa File Run Debug leân thanh ngang treân
puts(menu_bar[i]);
x += strlen(menu_bar[i]);
}
x=0;
print_string(22,24,tool_bar,TEXT_ATTR); //Tool_bar
set_attr_screen(0,24,80,1,MENU_ATTR);
clear_screen(14,24,4,1,MENU_ATTR); //Chæ soá haøng
itoa(win_index+y+1, string_y, 10);
pos=strlen(string_y);
print_string(18-pos,24,string_y,0x74);
clear_screen(19,24,2,1,MENU_ATTR); //Chi so cot
itoa(x+1, string_x, 10);
print_string(19,24,string_x,0x74);
clear_screen(18,24,1,1,MENU_ATTR); //":"
print_string(18,24,":",0x74);
clear_screen(0,24,13,1,MENU_ATTR);
print_string(1,24,file_name,0x74); //In filename cuoái maøn hình.
}
/////////////////////////////////////////////////////////////////////
/*===========================Doc ten file=========================*/
unsigned read_string(unsigned x, unsigned y, unsigned win_width,
unsigned max_len, unsigned attr, char s[])
{
unsigned key,len=strlen(s), cursor_pos, win_pos=0, i;
if (len+1>win_width) cursor_pos=0;
else cursor_pos=len;
set_attr_screen(x,y,win_width,1,attr);
do
{ //top, bottom
set_cursor_style(0x20,0x20);
len=strlen(s);
for( i=0; (i<win_width-1)&&(i<len); i++)
*(char far *)MK_FP(0xB800, y*160+x+x+i+i) = s[win_pos+i];
for( ; i<win_width; i++)
*(char far *)MK_FP(0xB800, y*160+x+x+i+i) = ' ';
gotoxy(x+cursor_pos+1, y+1);
set_cursor_style(6,7);
key = get_key();
switch (key)
{

114
case K_ENTER:
case K_ESC:
return key;
case K_LEFT:
if (cursor_pos>0) cursor_pos--;
else if (win_pos>0) win_pos--;
break ;
case K_RIGHT:
if ((win_pos+cursor_pos)!=len)
{
if (cursor_pos<win_width-1) cursor_pos++ ;
else if (win_pos+win_width-1<max_len) win_pos++ ;
}
break ;
case K_END:
if ((len>win_width-1)&&(len-win_pos>=win_width-1))
{
cursor_pos = win_width-1;
win_pos = len-win_width+1;
}
else cursor_pos = len-win_pos;
break ;
case K_HOME:
cursor_pos=0;
win_pos=0;
break;
case K_DEL:
for(i=cursor_pos+win_pos; i<len; i++) s[i]=s[i+1];
break ;
case K_BACK_SPACE:
if (cursor_pos+win_pos>0)
{
for(i=cursor_pos+win_pos-1; i<len; i++) s[i]=s[i+1];
if (cursor_pos==0) win_pos--;
else cursor_pos--;
}
break ;
default:
if ((key<0xFF)&&(len<max_len)&&(key!=K_ESC))
{
for(i=len+1; i>cursor_pos+win_pos; i--) s[i]=s[i-1];
s[i]=key;
if (cursor_pos==win_width-1) win_pos++;
else cursor_pos++;
}

115
break;
} //end switch
} while (1) ; //end do
}
/////////////////////////////////////////////////////////////////////
void K_UP_func(void)
{
unsigned pos;
if (y>0) y--;
else if (win_index>0)
{
win_index--;
scroll_up(0,1,80,23,TEXT_ATTR);
print_string(0,1,text[win_index],TEXT_ATTR);
}
clear_screen(14,24,4,1,MENU_ATTR);
itoa(win_index+y+1, string_y, 10);
pos=strlen(string_y);
print_string(18-pos,24,string_y,0x74);
}
/////////////////////////////////////////////////////////////////////
void K_DOWN_func(void)
{
unsigned pos;
if (win_index+y==num_line-1) return;
if (y<22) y++;
else if (win_index+23<num_line)
{
win_index++;
scroll_down(0,1,80,23,TEXT_ATTR);
if (win_index+22<num_line)
print_string(0,23,text[win_index+22],TEXT_ATTR);
}
clear_screen(14,24,4,1,MENU_ATTR);
itoa(win_index+y+1, string_y, 10);
pos=strlen(string_y);
print_string(18-pos,24,string_y,0x74);
}
/////////////////////////////////////////////////////////////////////
void K_LEFT_func(void)
{
clear_screen(19,24,2,1,MENU_ATTR);
itoa(x+1, string_x, 10);
print_string(19,24,string_x,0x74);
}

116
/////////////////////////////////////////////////////////////////////
void K_RIGHT_func(void)
{
clear_screen(19,24,2,1,MENU_ATTR);
itoa(x+1, string_x, 10);
print_string(19,24,string_x,0x74);
}
/////////////////////////////////////////////////////////////////////
void K_HOME_func(void)
{
clear_screen(19,24,2,1,MENU_ATTR);
itoa(x+1, string_x, 10);
print_string(19,24,string_x,0x74);
}
/////////////////////////////////////////////////////////////////////
void K_END_func(void)
{
clear_screen(19,24,2,1,MENU_ATTR);
itoa(x+1, string_x, 10);
print_string(19,24,string_x,0x74);
}
/////////////////////////////////////////////////////////////////////
unsigned K_DEL_func(void) {
if (x<strlen(text[win_index+y])) {
register len = strlen(text[win_index+y])-1;
for( register i=x; i<len; i++)
text[win_index+y][i]=text[win_index+y][i+1];
text[win_index+y][i]=0;
*(char far *)MK_FP(0xB800, y*160+i+i+160) = ' ';
print_string(0,y+1,text[win_index+y],TEXT_ATTR);
}
else if (win_index+y<num_line-1) {
if (x+strlen(text[win_index+y+1])>MAX_X) return 1;
else {
if (text[win_index+y+1][0]!=0) {
for(register i=strlen(text[win_index+y]); i<x; i++)
text[win_index+y][i]=' ';
memmove(text[win_index+y]+i,
text[win_index+y+1], strlen(text[win_index+y+1])+1);
}
memmove(text[win_index+y+1], text[win_index+y+2],
(num_line-1-(win_index+y+1))*(MAX_X+1));
num_line--;
text[num_line][0]=0;
print_string(x,y+1,text[win_index+y]+x,TEXT_ATTR);

117
scroll_down(0,y+2,80,22-y,TEXT_ATTR);
if (win_index+22<=num_line-1)
print_string(0,23,text[win_index+22],TEXT_ATTR);
}
}
saved=0;
return 0;
}
/////////////////////////////////////////////////////////////////////
void update_screen(void)
{
unsigned i,pos;
char string[5];
clear_screen(0,1,80,23,TEXT_ATTR);
for(i=0; i<23; i++)
print_string(0,i+1,text[win_index+i],TEXT_ATTR);
//Tam thoi set dong dau tien
if (sub_bp) set_attr_screen(0, sub_bp-win_index, 80, 1, TOGGLE_ATTR);
clear_screen(22,24,60,1,MENU_ATTR);
print_string(22,24,tool_bar,TEXT_ATTR); //Tool_bar
set_attr_screen(0,24,80,1,MENU_ATTR);
clear_screen(14,24,4,1,MENU_ATTR); //Chæ soá haøng
itoa(win_index+y+1, string_y, 10);
pos=strlen(string_y);
print_string(18-pos,24,string_y,0x74);
clear_screen(19,24,2,1,MENU_ATTR); //Chæ soá coät
itoa(x+1, string_x, 10);
print_string(19,24,string_x,0x74);
clear_screen(18,24,1,1,MENU_ATTR); //":"
print_string(18,24,":",0x74);
clear_screen(0,24,13,1,MENU_ATTR);
print_string(1,24,file_name,0x74); //In filename cuoái maøn hình.
}
/////////////////////////////////////////////////////////////////////
/*Laøm vieäc vôùi maøn hình soaïn thaûo*/
unsigned edit_text(void)
{
unsigned key, i;
update_screen();
set_cursor_style(6,7);
do
{
gotoxy(x+1,y+2); // 1, 2
key = get_key(); //Read keyboard
switch (key)

118
{ //Xöû lyù caùc phím ñieàu khieån
case K_ALT_X:
case K_F10:
return key;
case K_F1:
return key;
case K_F2:
return key;
case K_F3:
return key;
case K_F7:
return key;
case K_F8:
return key;
case K_CTRL_F9:
return key;
case K_CTRL_F8:
return key;
case K_ESC:
break;
case K_LEFT:
if (x>0) x--; K_LEFT_func(); break;
case K_RIGHT:
if (x<MAX_X-1) x++; K_RIGHT_func(); break;
case K_UP:
K_UP_func(); break;
case K_DOWN:
K_DOWN_func(); break;
case K_HOME:
x = 0; K_HOME_func(); break;
case K_END:
x = strlen(text[win_index+y]);
if (x==MAX_X) x--; K_END_func(); break;
case K_DEL:
K_DEL_func(); break;
case K_BACK_SPACE:
if (x>strlen(text[win_index+y])) x--;
else if (x>0)
{
x--;
K_DEL_func();
}
else if (win_index+y!=0)
{
K_UP_func();

119
x = strlen(text[win_index+y]);
if (K_DEL_func()!=0)
{
x = 0;
K_DOWN_func();
}
}
break;
case K_PAGEUP:
if (win_index!=0)
{
if (win_index<22) win_index=y=0;
else win_index-=22;
update_screen();
}
else y=0;
break;
case K_PAGEDOWN:
if (win_index+22>num_line-1) win_index=num_line-1;
else (win_index+=22);
if (win_index+y>num_line-1) y=num_line-1-win_index;
update_screen();
break;
case K_ENTER:
if (win_index+y<MAX_LINE-1)
{
saved=0;
if (num_line-1>win_index+y)
memmove(text[win_index+y+2], text[win_index+y+1], (MAX_X+1)*(num_line-win_index-
y-1));
scroll_up(0,y+2,80,22-y,TEXT_ATTR);
if (strlen(text[win_index+y])<=x)
text[win_index+y+1][0]=0;
else
{
strcpy(text[win_index+y+1],text[win_index+y]+x);
text[win_index+y][x]=0;
for(i=x; i<MAX_X; i++)
*(char far *)MK_FP(0xB800, y*160+i+i+160) = ' ';
if (y<22) print_string(0,y+2,text[win_index+y+1],TEXT_ATTR);
}
num_line++;
x = 0;
K_DOWN_func();
}

120
break;
default: //Xöû lyù caùc phím kyù töï
if ((key&0xFF)==0) break;
if ((key&0xFF)=='\t') key=' ';
register len=strlen(text[win_index+y]);
if (len<x)
{
saved=0;
*(char far *)MK_FP(0xB800, y*160+x+x+160) = key;
memset(text[win_index+y]+len,' ',x-len);
text[win_index+y][x]=key;
text[win_index+y][x+1]=0;
if (x<MAX_X-1) x++;
}
else if (len<MAX_X)
{
saved=0;
text[win_index+y][strlen(text[win_index+y])+1]=0;
for(i=strlen(text[win_index+y]); i>x; i--)
{
text[win_index+y][i]=text[win_index+y][i-1];
*(char far *)MK_FP(0xB800, y*160+i+i+160) = text[win_index+y][i];
}
text[win_index+y][x]=key;
*(char far *)MK_FP(0xB800, y*160+x+x+160) = key;
if (x<MAX_X-1) x++;
}
break;
} //end switch
} while (1); //end do
}
/////////////////////////////////////////////////////////////////////
unsigned input_file_name(void) {
char str[64];
strcpy(str,file_name);
set_attr_screen(24,11,32,3,0x5F);
gotoxy(25,12); puts("⎡Open a File⎤");
gotoxy(25,13); puts("⏐ File name: ⏐");
if (read_string(40,12,14,60,0x5F,str)==K_ESC) return 1;
strcpy(file_name,str);
return 0;
}
/////////////////////////////////////////////////////////////////////
unsigned save_file_name(void) {
char str[64];

121
strcpy(str,file_name);
set_attr_screen(24,11,32,3,0x5F);
gotoxy(25,12); puts (“Save File As ");
gotoxy(25,13); puts("⏐ File name: ⏐");
if (read_string(40,12,14,60,0x5F,str)==K_ESC) return 1;
strcpy(file_name,str);
return 0;
}
/////////////////////////////////////////////////////////////////////
void open_error(void) {
set_cursor_style(0x20,0x20);
set_attr_screen(23,11,33,3,0x4F);
gotoxy(24,12); puts(“ ⎡Error ⎤");
gotoxy(24,13); puts("⏐ Can not open file ! ⏐ ");
if (getch()==0) getch();
}
/////////////////////////////////////////////////////////////////////
unsigned overwrite_file(void) {
unsigned key;
set_cursor_style(0x20,0x20);
set_attr_screen(14,11,50,3,0x4F);
gotoxy(15,12); puts("⎡Message⎤”);
gotoxy(15,13); puts("⏐ File is already exist. Overwrite (Y/N) ⏐ ");
do key=get_key();
while ((key!='Y')&&(key!='y')&&(key!='N')&&(key!='n'));
if ((key=='Y')||(key=='y')) return 1;
else return 0;
}
/////////////////////////////////////////////////////////////////////
void error_filename(void)
{
set_cursor_style(0x20,0x20);
set_attr_screen(23,11,38,4,0x4F);
gotoxy(24,13); puts("⏐ ERROR: ⏐");
gotoxy(24,14); puts("⏐ Filename may be: filename.asm ⏐ ");
if (getch()==0) getch();
}
/////////////////////////////////////////////////////////////////////
void open(void)
{
FILE *fptr;
char str[64];
strcpy(tr,file_name);
if (input_file_name()!=0) return;
strupr(file_name); //Ñoåi teân file thaønh chöõ hoa

122
fptr = fopen(file_name,"rt");
if (fptr!=NULL)
{ //MAX_LINE=500, MAX_X=80
for(register i=0; i<MAX_LINE; i++) text[i][0]=0;
i=0;
fgets(text[i],MAX_X,fptr);
while (!feof(fptr))
{
text[i][strlen(text[i])-1]=0;
i++;
fgets(text[i],MAX_X,fptr);
}
num_line=i+1;
for(i=0; i<num_line; i++)
for(register j=0; j<MAX_X; j++)
if (text[i][j]=='\t') text[i][j]=' ';
fclose(fptr);
x=y=win_index=0;
saved=1;
}
else
{
open_error();
strcpy(file_name,str);
}
}
/////////////////////////////////////////////////////////////////////
void save(unsigned option) {
FILE *fptr;
char str[64];
strcpy(str,file_name);
if ((option==SAVE_AS)||(strcmp(file_name,DEFAULT_FILENAME)==0)) {
if (save_file_name()!=0) return;
if (access(file_name,0)==0) if (overwrite_file()==0) {
strcpy(file_name,str);
return;
}
}
strupr(file_name); //Ñoåi teân file thaønh chöõ hoa
fptr = fopen(file_name,"wt");
if (fptr!=NULL) {
fputs(text[0], fptr);
for(register i=1; i<num_line; i++) {
fputc('\n',fptr);
fputs(text[i], fptr);

123
}
fclose(fptr);
saved=1;
}
else {
open_error();
strcpy(file_name,str);
}
}
/////////////////////////////////////////////////////////////////////
void spawnle_example(void)
{
int result;
result = spawnle(P_WAIT, "dz80.exe", NULL, NULL);
if (result == -1)
{
perror("Error from spawnle");
exit(1);
}
}
/////////////////////////////////////////////////////////////////////
/*==Dich, dua chuong trinh ra RAM chung & Run==*/
void run(void)
{
int n;
char tenfile[64];
//Goi dz80
spawnle_example();
update_screen();
clear_screen(0,0,80,1,MENU_ATTR); //Xoaù thanh ngang phía treân
for( register i=0,x=1; i<NUM_ITEM; i++)
{
gotoxy(x+1,1); //Ñöa File Run Debug leân thanh ngang treân
puts(menu_bar[i]);
x += strlen(menu_bar[i]);
}
//Tim chuoi ".asm" trong filename, AddPoint -> '.' (neáu tìm thaáy)
if (strstr(file_name,".ASM")==NULL) error_filename();
else
{
//Thay file.asm (file_name) = file.bin
n=strlen(file_name);
memcpy(tenfile,file_name,n-3);
tenfile[n-3]=0X00;
strcat(tenfile,"bin");

124
main1(tenfile,2,0);
//Sau khi thöïc hieän xong main 1 phaûi traû laïi maøn hình cuõ
}
}
/////////////////////////////////////////////////////////////////////
/*==Dòch, ñöa chöông trình ra RAM chung & Debug==*/
void debug(int key)
{
int n;
char tenfile[64];
//Goi dz80
spawnle_example();
update_screen();
clear_screen(0,0,80,1,MENU_ATTR); //Xoaù thanh ngang phía treân
for( register i=0,x=1; i<NUM_ITEM; i++)
{
gotoxy(x+1,1); //Ñöa File Run Debug leân thanh ngang treân
puts(menu_bar[i]);
x += strlen(menu_bar[i]);
}
//Tim chuoi ".asm" trong filename, AddPoint -> '.' (neáu tìm thaáy)
if (strstr(file_name,".ASM")==NULL) error_filename();
else
{
//Thay file.asm (file_name) = file.bin
n=strlen(file_name);
memcpy(tenfile,file_name,n-3);
tenfile[n-3]=0X00;
strcat(tenfile,"bin");
main1(tenfile,1,key);
}
}
/////////////////////////////////////////////////////////////////////
unsigned main_menu(void)
{
unsigned key;
set_cursor_style(0x20,0x20);
do
{
for(register i=0,x=1; i<selection1; i++) x+=strlen(menu_bar[i]);
set_attr_screen(x+1, 0, strlen(menu_bar[selection1])-2, 1, HIGH_ATTR);
key = get_key();
if ((key==K_DOWN)&&(selection1==0)) key=K_ENTER;
if ((key==K_ENTER)||(key==K_ESC)||(key==K_ALT_X)||
(key==K_F1)||(key==K_F2)||(key==K_F3) ||(key==K_CTRL_F9)||

125
(key==K_F7)||(key==K_F8)||(key==K_CTRL_F8) ) return key;
set_attr_screen(x+1, 0, strlen(menu_bar[selection1])-2, 1, MENU_ATTR);
if (key==K_LEFT)
if (selection1==0) selection1=NUM_ITEM-1;
else selection1--;
else if (key==K_RIGHT)
if (selection1==NUM_ITEM-1) selection1=0 ;
else selection1++;
} while (1);
}
/////////////////////////////////////////////////////////////////////
/*==Xöû lyù caùc phím: Enter, Esc, Alt_x, muõi teân leân, muõi teân xuoáng==*/
unsigned menu_file(void)
{
unsigned key;
init_menu_file();
do
{
set_attr_screen(4,selection2+2,13,1,HIGH_ATTR);
key = get_key();
if ((key==K_ENTER)||(key==K_ESC)||(key==K_ALT_X)||(key==K_LEFT)||
(key==K_F7)||(key==K_F8) ||(key==K_CTRL_F9)||(key==K_RIGHT)||
(key==K_F1)||(key==K_F2)||(key==K_F3)||(key==K_CTRL_F8) ) break;
set_attr_screen(4,selection2+2,13,1,MENU_ATTR);
if (key==K_UP)
if (selection2==0) selection2=5;
else if (selection2==5) selection2=3;
else selection2--;
else if (key==K_DOWN)
if (selection2==5) selection2=0 ;
else if (selection2==3) selection2=5;
else selection2++;
} while (1);
update_screen();
return key;
}
/////////////////////////////////////////////////////////////////////
unsigned menu_run(void)
{
unsigned key;
init_menu_run();
do
{
set_attr_screen(12,selection3+2,16,1,HIGH_ATTR);
key = get_key();

126
if ((key==K_ENTER)||(key==K_ESC)||(key==K_ALT_X)||(key==K_LEFT)||
(key==K_F1)||(key==K_F2)||(key==K_F3) ||(key==K_CTRL_F9)||
(key==K_RIGHT)||(key==K_F7)||(key==K_F8)||(key==K_CTRL_F8) ) break;
set_attr_screen(12,selection3+2,16,1,MENU_ATTR);

if (key==K_UP)
if (selection3==0) selection3=2;
else selection3--;
else if (key==K_DOWN)
if (selection3==2) selection3=0 ;
else selection3++;
} while (1);
update_screen();
return key;
}
/////////////////////////////////////////////////////////////////////
unsigned menu_debug(void)
{
unsigned key;
init_menu_debug();
do
{
set_attr_screen(19,selection4+2,30,1,HIGH_ATTR);
key = get_key();
if ((key==K_ENTER)||(key==K_ESC)||(key==K_ALT_X)||(key==K_LEFT)||
(key==K_F7)||(key==K_F8) ||(key==K_CTRL_F9)||(key==K_RIGHT)||
(key==K_F1)||(key==K_F2)||(key==K_F3)||(key==K_CTRL_F8) ) break;
set_attr_screen(19,selection4+2,30,1,MENU_ATTR);
if (key==K_UP)
if (selection4==0) selection4=1;
else selection4--;
else if (key==K_DOWN)
if (selection4==1) selection4=0 ;
else selection4++;
} while (1);
update_screen();
return key;
}
/////////////////////////////////////////////////////////////////////
unsigned menu_help(void)
{
unsigned key;
init_menu_help();
do
{

127
set_attr_screen(28,selection5+2,25,1,HIGH_ATTR);
key = get_key();
if ((key==K_ENTER)||(key==K_ESC)||(key==K_ALT_X)||(key==K_LEFT)||
(key==K_F7)||(key==K_F8) ||(key==K_CTRL_F9)||(key==K_RIGHT)||
(key==K_F1)||(key==K_F2)||(key==K_F3)||(key==K_CTRL_F8) ) break;
set_attr_screen(28,selection5+2,25,1,MENU_ATTR);
if (key==K_UP)
if (selection5==0) selection5=3;
else if (selection5==3) selection5=1;
else selection5--;
else if (key==K_DOWN)
if (selection5==3) selection5=0 ;
else if (selection5==1) selection5=3;
else selection5++;
} while (1);
update_screen();
return key;
}
/////////////////////////////////////////////////////////////////////
void conv_attr(unsigned order_menu)
{
for(register i=0,x=1; i<selection1; i++) x+=strlen(menu_bar[i]);
set_attr_screen(x+1, 0, strlen(menu_bar[selection1])-2, 1, HIGH_ATTR);
for(i=0,x=1; i<order_menu; i++) x+=strlen(menu_bar[i]);
set_attr_screen(x+1, 0, strlen(menu_bar[order_menu])-2, 1, MENU_ATTR);
}
/////////////////////////////////////////////////////////////////////
void toggle(void)
{
int sub_arr_bp;
if (win_index+y+1 == sub_bp)
{
set_attr_screen(0, y+1, 80, 1, TEXT_ATTR);
arr_bp=0;
sub_bp=0;
}
else
{
set_attr_screen(0, y+1, 80, 1, TOGGLE_ATTR);
arr_bp=win_index+y+1; //traû veà soá doøng treân file *.asm
sub_bp=win_index+y+1;
sub_arr_bp=(arr_bp-1)/60*2;
arr_bp=arr_bp+sub_arr_bp; //Doøng t.öùng trong file *.lst
//*.asm -> *.lst: line=line+(line-1)/60*2
}

128
}
/////////////////////////////////////////////////////////////////////
void About(void)
{
set_cursor_style(0x20,0x20);
set_attr_screen(21,6,38,14,0x5F);
set_attr_screen(36,18,8,1,MENU_ATTR);
gotoxy(22,7); puts (“ ⎡About ⎤");
gotoxy(22,8); puts("⏐ Truong Dai Hoc Ky Thuat. ⏐ ");
gotoxy(22,9); puts("⏐ Khoa cong nghe thong tin. ⏐ ");
gotoxy(22,10); puts("⏐ ⏐ ");
gotoxy(22,11); puts("⏐ LUAN VAN TOT NGHIEP ⏐ ");
gotoxy(22,12); puts("⏐ ⏐ ");
gotoxy(22,13); puts("⏐ Giao vien huong dan: ⏐ ");
gotoxy(22,14); puts("⏐ Thay Nguyen Xuan Minh. ⏐ ");
gotoxy(22,15); puts("⏐ Sinh vien thuc hien: ⏐ ");
gotoxy(22,16); puts("⏐ Luu Dinh Dung. ⏐ ");
gotoxy(22,17); puts("⏐ Hoang Le Binh. ⏐ ");
gotoxy(22,18); puts("⏐ Lop: KSII-K6-T. ⏐ ");
gotoxy(22,19); puts("⏐ OK ⏐ ");
if (getch()==0) getch();
}
/////////////////////////////////////////////////////////////////////
void Instruction(void)
{
unsigned count_line=0,phim;
char help_text[81];//Nho hon 80
FILE *fp;
fp = fopen("help.hlp","rt");
if (fp!=NULL)
{
set_cursor_style(0x20,0x20);
clear_screen(1,1,78,22,0x5F);
gotoxy(4,2); puts(" Instruction Z80 ");
gotoxy(4,24); puts(" Enter - More ESC - Exit ");
set_attr_screen(1,1,78,1,0x4F);
set_attr_screen(1,23,78,1,0x4F);
while ( !feof(fp) )
{
if (count_line==20)
{
phim=get_key();
while ( ( phim != K_ENTER ) && ( phim != K_ESC ) ) phim=get_key();
if (phim==K_ESC) break;
else count_line=0;

129
clear_screen(1,2,76,20,0x5F);
}
fgets(help_text,80,fp);
print_string(2,count_line+2,help_text,0x5F);
count_line++;
}
fclose(fp);
}
else
{
set_cursor_style(0x20,0x20);
set_attr_screen(23,11,33,3,0x4F);
gotoxy(24,12); puts("⎡Error⎤”);
gotoxy(24,13); puts("⏐ Can not open file help.hlp! ⏐ ");
if (getch()==0) getch();
}
// phim=get_key();
while ( phim != K_ESC ) phim=get_key();
update_screen();
}
/////////////////////////////////////////////////////////////////////
void Intro(void)
{
set_cursor_style(0x20,0x20);
set_attr_screen(21,6,38,14,0x5F);
set_attr_screen(36,18,8,1,MENU_ATTR);
gotoxy(22,7); puts("⎡Trouble shootting⎤");
gotoxy(22,8); puts("⏐ 1. Ram 's fail: Replace. ⏐ ");
gotoxy(22,9); puts("⏐ 2. Power off: Power on. ⏐ ");
gotoxy(22,10); puts("⏐ 3. Jack 25 pin: ⏐ ");
gotoxy(22,11); puts("⏐ - Check jack 25 or connect to PC. ⏐ ");
gotoxy(22,12); puts("⏐ 4. File 's too long: ⏐ ");
gotoxy(22,13); puts("⏐ - File (*.bin) may be < 32Kb. ⏐ ");
gotoxy(22,14); puts("⏐ 5. Hard wave error: ⏐ ");
gotoxy(22,15); puts("⏐ - Check 74LS: 157,244,374,8255... ⏐ ");
gotoxy(22,16); puts("⏐ 6. Invalid breakpoint: ⏐ ");
gotoxy(22,17); puts("⏐ - Set breakpoint again. ⏐ ");
gotoxy(22,18); puts("⏐ - Possible is incorrect. ⏐ ");
gotoxy(22,19); puts("⏐ OK ⏐ ");
if (getch()==0) getch();
}
/////////////////////////////////////////////////////////////////////
void delToggle(void)
{
set_attr_screen(0, 1, 80, 23, TEXT_ATTR);

130
arr_bp=0;
sub_bp=0;
}
/////////////////////////////////////////////////////////////////////
unsigned func_func(unsigned key)
{
switch (key)
{
case K_F1: About(); return (1);
case K_F2: save(SAVE); return (1);
case K_F3: open(); return (1);
case K_F7: debug(K_F7); return (1);
case K_F8: debug(K_F8); return (1);
case K_CTRL_F8: toggle(); return (1);
case K_CTRL_F9: run(); return (1);
case K_ESC: return (1);
default: return 0;
}
}
////////////////////////////////////////////////////////////////////
void main(void)
{
unsigned key,pos;
int number;
init_program();
do
{
set_attr_screen(0,0,80,1,MENU_ATTR);
//Xu ly trong man hinh soan thao
key = edit_text(); //return F10
if (key==K_ALT_X) break; //Alt + X = Exit
if ( !(func_func(key) ) )
{
key = main_menu();
if (key==K_ALT_X) break;
if ( !(func_func(key) ) )
if (key==K_ENTER) //(1)
{
do
{
if (selection1==0) //Select File menu
{
key = menu_file();
if (key==K_ALT_X) break;
else if (key==K_RIGHT) selection1=1;

131
else if (key==K_LEFT) selection1=3;
conv_attr(0);
}
else if (selection1==1)
{
key = menu_run();
if (key==K_ALT_X) break;
else if (key==K_LEFT) selection1=0;
else if (key==K_RIGHT) selection1=2;
conv_attr(1);
}
else if (selection1==2)
{
key = menu_debug();
if (key==K_ALT_X) break;
else if (key==K_LEFT) selection1=1;
else if (key==K_RIGHT) selection1=3;
conv_attr(2);
}
else if (selection1==3)
{
key = menu_help();
if (key==K_ALT_X) break;
else if (key==K_LEFT) selection1=2;
else if (key==K_RIGHT) selection1=0;
conv_attr(3);
}
} while ( (!(key == K_ENTER)) && ( !(func_func(key)) ) );
if (key==K_ENTER) //(2)
{
if (selection1==0)
{
if (selection2==5) break;
else if (selection2==0) new_file();
else if (selection2==1) open();
else if (selection2==2) save(SAVE);
else save(SAVE_AS);
}
else if (selection1==1)
{
if (selection3==0) run();
else if (selection3==1) debug(K_F7);
else if (selection3==2) debug(K_F8);
}
else if (selection1==2)

132
{
if (selection4==0) toggle();
else if (selection4==1) delToggle();
}
else if (selection1==3)
{
if (selection5==0) Intro();
else if (selection5==1) Instruction();
else if (selection5==3) About();
}
} //end if (key==K_ENTER) (2)
} //end if (key==K_ENTER) (1)
} //end if (!(func_func()))
} while (1);
clear_screen(0,0,80,25,0x07);
gotoxy(1,1);
set_cursor_style(6,7);
}
/*========================END OF FILE==========================*/

5.5. Caùc chöông trình ví duï.

5.5.1. Chöông trình ví duï No.1.

; Ñoïc traïng thaùi SW.


; Xuaát traïng thaùi töông öùng ra LED.
; Ngöôøi vieát: Löu Ñình Duõng.
; Ngaøy vieát: 11/03/1999.
; Caäp nhaät laàn cuoái:09/07/1999.

org 0000h
ld sp,0fe00h
start:
in a,(04h)
out (00h),a
jp start
;================= End of file ====================

5.5.2. Chöông trình ví duï No.2.

; Load data vao RAM töøØ baûng.


; Xuaát data töø RAM ra LED.
; Xuaát data töø baûng ra LED.
; Ngöôøi vieát: Löu Ñình Duõng.
133
; Ngaøy vieát: 11/03/1999.
; Caäp nhaät laàn cuoái: 09/07/1999.

org 0000h
start:
;Set giaù trò ban ñaàu cho Stack
ld sp,0fe00h
;Naïp caùc baûng vaøo RAM
ld ix,8000h
ld b,01h
loop:
ld a,b
;
cp 01h
jp z,sw001 ;Neáu a=01h, nhaûy ñeán sw001

cp 02h
jp z,sw002

cp 03h
jp z,sw003

cp 04h
jp z,sw004

cp 05h
jp z,sw005

cp 06h
jp z,sw006

cp 07h
jp z,sw007

cp 08h
jp z,sw008

jp start1

;
sw001:
inc b
ld hl,table1
jp loop02
sw002:

134
inc b
ld hl,table2
jp loop02
sw003:
inc b
ld hl,table3
jp loop03
sw004:
inc b
ld hl,table4
jp loop03
sw005:
inc b
ld hl,table5
jp loop02
sw006:
inc b
ld hl,table6
jp loop02
sw007:
inc b
ld hl,table7
jp loop02
sw008:
inc b
ld hl,table8
jp loop04
;
loop02:
ld d,08h
jp loop01
loop03:
ld d,0ah
jp loop01
loop04:
ld d,10h
; jp loop01
loop01:
ld a,(hl)
ld (ix+00h),a
inc ix
inc hl
dec d
jp nz,loop01
jp loop

135
;
start1:
ld iy,8000h
start2:
ld a,(iy+00)
out (00h),a
call delay
;
loop00:
in a,(04h)
;
cp 0feh ;1111 1110
jp z,sw1
;
cp 0fdh ;1111 1101
jp z,sw2
;
cp 0fbh ;1111 1011
jp z,sw3
;
cp 0f7h ;1111 0111
jp z,sw4
;
cp 0efh ;1110 1111
jp z,sw5
;
cp 0dfh ;1101 1111
jp z,sw6
;
cp 0bfh ;1011 1111
jp z,sw7
;
cp 7fh ;0111 1111
jp z,sw8
;
; jp start1
;
inc iy
push iy
push ix
pop de ; ld de,ix
pop bc ; ld bc,iy
ld a,c ; so saùnh ix & iy (cho iy chæ tôùi ix max)
cp e ; (giaù trò lôùn nhaát naïp vaøo RAM)
jp nz,start2

136
ld a,b
cp d
jp nz,start2
jp start1
;
sw1:
ld hl,table1
jp sw00
;
sw2:
ld hl,table2
jp sw00
;
sw3:
ld hl,table3
jp sw02
;
sw4:
ld hl,table4
jp sw02
;
sw5:
ld hl,table5
jp sw00
;
sw6:
ld hl,table6
jp sw00
;
sw7:
ld hl,table7
jp sw00
;
sw8:
ld hl,table8
jp sw03
;
sw00:
ld b,8
jp sw01
;
sw02:
ld b,0ah
jp sw01
;

137
sw03:
ld b,10h
; jp sw01
;
sw01:
ld a,(hl)
out (00h),a
call delay
inc hl
dec b
jp nz,sw01
;
jp loop00
;
table1:
db 0feh ;1111 1110
db 0fdh ;1111 1101
db 0fbh ;1111 1011
db 0f7h ;1111 0111
db 0efh ;1110 1111
db 0dfh ;1101 1111
db 0bfh ;1011 1111
db 7fh ;0111 1111
;
table2:
db 7fh ;0111 1111
db 0bfh ;1011 1111
db 0dfh ;1101 1111
db 0efh ;1110 1111
db 0f7h ;1111 0111
db 0fbh ;1111 1011
db 0fdh ;1111 1101
db 0feh ;1111 1110
;
table3:
db 0ffh ;1111 1111
db 0e7h ;1110 0111
db 0c3h ;1100 0011
db 81h ;1000 0001
db 00h ;0000 0000
db 0ffh ;1111 1111
db 0e7h ;1110 0111
db 0c3h ;1100 0011
db 81h ;1000 0001
db 00h ;0000 0000

138
;
table4:
db 00h ;0000 0000
db 81h ;1000 0001
db 0c3h ;1100 0011
db 0e7h ;1110 0111
db 0ffh ;1111 1111
db 00h ;0000 0000
db 81h ;1000 0001
db 0c3h ;1100 0011
db 0e7h ;1110 0111
db 0ffh ;1111 1111
;
table5:
db 0aah ;1010 1010
db 55h ;0101 0101
db 0aah ;1010 1010
db 55h ;0101 0101
db 0aah ;1010 1010
db 55h ;0101 0101
db 0aah ;1010 1010
db 55h ;0101 0101
;
table6:
db 7fh ;0111 1111
db 3fh ;0011 1111
db 1fh ;0001 1111
db 0fh ;0000 1111
db 07h ;0000 0111
db 03h ;0000 0011
db 01h ;0000 0001
db 00h ;0000 0000
;
table7:
db 0feh ;1111 1110
db 0fch ;1111 1100
db 0f8h ;1111 1000
db 0f0h ;1111 0000
db 0e0h ;1110 0000
db 0c0h ;1100 0000
db 80h ;1000 0000
db 00h ;0000 0000
;
table8:
db 0ffh ;1111 1111

139
db 7fh ;0111 1111
db 3fh ;0011 1111
db 0bfh ;1011 1111
db 1fh ;0001 1111
db 0dfh ;1101 1111
db 0fh ;0000 1111
db 0efh ;1110 1111
db 07h ;0000 0111
db 0f7h ;1111 0111
db 03h ;0000 0011
db 0fbh ;1111 1011
db 01h ;0000 0001
db 0fdh ;1111 1101
db 00h ;0000 0000
db 0feh ;1111 1110
;
delay:
push hl ;3M, 11T
ld d,0fh ;2M, 7T
delay01:
ld e,0fh ;2M, 7T
delay001:
ld h,0fh ;2M, 7T
delay002:
ld l,0fh ;2M, 7T
;
delay003:
dec l ;1M, 4T
jr nz,delay003 ;2M, 7T
;
dec h ;1M, 4T
jr nz,delay002 ;2M,7T
;
dec e ;1M, 4T
jr nz,delay001 ;2M, 7T
;
dec d ;1M, 4T
jr nz,delay01 ;2M, 7T
;
pop hl ;3M, 10T
ret ;3M, 10T
;
; T1 = 11*15 = 165
; T2 = ( 18+T1 ) * 15 = ( 18+165 ) * 15 = 183 * 15 = 2745
; T3 = ( 18+T2 ) * 15 = ( 18+2745 ) * 15 = 2763 * 15 = 41445

140
; T4 = ( 18+T3 ) * 15 = ( 18+41445 ) * 15 = 41463 * 15 = 621945
; T5 = T4+59 = 621945+59 = 622004
; T (Thôøi gian delay) = T5/2.4576 (uS) = 253094(uS) = 0.253 (S)
; T = 1/4 (S)
;
;================= End of file ====================

WX WX

141
Phuï luïc A

Caùc thoâng baùo loãi.


Caùc loaïi loãi coù theå coù khi chaïy chöông trình ôû mode Debug vaø Run:
1. File coù phaàn môû roäng .asm chöa ñöôïc môû.
2. Nhaäp khoâng ñuùng teân cuûa file ñang ñöôïc môû khi coù yeâu caàu nhaäp teân file töø chöông trình dòch
(Chuù yù: khoâng nhaäp phaàn môû roäng).
3. Thieáu file coù phaàn môû roäng .lst khi chaïy chöông trình ôû cheá ñoä Debug (Chuù yù: nhaäp ‘Y’ khi coù
thoâng baùo taïo file listing khi dòch chöông trình).
4. Chöa caáp nguoàn +5V cho KIT.
5. Phaàn cöùng coù vaán ñeà:
a. Coù byte trong vuøng RAM chung hö.
b. Chöa caém Jack 25 pin.
c. Caùc IC 8255, 74LS157, 74LS244, 74LS374, 74LS74, 74LS04 coù söï coá.
6. Nguoàn +5V bò maát ñoät ngoät trong khi chöông trình ñang chaïy.
7. File *.bin quaù lôùn (>32 Kb).
Caùc loaïi loãi treân seõ ñöôïc thoâng baùo leân maøn hình (neáu coù).

Chuù yù: Trong khi thöïc hieän phaûi chaéc raèng KIT Z80 ñang ñöôïc caáp nguoàn +5V.

WX WX

142
Phuï luïc B

Vi maïch 8255
Vi maïch 8255 thöôøng hay ñöôïc söû duïng trong vieäc xuaát vaø nhaäp döõ lieäu soá, trong vieäc ñieàu
khieån quaù trình bieán ñoåi A/D. 8255 coù 24 ñöôøng xuaát nhaäp ñöôïc xeáp thaønh 3 coång song song
(coång A, B vaøC).

Tính linh hoaït cuûa vi maïch naøy theå hieän ôû khaû naêng laäp trình. Qua moät thanh ghi ñieàu khieån,
ngöôøi söû duïng xaùc ñònh loaïi hoaït ñoäng vaø coång naøo caàn ñöôïc söû duïng nhö laø loái ra hoaëc loái vaøo.
Ñöôøng data 2 chieàu D0 - D7 roäng 8 bits. Taát caû caùc döõ lieäu khi truy xuaát ghi hoaëc ñoïc ñöôïïc daãn
qua caùc ñöôøng daãn naøy. Traïng thaùi logic ghi/ñoïc ñöôïc nhaän bieát qua caùc tín hieäu ñieàu khieån /CS,
/RD, /WR. Khi /CS = '0', /RD = '0' caùc tín hieäu cuûa coång ñöôïc löïïa choïn ñöôïc daãn ñeán data bus.
Khi /CS = '0', /WR = 0 moïi vieäc xaûy ra ngöôïc laïi. Caùc bit ñòa chæ A0 vaø A1 cuøng vôùi caùc tín hieäu
ghi vaø ñoïc baùo hieäu cho bieát seõ truy nhaäp leân coång naøo.
Baûng söï thaät döôùi ñaây toùm taêt caùc keát luaän vöøa môùi trình baøy ôû treân:

A1 A0 /RD /WR /CS Chöùc naêng


0 0 0 1 0 Port A => Data bus
0 1 0 1 0 Port B => Data bus
1 0 0 1 0 Port C => Data bus
0 0 1 0 0 Data bus => Port A
0 1 1 0 0 Data bus => Port B
1 0 1 0 0 Data bus => Port C
1 1 1 0 0 Ghi töø ñieàu khieån
X X X X 1 Data bus ôû traïng thaùi HiZ
X X 1 1 0 Data bus ôû traïng thaùi HiZ

Trong moät chu trình ghi leân thanh ghi ñieàu khieån, ngöôøi söû duïng khaúng ñònh coång vaøo/ ra cuõng
nhö kieåu hoaït ñoäng trong moät töø ñieàu khieån. Moät möùc logic '1' ôû chaân RESET ñaët trôû laïi thanh ghi
ñieàu khieån vaø ñònh nghiaõ toaøn boä 24 ñRôøng daãn nhö laø caùc loái vaøo. Söï saép xeáp cuûa töø ñieàu khieån
ñöôïc moâ taû treân hình sau:

143
D7 D6 D5 D4 D3 D2 D1 D0
Nhoùm B
Coång C
1 = in
0 = out
Coång B
1 = in
0 = out
Mode
1 = Mode 1
0 = Mode 0

Nhoùm A
Coång C
1 = in
0 = out
Coång A
1 = in
0 = out
Mode
00 = Mode 0
01 = Mode 1
0X = Mode 2

Mode - Flag
1 = Active

Söï saép xeáp cuûa töø ñieàu khieån ôû vi maïch 8255.

Ta thaáy 24 ñöôøng daãn cuûa caùc coång A, B, C ñöôïc phaân chia thaønh 2 nhoùm. Trong ñoù 1 nöûa cuûa
coång C (PC4...PC7) thuoäc vaøo nhoùm A, coøn nöûa kia thuoäc nhoùm B. Toång coäng ngöôøi söû duïng coù 3
kieåu hoaït ñoäng khaùc nhau. Mode 0, mode 1, mode 2.
Mode 0: Xuaát vaø nhaäp döõ lieäu theo caùch ñôn giaûn qua PA, PB, PC.
Ta seõ khoâng ñeà caäp tôùi mode 1 vaø mode 2.

WX WX

144
Taøi lieäu tham khaûo.
[1] Ngoâ Dieân Taäp, Ño löôøng vaø ñieàu khieån baèng maùy tính.
Nhaø xuaát baûn khoa hoïc vaø kyõ thuaät - 1996.

[2] Leâ Vaên Vieät, Caáu truùc maùy tính.


Nhaø xuaát baûn Ñoàng Nai - 1995.

[3] Lance A. Leventhal, Z80 Assembly language programming.


McGraw-Hill, Inc - 1986.

[4] Atkinson and Atkinson, Using Borland C++.


QUE - 1991.

[5] Gerald Leblanc, Turbo C.


Nhaø xuaát baûn khoa hoïc vaø kyõ thuaät - 1996.

[6] Motorola, DATA BOOK DIGITAL IC - 1992.

[7] Z80 Microprocessor Family.


User’s Manual.

-------------------------------------------------------------

WX WX

145

You might also like