You are on page 1of 141

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

KHOA COÂNG NGHEÄ THOÂNG TIN


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.

 

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


 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.................................................................................................
 2.2. Kieán truùc Z80 CPU.......................................................trang 10
 2.3. Thieát keá chi tieát.........................................................trang 48
 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, Runtrang 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

 

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.

 

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:

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

5
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
pin
PC
Adrres C
Rom
bus aùc
chöôn
Z80 linh
g
CPU kieä
trình
Data bus KIT Z80 baát kyø n
kha
Simulator

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á  cuûa 74LS74 (U8A)
Reset : noái vaøo chaân soá  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 1
T.h cho 6 Z80
pheùp/caám CPU
Caám=’0’ : Khi chaïy ôû cheá ñoä Debug(caám ngaét).

 

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.

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
8
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æ9cô 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.

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 9
Bus noäi
Giaûi Thanh ALU
Tín hieäu maõ ghi
ñieàu khieån & leänh Kieåm soaùt CPU
heä thoáng
ñieàu
& CPU khieån
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 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.

10
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

11
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 Thanh ghi Thanh ghi tích Thanh ghi
luõy A côø F luõy A’ côø F’
B C B’ C’ Thanh ghi
D E D’ E’ ña duïng
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.


12
a. Giôùi thieäu.

Sô ñoà caùc chaân cuûa Z80 CPU ñöôïc moâ taû trong hình sau :

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
2 A12
16
/INT 3 A13
17 4
/NMI A14
5
A15
/RESET 26

/BUSRE
25
23
Z80 CPU 14
15
D0
Q D1
/BUSACK
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õ ôû
14
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.
• /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 Ñoïc boä nhôù


Ghi boä nhôù M3
M1 M2

Chu kyø
leänh ñoà thôøi gian cô baûn
Hình 3 -1 : Giaû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

16
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 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 Refresh
PC
address

/MREQ

/RD

/WAIT

/M1

D7÷
D0 IN
/RFSH

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

Hình 3-3 minh hoïa Hình


giaûn3-2:
ñoàChu
thôøi
kyøgian
laáycuûa
maõ chu kyø ñoïc, ghi boä nhôù.
leä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 Chu kyø ghi boä
boä nhôù nhôù
T T T T T T
/ 1 2 3 1 2 3
Clk

A15÷A0 MEMORY ADDR MEMORY ADDR

/MRE
Q
/RD

/WR

D7÷
I DATA OUT
D0
N

/WAIT
d. Chu kyø nhaäp/xuaát.
Hìnhñoäng
Hình 3-4 minh hoïa hoaït 3-2: Chu
ñoïckyø
hayñoïc
ghi ghi
I/O. Chuù yù raèng trong thôøi
boä nhôù.
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 IN ÑOÏC

/WAIT

/WR

CHU
D7÷D0 KYØ GHI
OUT

e. Chu kyø Bus Req/Ack.


Hình 3-4: Chu kyø xuaát /
Hình 3-5 minh hoïa giaûn ñoànhaäp.
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 TRAÏNG THAÙI
KYØ COÙ THEÅ
Traïng
thaùi T
Tx Tx Tx T1
cuoái
/
Clk

/BUSR Maãu
Q Maãu

/BUSACK

A15÷A0

D7÷
D0
Floati
/MERQ ng
/RD, /WR
/IORQ
/RFSH

f. Chu kyø interrupt req/ack


Hình 3-5: CHU KYØ BUS 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 M1
LEÄNH
Traïng Tw Tw
thaùi T T1 T2 T3
’ ’
cuoái
/Clk

/
INT

A15÷A0 PC REFRESH

/M1

/MREQ

/IORQ

D7÷
D0
I
N
/WAIT

/RD

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


Hình 3-6: CHU KYØ NGAÉT
Hình 3-7 minh hoïa chu kyø request hay chu kyø ack cho ngaét khoâng che
REQ/ACK
ñöôï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 M1
LEÄNH
Traïng
thaùi T T1 T2 T3 T4 T1
cuoái
/Clk

/NMI

A15÷ PC REFRESH
A0
/M1

/MREQ

/RD

/RFSH

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


Hình 3-7 : Giaûn ñoà thôøi gian cuûa NMI.
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
T T2 T3 T4 T1
1
/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
i. POWER-DOWN ACKNOWLEDGE khoûi traïng
CYCLE.
thaùi HALT
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 Tw Twa
a
/Clk

/RESET
/M1

/HALT

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


24
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.

25
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û 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.

26
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ôù.

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
27
ñí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õ 2 byte maõ leänh


leänh
Maõ 2 byte maõ leänh
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 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õ 1 hay 2 byte
leänh

28
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æ:

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.

29
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 A
ddr

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


BC) ) ) nn)
A ED ED 7F 78 79 7A 7B 7C 7D 7E 30 1A FD DD DD DD
57 5F A 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
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
( 02
BC)
( 12
DE)
( DD DD DD DD DD DD DD DD
IX+ 77 70 71 72 73 74 75 36
d) d d d d d d d d
n
( FD FD FD FD FD FD FD
IY+ 77 70 71 72 73 74 75
d) d d d d d d d
(nn) 32

30
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æ DD Maõ leänh


A
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æ 3A Maõ leänh


A
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æ 26 Maõ leänh


A
A+1 36 Toaùn haïng

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æ DD Maõ leänh


A
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 :
31
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æ E6 Maõ leänh
A
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.

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

32
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 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)
33
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)

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
34
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 1111 0011 = F3H
hieän pheùp toaùn
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
d d
ADD 8F 88 89 8A 8B 8C 8D 8E DD FD CE
Carr 8E 8E n
y d d
ADC
SUB 97 90 91 92 93 94 95 96 DD FD D8
96 96 n

35
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
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

36
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
d d
3E 3E
‘SRL’ ED
6F
‘SRL’ ED
67

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

CY b7 → b0 37
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

38
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

39
ñò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:

Ñòa chæ C3 Maõ leänh


A
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
40
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
T 2 CB CB CB CB CB CB CB CB DD FD
EST 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
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
R 2 CB CB CB CB CB CB CB CB DD FD
EST 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
41
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
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 D DE CB CB
D 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

42
Un- Carr Non Z Non Parit Parit S S Neg
con y Carr ero Zer y y ign ign S=0
d y o Even Odd Neg Pos
Jump ‘JP’ I (nn) C3 DA D2 CA C2 EA E2 FA F2
mme n n n n n n N n n
d Ext n n n n n n N n n
Jump ‘JR’ Relat PC→ 18 38 30 28 20
ive e 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’ I nn CD 0C D4 CC C4 EC E4 FC F4
mm n n n n n n N n n
ed n n n n n n N n n
Ext
Giaûm B, Rela P
nhaûy tive C+e
neáu
khoâng
zero ‘DJNZ
Return Reg (SP) C9 D8 D0 C8 C0 E8 E0 F8 F0
‘Ret’ Indr (SP+
1)
Return töø Reg (SP) ED
Int ‘RETI’ Indr (SP+ 4D
1)
Return töø Reg (SP) ED
ngaét Indr (SP+ 45
khoâng 1)
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 0008H CF ‘RST 8 ‘
CHÆ
CALL 0010H D7 ‘RST 16 ‘
0018H DF ‘RST 24 ‘
0020H E7 ‘RST 32‘
0028H EF ‘RST 40 ‘
0030H F7 ‘RST 48 ‘
43
0038H FF ‘RST 56 ‘
Hình 4-12 : NHOÙM LEÄNH KHÔÛI ÑOÄNG LAÏI ( RESTART GROUP)

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 ED
B REPEAT If B≠0 BA
Hình 4-13: NHOÙM LEÄNH NHAÄP ( INPUT GROUP )

44
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 IND AB
DecHL &B
11 OUT – REG (c) ED
OUTPUT IND BB
DecHL &B
REPEAT If B≠0
Port ñòa chæ Khoái
ñích 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.

45
Chæ ñeán baûng ngaét, thanh
ghi I laø ñòa chæ cao, ñaùp
Ñòa chæ öùng ngoaïi vi laø ñò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
Trong ñoù :

46
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.

47
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 Khoâng möôïn
ñeán bit 4 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

48
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.
49
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.

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.

50
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.
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.

51
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.

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)
52
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.
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:

53
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 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'.

54
- 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.

Ñ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
55
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.

 

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:
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).
56
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.
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.

57
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.

 

58
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

2 1
Read RAM

Count++

59
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

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

Start

Khôûi ñoäng
8255
PA=PC=Outpu

Taïo xung WR

End

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

Start

AddrLow=XX
H
AddrHi=XXH
Tx=AddrLow

Taïo xung WR

Ñöa Tx ra PA

Tx=AddrHi

Taïo xungWR

Ñöa Tx ra PC

End

4.5. Chöông trình con ghi / ñoïc RAM vaø kieåm tra DATA
Start
61
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
Caát 4 bit thaáp

Ñoïc vaøo thanh


ghi
traïng thaùi 4
Khoâi phuïc
byte

N
Byte phaùt
ñuùng?

Y
End

62
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

63
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

64
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

C3 ?
N
Y
32 ?

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

Cho CPU chaïy tieáp End


C2 ? N

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


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

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


data bus Ñöa byte cao cuûa voøng
laëp ra data bus
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

66
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

67
4.10. Giaûi thuaät chöông trình xöû lyù
phím F7 & F8 (Debug)
Ctrl F9
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

68
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

69
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

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


kyù töï

Caäp
nhaät N
maøn
Phím chöùc
naêng ?

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

Alt_X ?

End

70
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

F2 ?

Löu file ñang soaïn


thaûo
N

F3 ?

Môû file
N

ESC ?

Y 1

Trôû veà maøn hình


soaïn thaûo

71
1

Ctrl_F9 ?

RUN

Ctrl_F8 ?

End

Set Breakpoint

72
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*/
//===============================================
=============
73
#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*/
#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*/

74
#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
#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);

75
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);
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;

76
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;
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);

77
/* 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);
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() ) */

78
if ( AddrFlag )
{
outportb(CTRLREG,InitCTRL);
delay(Set);
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);
};
/* 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 )
{

79
do
{
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;
if ( (CurrentLine<win_index)||(CurrentLine>win_index+18) )
{
win_index=CurrentLine-8;
UpdateScreen();

80
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();
};
msg_finish();
/*Ñoaïn chöông trình dump boä nhôù*/
do
{
Key=get_key();
while ( ( Key!=K_F3 ) && ( Key != K_ESC ) )
{

81
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;
}
} 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)

82
{
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.  ");
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);

83
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)
{
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)==*/
84
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)
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();

85
}

/*==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);
}

/*==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.

86
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==*/
/*===========================================*/

/*==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
{

87
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++)
{
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;

88
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;
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++)

89
{
BusyYes=RDBusy();
if ((BusyYes)&&(k>=2)) break; // Ñoïc 2 laàn ñeå choáng nhieãu.
delay(Set);
};
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);

90
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)
{
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*/

91
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;
}

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


void error_file(char FName[81])
{
set_cursor_style(0x20,0x20);

92
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 )
{
AddrLow = 0;
AddrHi++;
if ( AddrHi > 0x7F ) // (0111 1111).
{
ERROR2();
Add.lo=0;
Add.hi=0;
return(Add);

93
};
} // > 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;
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;

94
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);
}

/**==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*/

95
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)
{
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;

96
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");
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);

97
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)
Ñ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;

98
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(" ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ");
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.  ");
99
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 */
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;
100
byte FlagError=1,readFlag=0;
byte DisplayFlag=0;
int Hi,value;
byte valueLo,valueHi;
byte DataMemory;
unsigned Key;
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

101
ErrorReg(LowAddr,HighAddr);
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();
readFlag=0;
};
}
for (k=1;k<=3;k++)

102
{
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();
};
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)
{

103
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);
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.

104
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);
}

/*==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);
}
}
105
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  ");
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)
106
{
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();
}

/*==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.
107
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();
}
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
108
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
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

109
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

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
cpe
jp nz,loop
ld a,b
cpd
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>
110
#include <stdio.h>
#include <conio.h>
#include <string.h>
#include "keyboard.h"
#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("");

111
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
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++)
{

112
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)
{
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:

113
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++;
}
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);

114
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);
}
/////////////////////////////////////////////////////////////////////
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);

115
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);
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);

116
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)
{ //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;

117
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();
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;

118
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();
}
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: ");

119
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];
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);
120
if (input_file_name()!=0) return;
strupr(file_name); //Ñoåi teân file thaønh chöõ hoa
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);
}
fclose(fptr);
saved=1;

121
}
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");
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)
{

122
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)||
(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==*/

123
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();
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)

124
{
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
{
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]);

125
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
}
}
/////////////////////////////////////////////////////////////////////
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

126
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;
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:  ");
127
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);
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)

128
{
do
{
if (selection1==0) //Select File menu
{
key = menu_file();
if (key==K_ALT_X) break;
else if (key==K_RIGHT) selection1=1;
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);

129
else if (selection3==2) debug(K_F8);
}
else if (selection1==2)
{
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)
} //endif (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.
; Ngaøy vieát: 11/03/1999.
130
; 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:
inc b
ld hl,table2
jp loop02
sw003:
inc b
ld hl,table3

131
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
;
start1:
ld iy,8000h
start2:
ld a,(iy+00)
out (00h),a
call delay
;
loop00:
in a,(04h)
;

132
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
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

133
;
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
;
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

134
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
;
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

135
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
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

136
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
; 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 ====================

 

137
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.

 

138
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:

139
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.

 

140
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.

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

 

141

You might also like