[ บทความ : เรียนรู้ z80 ] ตอนที่ 2 เรื่อง z80 และรีจิสเตอร์ใน Z80

Z80 เป็นไมโครโปรเซสเซอร์ 8 บิต ที่สามารถประมวลผลข้อมูลได้ทั้งขนาด 8 และ 16 บิต ... มีชุดคำสั่งทั้ง การคำนวณ, ลอจิก และ I/O ... Z80 สามารถอ้างอิงหน่วยความจำได้สูงสุด 64KB (8 บิต = 1 ไบต์ , 1024 ไบต์ = 1 กิโลไบต์ [KB]) .. สามารถอ้างอิงอุปกรณ์ I/O ได้ 256 อุปกรณ์ (0-255)

โครงสร้างภายในของ Z80 มีรายละเอียดหลัก ๆ ดังนี้

ALU : เป็นหน่วยประมวลผลทางคณิตศาสตร์และตรรกศาสตร์ (Logic)
IR : เป็นรีจิสเตอร์ ที่ทำหน้าที่เป็น buffer สำหรับเก็บคำสั่งที่อ่านมาจากหน่วยความจำ (memory)
Shifter : เป็นหน่วยที่ทำหน้าที่เลื่อนบิต และหมุนบิต
Decode/Control : เป็นหน่วยที่มีความสำคัญมาก เนื่องจากทำหน้าที่ตีความว่า คำสั่งที่จะทำงานนั้นเป็นคำสั่งอะไร และเป็นตัวที่ทำหน้าที่สั่งงานไปยัง ALU/Shifter
Flag : เป็นรีจิสเตอร์ที่ทำหน้าที่เก็บผลลัพธ์จากการทำงานของ ALU/Shifter
Register : เป็นหน่วยความจำภายใน CPU ซึ่งมีหน้าที่หลาย ๆ ด้าน ... ดังจะกล่าวถึงในหัวข้อรีจิสเตอร์ครับ

ลำดับการทำงานของไมโครโปรเซสเซอร์ z80 แบ่งได้เป็น 3 อย่าง คือ
1. Fetch หรือ กระบวนการอ่าน ... ช่วงนี้เป็นการอ่านคำสั่งจากหน่วยความจำ มาเก้บไว้ที่ IR
2. Decode หรือ กระบวนการจำแนกชนิดของคำสั่ง ... ในขั้นตอนนี้ Z80 จะดูว่า คำสั่งที่อ่านมาจากขั้นตอน Fetch นั้นทำหน้าที่อะไร และมีขนาดเท่าไร เพื่อที่จะ ได้กำหนดค่าแก่รีจิสเตอร์ PC ว่าคำสั่งถัดไปที่จะต้องทำนั้นอยู่ที่ตำแหน่งเท่าใดในหน่วยความจำ
3. Execute หรือ กระบวนการประมวลผล ... ในขั้นตอนนี้ Z80 จะทำงานตามคำสั่งที่ได้รับ เมื่อทำงานเสร็จ Z80 ก็จะทำการ เก็บผลการทำงานของ ALU เอาไว้ที่ flag เสร็จแล้วก็จะกลับไปทำที่ ขั้นตอนที่ 1 ใหม่ จนกว่าจะเจอคำสั่ง halt ตัว z80 ก็จะหยุดทำงาน

ในไมโครโปรเซสเซอร์ Z-80 นั้นจะมีรีจิสเตอร์ทั้งแบบ 8 บิต และ 16 บิต นอกจากนี้ยังสามารถรวมรีจิสเตอร์ทั่วไปขนาด 8 บิตจำนวน 2 ตัวให้เป็นรีจิสเตอร์แบบ 16 บิตก็ได้ รายละเอียดของรีจิสเตอร์ต่างๆ เป็นดังรูปต่อไปนี้

จากรูปจะได้ว่า Z-80 มีรีจิสเตอร์แบ่งออกเป็นประเภทหลักๆ ได้ 3 ประเภท คือ

1. รีจิสเตอร์หลัก สำหรับใช้งานทั่วไป

2. รีจิสเตอร์สำรอง ซึ่งใช้สลับกับรีจิสเตอร์หลัก

3. รีจิสเตอร์พิเศษ ที่เอาไว้ใช้ชี้ตำแหน่งต่างๆ ของหน่วยความจำ

1. รีจิสเตอร์หลัก

1.1 รีจิสเตอร์ A : เป็นรีจิสเตอร์ขนาด 8 บิต ที่ทำหน้าที่ทางด้านการคำนวณต่างๆ

1.2 แฟล็กของ Z-80

แฟล์กรีจิสเตอร์ (Flag register) เป็นหน่วยความจำที่เก็บสถานะจากการทำงานของคำสั่งที่ได้ประมวลผลไป หลังสุด หรือเรียกได้อย่างหนึ่งคือ เมื่อมีการประมวลคำสั่งไป 1 คำสั่ง ผลจากการทำงานของคำสั่งนั้นจะทำให้ค่าของแฟล์กเปลี่ยนแปลงไป ส่วนจะเปลี่ยนแปลงอย่างไรนั้นอยู่ที่ว่าคำสั่งนั้นมีผลกับแฟล์กตัวใดบ้าง (ดูได้จากคำอธิบายคำสั่ง) นอกจากแฟล์กเป็นตัวเก็บสถานะการทำงานแล้ว เรายังเอาค่าที่เกิดกับแฟล็กนี้มาใช้ในการตรวจสอบเงื่อนไขอีกด้วย ซึ่งจะอธิบายรายละเอียดนี้อีกครั้งในส่วนของคำสั่งเงื่อนไขของการทำงาน (condition jump)

ความหมายของแฟล็กบิตต่างๆ

C : เป็น 1 ถ้ามีการทดจาก MSB

N: 1 ถ้าการทำงานหลังสุดให้ค่าออกมาเป็นค่าลบ

P : เป็น 1 ถ้าค่าของบิตพาริตีเป็นคี่ หรือเกิดการล้นของข้อมูลในการคำนวณ (Overflow)

H : เป็น 1 ถ้ามีการทดหรือยืมจากบิตที่ 4

Z : เป็น 1 ถ้าการทำงานหลังสุดให้ผลลัพธ์เป็น 0

S : เป็น 1 ถ้า MSB เป็น 1

1.3 รีจิสเตอร์ B, C, D, E, H และ L : เป็นรีจิสเตอร์ขนาด 8 บิต ที่เราสามารถนำไปใช้งานทั่วไปได้ตามความต้องการ นอกจากนี้เราสามารถ ใช้รีจิสเตอร์ B,C,D,E,H และ L ให้เป็นรีจิสเตอร์แบบ 16 บิต ได้โดยการเรียกรวมกัน คือ BC , DE และ HL

2. รีจิสเตอร์สำรอง : จะเหมือนกับรีจิสเตอร์หลัก แต่ว่าเวลาใช้งานนั้นจะสลับกันใช้กับรีจิสเตอร์หลัก ทั้งนี้เพื่อความสะดวกในด้านการเก็บสถานะของรีจิสเตอร์เดิมเอาไว้ ดังนั้นเราจึงสามารถเขียนโปรแกรมให้มีโปรแกรม 2 ตัวทำงานพร้อมกันได้เลยโดยที่ไม่ทำให้รีจิสเตอร์ใช้งานทั่วไปและแฟล็กคำสั่งไม่มีผลกระทบระหว่างกัน

3. รีจิสเตอร์พิเศษ : เป็นรีจิสเตอร์ที่มีหน้าที่สำคัญต่อการทำงานของ CPU ซึ่งมีด้วยกันหลายตัว ดังนี้ครับ

รีจิสเตอร์ IX / IY : เป็นรีจิสเตอร์ที่ทำหน้าที่เป็นตัวชี้ (Index register) ตำแหน่งต่างๆ ในหน่วยความจำ

รีจิสเตอร์ SP : เป็นรีจิสเตอร์ที่ทำหน้าที่ ชี้ไปยังตำแหน่งของหน่วยความจำที่เรากำหนดให้เป็น stack ซึ่งหน่วยความจำ stack นี้จะกล่าวถึงในภายหลังครับ (ตอนนี้แปะโป้งเอาไว้ก่อน)

รีจิสเตอร์ PC : เป็นรีจิสเตอร์ที่ทำหน้าที่ชี้ไปยังตำแหน่งถัดไปที่ CPU จะนำมาประมวลผล

รีจิสเตอร์ I : เป็นรีจิสเตอร์ทำงานเกี่ยวกับ interrupt vector หน้าที่ของมัน คือ เก็บตำแหน่ง 8 บิตแรกของตารางอินเทอร์รัพท์ ซึ่งรายละเอียด การทำงาน จะกล่าวถึงในเรื่อง "interrupt" ล่ะกันครับ

รีจิสเตอร์ R : เป็นรีจิสเตอร์ที่ทำงานกับหน่วยความจำแบบไดนามิก แต่ปกติแล้วบอร์ดต่างๆ ที่เราใช้กันอยู่ใชหน่วยความจำแบบ static ram ซึ่ง เราไม่จำเป็นต้องทำการ refresh หน่วยความจำ ดังนั้น รีจิวเตอร์ R เลยไม่ได้ใช้ไปโดยปริยายครับ ... (เมื่อไม่ได้ใช้ก็ขอข้ามเลยล่ะกันครับ ;-D)

เรียบร้อยครับ สัปดาห์นี้เราได้ทำความรู้จักทั้งเรื่องโครงสร้างภายใน Z80 และรายละเอียดของรีจิสเตอร์ที่สำคัญ ๆ ไปแล้ว ... ต่อไปเราคงมาเริ่มใช้งาน บอร์ด Z80 กันดีกว่าครับ ... แล้วจะใช้รุ่นไหนดีล่ะ ... เอาเป็นว่าใช้รุ่นที่ผมมีอยู่ล่ะกันครับ ... ก็รุ่น ET-BOARD V6 ไงครับ ... เดิมมีรุ่น ET-BOARD V3.5 แต่ผมให้รุ่นน้องเอาไปใช้ ... ส่วนใครที่ใช้รุ่นที่แตกต่างออกไป ผมว่าคงไม่มีปัญหาอะไรมากนักหรอกครับ เพราะ โปรแกรมมอนิเตอร์ทำงานคล้ายๆ กัน แต่จะแตกต่าง กันในเรื่องการออกแบบทางด้าน memory map เท่านั้นครับ ... คราวหน้าเราจะเริ่มจากใช้งาน monitor แบบเท่าที่จำเป็นต่อการเขียนโปรแกรม แล้วก็เขียนโปรแกรมกัน ทั้งแบบใช้ remote debugger และ assembler กันต่อไปเลยล่ะกันครับ ... ตอนนี้คงจบเพียงเท่านี้ก่อนครับ



เขียนโดย : ศุภชัย บุศราทิจ
Author : Supachai Budsaratij
e-mail : raek@se-ed.net
วันที่ทำการปรับปรุง : ๒๐ ก.ย. ๒๕๔๓