สารบัญ:
- ขั้นตอนที่ 1: ภาพรวมอย่างรวดเร็วของการเปลี่ยนแปลง + แผนผัง
- ขั้นตอนที่ 2: CPU หน่วยความจำและการควบคุมหน่วยความจำ
- ขั้นตอนที่ 3: ไฟ LED แสดงสถานะระบบ
- ขั้นตอนที่ 4: อินพุตและเอาต์พุต
- ขั้นตอนที่ 5: รีเซ็ตและสิ้นสุดอินพุตและเอาต์พุต
- ขั้นตอนที่ 6: การเขียนโปรแกรม
วีดีโอ: ทบทวนคอมพิวเตอร์ Z80: 6 ขั้นตอน
2024 ผู้เขียน: John Day | [email protected]. แก้ไขล่าสุด: 2024-01-30 13:02
ในอดีต ฉันได้เขียนคู่มือเกี่ยวกับวิธีการสร้างคอมพิวเตอร์ที่ใช้ Z80 และฉันได้ออกแบบวงจรให้เรียบง่ายที่สุดเท่าที่จะเป็นไปได้ เพื่อให้สามารถสร้างได้ง่ายที่สุด ฉันเขียนโปรแกรมขนาดเล็กด้วยแนวคิดเรื่องความเรียบง่ายแบบเดียวกัน การออกแบบนี้ใช้งานได้ค่อนข้างดี แต่ฉันไม่ค่อยพอใจกับมันเท่าไหร่ ฉันเริ่มต้นด้วยการเขียนโปรแกรมใหม่เพื่อให้สามารถตั้งโปรแกรมได้ระหว่างรันไทม์ เพื่อให้ฉันทดสอบโค้ดโดยไม่ต้องทุ่มเทให้กับ EEPROM ซึ่งจะทำให้ฉันต้องตั้งโปรแกรม EEPROM ใหม่ นี้ไม่ได้ฟังดูเหมือนเป็นความคิดที่สนุกสำหรับฉัน จากนั้นฉันก็เริ่มคิดถึงพื้นที่หน่วยความจำ ถ้าฉันต้องการเชื่อมต่อกับชิ้นส่วนของฮาร์ดแวร์ (โดยหลักแล้ว IO) โค้ดบางส่วนอาจเกินพื้นที่หน่วยความจำที่มีให้กับระบบ โปรดจำไว้ว่า การออกแบบใช้เฉพาะไบต์ล่างของแอดเดรสบัส และจากนั้นใช้บิตล่างของไบต์สูงเพื่อเลือกระหว่างช่องว่าง ROM และ RAM นั่นหมายความว่าฉันมีพื้นที่ว่างเพียง 253 ไบต์เท่านั้น คุณอาจจะถามว่าทำไม 253 แทนที่จะเป็น 256 นั่นเป็นเพราะว่าโค้ดใหม่ของฉันใส่ข้อมูลสามไบต์ที่ส่วนท้ายของโปรแกรมที่เขียนขึ้น
NS
ฉันกลับไปดูแผนผังเก่าเพื่อดูว่าเกิดอะไรขึ้นอีก ฉันพบข้อบกพร่องเล็กๆ น้อยๆ เกี่ยวกับวงจรการเลือกหน่วยความจำ ซึ่งฉันจะแก้ไขเมื่อไปถึงที่นั่น เวอร์ชันที่เรียบง่าย: คำขอเขียนทั้งหมดจะผ่านได้จริง แม้ว่าจะใส่ RAM ไว้เสมอก็ตาม สิ่งนี้อาจไม่ใช่เรื่องน่ากังวล แต่คราวนี้ฉันต้องการทำอย่างถูกต้อง และด้วยเหตุนี้ ฉันจึงเริ่มวาดแผนผังใหม่ ภาพสองภาพที่แนบมาในหน้านี้ เป็นภาพก่อนและหลังวงจรจริง ฉันทำความสะอาดเส้นสปาเก็ตตี้ไปมากแล้ว มันไม่ตลกเลย
NS
หากคุณติดตามผลงานต้นฉบับของฉันและวางแผนที่จะทำตามนี้ คุณจะต้องเกลียดฉันแน่ หากคุณเริ่มต้นใหม่ แสดงว่าคุณโชคดี เพียงหยิบชิ้นส่วนในรายการ (หรือเทียบเท่า) แล้วทำตาม
เสบียง:
LM7805 - ตัวควบคุม 5 โวลต์Z80 - ซีพียู; สมองของระบบAT28C64B - EEPROM การจัดเก็บข้อมูล "ถาวร" ที่ใช้สำหรับเฟิร์มแวร์ของคอมพิวเตอร์IDT6116SA - SRAM ใช้สำหรับจัดเก็บรหัสผู้ใช้และ/หรือการจัดเก็บข้อมูลทั่วไปNE555 - นาฬิการะบบ74HC374 - Octal D-Latch พร้อม /OE; ใช้เป็นชิปอินพุต 74LS273 - Octal D-Latch พร้อม /MR; ชิปเอาต์พุตTLC59211 - ชิปไดรเวอร์ LED (ใช้เพื่อให้ 74LS273 สามารถขับไฟ LED ได้ เนื่องจากตัวเดียวไม่สามารถให้เอาต์พุตปัจจุบันได้)MC14572 - นี่คือชิป "Line Driver" แต่ฉันพบว่ามันสมบูรณ์แบบสำหรับตรรกะการควบคุมหน่วยความจำ มีอินเวอร์เตอร์ 4 ตัว และเกท NAND และ NOR ที่สร้างขึ้นใน 74LS32 - Quad OR gateCD4001 - Quad NOR gateCD4040 - 12 Stage Ripple Counter; วาด แต่ไม่ได้ใช้ตัวแบ่งนาฬิกา (สำหรับการเรียกใช้ระบบที่ความเร็วสัญญาณนาฬิกาที่ช้าลง)2 ตัวต้านทาน 10K Ohm - ตัวหนึ่งใช้ในวงจรจับเวลา 555 ดังนั้นใช้ค่าใดก็ได้ที่คุณต้องการ4 ตัวต้านทาน 1K Ohm - ตัวหนึ่งใช้สำหรับ วงจรจับเวลา 555 ดังนั้นใช้สิ่งที่คุณต้องการ อีกอันหนึ่งใช้สำหรับขับ LED ดังนั้นให้เปลี่ยนด้วยเช่นกันหากคุณต้องการ 8x330 Ohm Resistor Bus8x10K Ohm Resistor Bus11 LEDs - สามใช้สำหรับสถานะของระบบและอีกแปดตัวเป็นเอาต์พุต สำหรับ 8 ฉันใช้ตัวเก็บประจุแบบแท่งกราฟแท่ง (HDSP-4836)4 - LM7805 สองตัวถูกใช้ 0.22uF และ 0.1uF หนึ่งสำหรับตัวจับเวลา 555 ดังนั้นใช้สิ่งที่คุณรู้สึกว่าถูกต้อง สุดท้ายคือการรีเซ็ตการเปิดเครื่อง 100uF2 NO ปุ่มกด - อันหนึ่งใช้สำหรับอินพุต อีกอันสำหรับรีเซ็ต8 SPST DIP Switches - อินพุตข้อมูล; ฉันใช้คีย์เปียโน styleWire ลวดเยอะมาก
NS
หมายเหตุ: MC14572 through hole version ล้าสมัย แต่เวอร์ชัน SMD ยังคงทำงานอยู่ (ไม่ใช่สถานะ "ไม่ใช่สำหรับการออกแบบใหม่") ดังนั้นคุณอาจต้องซื้อแผงวงจรเพื่อให้สามารถใช้งานได้ สามารถใช้ 74LS32 ตัวที่สองแทน MC14572 ได้ (โปรดดูแผนผัง "วงจรการเลือกหน่วยความจำ" ของ ible ก่อนหน้า)
ขั้นตอนที่ 1: ภาพรวมอย่างรวดเร็วของการเปลี่ยนแปลง + แผนผัง
วิธีอ่านแผนผัง:ลูกศรที่ชี้ไปที่ชิปคืออินพุต:อินพุต >-ลูกศรที่ชี้ออกจากชิปคือเอาต์พุต:เอาต์พุต <-Busses ใช้บรรทัดแทนลูกศร:Bus |-
NS
ชิปส่วนใหญ่ถูกวาดด้วยพินเอาต์ที่แน่นอน จุ่มเล็กน้อยลงบนชิปเหล่านี้ ชิปส่วนใหญ่มีหมายเลขพินและป้ายกำกับอยู่ด้วย พวกเขาอาจจะอ่านยากสักหน่อย ดินสอของฉันเริ่มทื่อ
NS
ในแง่ของการเชื่อมต่อวงจร เลย์เอาต์ของการออกแบบใหม่ส่วนใหญ่ไม่เปลี่ยนแปลงจากเดิม ฉันเชื่อมต่อ nibble ล่างของที่อยู่ไบต์สูงกับความทรงจำ จากนั้นใช้บิตที่ต่ำของ nibble ด้านบน (A12) สำหรับการเลือก RAM/ROM ซึ่งหมายความว่าพื้นที่ ROM เปลี่ยนจาก 0000-00FF เป็น 0000-0FFF พื้นที่แรมเปลี่ยนจาก 0100-01FF เป็น 1000-1FFF ฉันยังเปลี่ยนลอจิกการควบคุมหน่วยความจำเพื่อการออกแบบที่ดีขึ้นและเพิ่มไฟ LED แสดงสถานะใหม่สองดวง (และตรรกะของกาวบางส่วน) ฉันยังวาด (แต่ไม่ได้ต่อสาย) วงจรแบ่งนาฬิกาด้วย เป็นการทำหน้าที่สองอย่าง หน้าที่ที่ชัดเจนคือการแบ่งความถี่สัญญาณนาฬิกาลง อีกฟังก์ชันหนึ่งมีไว้สำหรับวัตถุประสงค์ PWM (Pulse Width Modulation) เนื่องจาก 555 ไม่สร้างคลื่นที่มีรอบการทำงาน 50% วงจรนี้ไม่สำคัญ แต่ถ้าคุณต้องการใช้นาฬิกาเพื่อขับเคลื่อนไฟ LED คุณจะสังเกตเห็นว่าเอฟเฟกต์ (ชุดหนึ่ง) LED จะหรี่ลงกว่าที่อื่นอย่างแน่นอน วงจรที่เหลือทั้งหมดไม่เปลี่ยนแปลงโดยพื้นฐานแล้ว
ขั้นตอนที่ 2: CPU หน่วยความจำและการควบคุมหน่วยความจำ
นี่เป็นส่วนที่ผู้อ่านเวอร์ชันก่อนหน้าเกลียดฉัน ในการสร้างดั้งเดิม ฉันแค่โยนชิ้นส่วนบนกระดานในที่ที่ดูเหมือนว่าพวกเขาจะมีปัญหาเล็กน้อยในการต่อสาย ผลที่ได้ดูเหมือนมีคนเทปาเก็ตตี้จานหนึ่งและเป็นเหมือน "สายไฟ!" ฉันต้องการล้างข้อมูลเล็กน้อย ดังนั้นฉันจึงเริ่มด้วยการริปทุกอย่าง ยกเว้น CPU, RAM และ ROM ฉันดึงวงจรอินพุต วงจรเอาท์พุต และตรรกะของกาวขึ้นมาเกือบทั้งหมด ฉันเกือบจะเจ็บที่จะทำ แต่มันจำเป็น ฉันปล่อยให้การเชื่อมต่อข้อมูลทั้งหมดไม่เสียหายและไบต์ล่างของแอดเดรสบัส จากนั้นฉันก็เชื่อมต่อแอดเดรสบัสสี่บิตถัดไป (A8-A11) กับชิป ROM ฉันดูแลที่จะไปรอบ ๆ ชิปในครั้งนี้เพื่อให้ง่ายต่อการดึงขึ้นสำหรับการตั้งโปรแกรมใหม่ ฉันยังเพิ่มการเชื่อมต่อที่อยู่ลงไปที่ชิป RAM
NS
ด้วยวิธีนั้น ตอนนี้ฉันต้องวางสายตรรกะการควบคุมหน่วยความจำ ในแผนผังเดิม ฉันได้เชื่อมต่อสาย /MREQ ของโปรเซสเซอร์กับ /CE กับชิปหน่วยความจำทั้งสองโดยตรง จากนั้นจึงต่อสาย /WR ไปที่ RAM's /WE จากนั้นฉันก็มี /RD และ /MREQ ของ CPU อย่างมีเหตุผลหรือรวมกันเช่นเดียวกับ A9 โดยพื้นฐานแล้ว มันถูกตั้งค่าเพื่อให้คำขอหน่วยความจำทั้งหมดเปิดใช้งานทั้ง RAM และ ROM แต่ A9 ถูกใช้เพื่อเลือกชิป / OE ที่ได้รับเลือก นี่เป็นเรื่องปกติและทั้งหมดเป็นเพราะชิปจะยังคงไม่ทำงานจนกว่าจะมีการร้องขอหน่วยความจำและมีเพียง /OE เดียวเท่านั้นที่จะเปิดใช้งานระหว่างการร้องขอการอ่าน สิ่งนี้ป้องกัน crosstalk ได้ แต่แนะนำความแตกต่างเล็กน้อยที่น่าอึดอัดใจ เนื่องจาก A9 ใช้เพื่อกำหนดว่าชิปตัวใดกำลังส่งข้อมูลออก และเนื่องจาก CPU มีการเข้าถึงโดยตรงไปยังพิน /WE ของ RAM คำขอเขียนใดๆ และทั้งหมดจึงจะผ่านได้ นี่เป็นเรื่องปกติสำหรับ ROM เนื่องจากโหมดการเขียนถูกยับยั้งโดยผูก /WE เข้ากับแหล่งจ่ายไฟ 5V โดยตรง อย่างไรก็ตาม RAM จะถูกเขียนโดยไม่คำนึงถึง A9 ซึ่งหมายความว่าการพยายามเขียนไปยังตำแหน่งพื้นที่ ROM จะเขียนไปยังตำแหน่งเดียวกันในพื้นที่ RAM
NS
ทางออกหนึ่งสำหรับสิ่งนี้คือการเดินสายตรรกะการควบคุมใหม่ เพื่อให้ CPU สามารถเข้าถึงพิน /OE และ /WE ของชิปได้โดยตรง จากนั้นใช้ MREQ และ A12 เพื่อเลือกว่าชิปใด /CE ถูกขับเคลื่อน ฉันไปกับแนวคิดนี้ แต่แทนที่จะใช้เกท NOR สี่ตัวและอินเวอร์เตอร์แบบเดียวกับการออกแบบดั้งเดิม ฉันพบว่าชิปตัวเล็กๆ ที่น่าอึดอัดใจซึ่งเหมาะกับงานนี้ที่สุด ฉันต้องสร้างวงจรที่ใช้เฉพาะลอจิกเกตที่มีอยู่ในชิป แต่ก็ง่ายพอ A12 ป้อนเข้าโดยตรงในเกท NAND และเกท NOR /MREQ ถูกป้อนเข้าประตู NOR และป้อนคำชมเข้าประตู NAND ประตู NAND ใช้เพื่อขับเคลื่อน /CE สำหรับ RAM และเอาต์พุต NOR จะกลับด้านและใช้เพื่อขับเคลื่อน ROM /CE ทำให้ต้อง /MREQ ต่ำก่อนที่จะเลือกชิปตัวใดตัวหนึ่ง จากนั้น A12 จะเลือกตัวใดตัวหนึ่งที่จะเลือก ด้วยการตั้งค่านี้ ตอนนี้คำขอเขียนไปยัง ROM จะไม่ทำอะไรเลย นอกจากนี้ยังประหยัดพลังงานเพราะมีชิปเพียงตัวเดียวที่ทำงานแทนทั้งสองอย่าง สำหรับตัวลอจิกชิปนั้น เรายังมีอินเวอร์เตอร์ที่ไม่ได้ใช้สองตัวอยู่ข้างใน หนึ่งจะใช้ในภายหลัง แต่เราจะไปที่นั่นเมื่อเราไปถึงที่นั่น
ขั้นตอนที่ 3: ไฟ LED แสดงสถานะระบบ
ก่อนที่ฉันจะเริ่มโปรเจ็กต์นี้ ฉันพยายามเชื่อมต่อกับไอซีบางตัว แต่ฉันมีปัญหากับมัน ไม่แน่ใจว่าเกิดอะไรขึ้น ฉันใช้ LED แบบติดตั้งบนแผงเพื่อตรวจสอบรอบๆ (หนึ่งในแอสเซมบลีที่มีตัวต้านทานในตัว) การทำเช่นนี้ทำให้ฉันมีความคิดถึงที่ยังใช้อยู่ในปัจจุบัน: ไฟ LED แสดงสถานะใช้เพื่อระบุว่าหน่วยความจำถูกอ่านหรือเขียนถึงหรือไม่ มันต้องใช้ร่วมกับอินพุต LED ที่ฉันมีอยู่แล้ว LED อินพุตเชื่อมต่อกับเครื่องกำเนิดสัญญาณ /WAIT เพื่อแจ้งให้เราทราบว่าระบบกำลังรออินพุตอยู่ (ฉันจะไปที่นั่นไม่ต้องกังวล) ฉันคิดว่าจะเพิ่ม LED เพื่อระบุการเขียน IO แต่ฉันคิดว่า LED เอาต์พุตที่เปลี่ยนไปจะเป็นตัวบ่งชี้ที่ดีอยู่แล้ว คิดดูแล้วยังบวกได้อีก อย่างไรก็ตาม ฉันพบว่ามีประโยชน์ที่จะทราบว่ามีการอ่านหรือเขียนหน่วยความจำหรือไม่ มันมีประโยชน์สำหรับการดีบักโปรแกรมอยู่ดี จริง ๆ แล้วฉันใช้มันอย่างหนักเมื่อพยายามทำให้โปรแกรมของฉันทำงาน: ทำไมมันถึงเขียนลงในหน่วยความจำ? มันยังไม่ควรทำอย่างนั้น!”
NS
เพื่อควบคุมไฟ LED เหล่านี้ ฉันใช้เกท NOR รูปสี่เหลี่ยม ฉันใช้ประตูทั้งหมด มีเพียงสองตัวเท่านั้นที่ใช้ในการสร้างสัญญาณสถานะ แต่ชิปไม่มีความสามารถในการขับเคลื่อนไฟ LED ได้จริง พวกมันสามารถจมพลังงานได้มากขนาดนั้น ดังนั้นฉันจึงใช้เกท NOR อีกสองตัวเป็นอินเวอร์เตอร์และเชื่อมต่อไฟ LED เช่นนั้น เนื่องจาก LED ดวงหนึ่งใช้เพื่อระบุการอ่านและอีกดวงสำหรับการเขียน และคำขออ่านและเขียนจะไม่เกิดขึ้นพร้อมกัน ฉันสามารถหลีกเลี่ยงได้โดยใช้ตัวต้านทานเพียงตัวเดียวสำหรับ LED ทั้งสองดวง สำหรับสัญญาณที่ฉันจำเป็นต้องถอดรหัส นั่นก็ง่ายพอเช่นกัน ฉันต้องการให้คำขออ่านหน่วยความจำทั้งหมดได้รับการระบุ ดังนั้นเกต NOR แรกจึงมี /MREQ และ /RD บนอินพุต สถานะการเขียนนั้นซับซ้อนกว่าเล็กน้อย แต่ก็ง่ายเหมือนกัน ฉันยังคงใช้ /MREQ เป็นอินพุตเดียว แต่การใช้ /WR เป็นอินพุตอื่นจะทำให้ความแตกต่างเล็กน้อยที่ฉันต้องการหลีกเลี่ยง มันจะได้ระบุคำขอเขียนทั้งหมด ฉันต้องการเพียงคนที่ผ่านไปแล้วจริงๆ แล้วฉันจะทำอย่างนั้นได้อย่างไร? จำได้ว่าฉันตั้งค่าระบบอย่างไรเพื่อให้สามารถเขียนได้เฉพาะ RAM เท่านั้น ฉันใช้ RAMs /CE เป็นอินพุตอื่นไปยังเกต NOR ซึ่งหมายความว่า LED จะสว่างขึ้นเมื่อเลือก RAM และทำการร้องขอการเขียนเท่านั้น ในแง่ของสี LED ฉันเลือกสีส้มเป็นตัวบ่งชี้การอ่าน (แต่ฉันพบเพียงสีเหลือง) และสีแดงเป็นตัวบ่งชี้การเขียน
ขั้นตอนที่ 4: อินพุตและเอาต์พุต
ในขั้นตอนก่อนหน้านี้ คุณอาจสังเกตเห็นว่าฉันได้เพิ่มส่วนประกอบที่เหลือบางส่วนลงในบอร์ดแล้ว ฉันจองพื้นที่ไว้เพื่อไม่ให้วางสายไฟในที่ที่ฉันต้องการส่วนประกอบโดยไม่ได้ตั้งใจ (ดังนั้นฉันจึงต้องหาตำแหน่งใหม่สำหรับส่วนประกอบดังกล่าว) คุณอาจสังเกตเห็นว่าฉันทิ้งสวิตช์อินพุตไว้และต่อเข้ากับรางจ่ายไฟ ฉันตัดสินใจว่าตำแหน่งเดิมเป็นจุดที่เหมาะสมที่สุด และตัดสินใจวาง LED เอาต์พุตไว้ใกล้ๆ (ด้านบน) ทางด้านขวาของแถบแสดงผลคือสลักอินพุต ด้านบนนั้นคือสลักเอาท์พุต และด้านซ้ายของมันคือไดรเวอร์ LED ฉันเริ่มต้นด้วยการเชื่อมต่อจอแสดงผลกับไดรเวอร์เนื่องจากเป็นวิธีที่ง่ายที่สุด จากนั้นฉันก็เชื่อมต่อสวิตช์กับด้านอินพุตของสลักอินพุต ต่อไปฉันเชื่อมต่อด้านเอาต์พุตของสลักเอาต์พุตกับไดรเวอร์ LED นี่อาจดูเหมือนเป็นคำสั่งที่น่าอึดอัดใจในการรับสายเหล่านี้ แต่ด้วยเหตุผล อินพุตของสลักเอาต์พุตจะต้องเชื่อมต่อกับบัสข้อมูลและเอาต์พุตของสลักอินพุต แนวคิดคือการเชื่อมต่อเอาต์พุตของสลักอินพุตกับอินพุตของสลักเอาต์พุต ซึ่งฉันทำ ทั้งหมดที่ฉันต้องทำคือทำให้ยุ่งกับดาต้าบัส ไม่สำคัญว่าการเชื่อมต่อเหล่านี้จะไปที่ใดเพราะทั้งหมดจะเชื่อมต่อด้วยไฟฟ้า ตอนนี้คอมพิวเตอร์เกือบเสร็จแล้ว
ขั้นตอนที่ 5: รีเซ็ตและสิ้นสุดอินพุตและเอาต์พุต
ขออภัยไม่มีรูปภาพสำหรับขั้นตอนนี้ อ้างถึงขั้นตอนก่อนหน้าสำหรับรูปภาพ
NS
คุณอาจสังเกตเห็นในรูปสุดท้ายของขั้นตอนก่อนหน้านี้ ฉันมีปุ่มสีเขียวและติดตั้งชิปลอจิกอื่น ชิปคือเกท OR สองประตูถูกใช้เพื่อสร้างสัญญาณ /WAIT อย่างใดอย่างหนึ่งสร้างสัญญาณโดย OR-ing /IORQ และ /RD จากโปรเซสเซอร์ เอาต์พุตถูกป้อนเข้าประตูที่สอง โดยที่มันจะได้รับ OR อีกครั้งที่ปุ่มกด ปุ่มนี้จะทำให้อินพุตของเกทสูงขึ้น ส่งผลให้เอาต์พุตสูง เอาต์พุตนี้ถูกป้อนไปยังพินโปรเซสเซอร์ /WAIT ในขณะที่ไม่ได้กด ตัวต้านทานจะเก็บอินพุตไว้ต่ำ ตอนแรกฉันใช้ตัวต้านทาน 10K แต่จริง ๆ แล้ว LS32 นั้นวางแรงดันไฟฟ้าไว้ที่อินพุต ตัวต้านทานไม่ได้ลดลงต่ำพอและฉันต้องแทนที่ด้วย 1K อย่างไรก็ตาม แนวคิดก็คือเมื่อมีการร้องขอการอ่าน IO ประตู OR ที่หนึ่งและที่สองจะบอกให้โปรเซสเซอร์รอ เมื่อคุณตั้งค่าสวิตช์อินพุตเป็นสิ่งที่คุณต้องการ คุณกดปุ่มและมันจะทำให้ CPU ออกจากสภาวะรอ ไฟ LED "อินพุต" สีเขียว ตามที่ฉันเรียกในขั้นตอนก่อนหน้านี้ มีการต่อสายไว้ ดังนั้นเมื่อพิน /WAIT เหลือน้อย ไฟจะสว่างขึ้น
NS
แต่เรายังไม่เสร็จ ฟลิปฟล็อปอินพุตต้องการสัญญาณเพื่อแจ้งให้ทราบเมื่ออินพุตข้อมูลถูกต้องและควรนำออกไปยัง CPU เข็มนาฬิกานี้มีการใช้งานสูง ก่อนหน้านี้เราเพิ่งเชื่อมต่อกับปุ่ม นี่ยังคงเป็นตัวเลือกที่ถูกต้อง แต่คราวนี้ฉันเลือกที่จะวางไว้บนเอาต์พุตเดียวกันกับเกท OR ที่สอง IC นี้ยังมีพิน /OE ที่ต้องขับเคลื่อนด้วย ถ้าจะให้สูง มันจะไม่ใส่ข้อมูลไปที่บัส ถ้าต่ำก็จะขับรถบัสเสมอ ในการแก้ไขปัญหานี้ ฉันแค่ใช้เกต OR ที่สาม อินพุตคือ /IORQ และ /RD และเอาต์พุตไปที่สลัก /OE โดยตรง
NS
สลักเอาต์พุตยังต้องการพินนาฬิกาเพื่อขับเคลื่อน อีกครั้งมีการใช้งานสูง ในแผนผังของฉัน ฉันวาดเกต OR ที่สี่โดยตรงเพื่อขับพินโดยใช้ /IORQ และ /WR นี่หมายความว่าเข็มนาฬิกาจะถูกตรึงไว้สูงจนกว่าจะมีการร้องขอการเขียน จากนั้นมันก็จะลดต่ำลงแล้วสูงอีกครั้ง สิ่งนี้น่าจะดีเพราะบัสข้อมูลยังคงมีข้อมูลที่ถูกต้องอยู่ทันทีหลังจากพยายามเขียน แต่จากมุมมองทางวิศวกรรมคือการออกแบบขยะ ฉันไม่ได้สังเกตเห็นข้อผิดพลาดนี้จนกระทั่งหลังจากที่ฉันถ่ายภาพสุดท้ายแล้ว แต่ฉันได้ตัดการเชื่อมต่อนั้นแล้วป้อนเอาต์พุตเกต OR ลงในอินเวอร์เตอร์ที่ไม่ได้ใช้จากตรรกะการควบคุมหน่วยความจำ จากนั้นเชื่อมต่อเอาต์พุตกับพินนาฬิกา. ฉันยังแก้ไขแผนผังและพบข้อผิดพลาดอื่นที่ฉันทำ ฉันแก้ไขมันด้วย
NS
เมื่อทำเสร็จแล้ว ฉันมีงานเพียงเล็กน้อยที่ต้องทำ นั่นคือ วงจรรีเซ็ต ฉันเพิ่มปุ่มบนบอร์ดและใช้ตัวต้านทาน 10K เพื่อให้สูงด้านหนึ่ง อีกด้านหนึ่งตรงไปที่พื้น ด้านที่อยู่สูงคือเอาต์พุต /RESET ซึ่งไปที่ชิปทุกตัวที่มีพิน /RESET (ซีพียูและสลักเอาต์พุต) ในการรีเซ็ตการเปิดเครื่องให้สำเร็จ ฉันได้เพิ่มตัวเก็บประจุไปที่เอาต์พุต /RESET แนวคิดก็คือตัวต้านทานค่าขนาดใหญ่จะทำให้ตัวเก็บประจุที่มีขนาดค่อนข้างใหญ่ชาร์จได้ช้าและตรึงหมุด /RESET ให้ต่ำสำหรับรอบสัญญาณนาฬิกาจำนวนหนึ่ง (CPU ต้องการสี่รอบสัญญาณนาฬิกา) คุณคงเดาได้แล้วว่าด้านลบของวงจรนี้คืออะไร เป็นลบเหมือนกันกับรุ่นก่อนเพราะเป็นวงจรเดียวกัน เมื่อกดปุ่ม ตัวเก็บประจุจะลัดวงจรผ่านปุ่ม สิ่งนี้ไม่ดีสำหรับทั้งฝาครอบและปุ่ม ดังนั้นหากคุณต้องการทำให้งานสร้างของคุณถาวรขึ้นอีกเล็กน้อย คุณอาจต้องการออกแบบใหม่ ฉันกำลังนึกถึงตัวจับเวลา 555 อีกตัวที่ตั้งค่าในโหมดโมโนสเตเบิล แต่ด้วยเหตุนี้วงจรคอมพิวเตอร์จึงเสร็จสิ้น เย้. ตอนนี้มันต้องการโปรแกรม
ขั้นตอนที่ 6: การเขียนโปรแกรม
การเขียนโปรแกรมสิ่งนี้เป็นฝันร้าย ฉันสร้างโปรแกรมเมอร์ Arduino EEPROM มันไม่ได้ผล ฉันสร้างอีกอันโดยอิงจากการออกแบบและการเขียนโค้ดของคนอื่น ยังไม่ได้ผล ฉันกลับไปที่วิธีการลองและจริงในการตั้งค่าที่อยู่และไบต์ข้อมูลด้วยตนเอง ยังไงก็ตาม ฉันทำมันพัง ฉันลองอีกครั้งและยังคงผิดพลาด ฉันกลับไปอีกครั้งและพบว่ามันถูกปิดโดยไบต์เดียว ดังนั้นฉันจึงแก้ไขและในที่สุดก็ใช้งานได้ ขอบคุณพระเจ้า
NS
สำหรับโปรแกรมจริง ดูเหมือนว่าจะซับซ้อนมากและน่าติดตาม แต่ก็ไม่เป็นเช่นนั้น มันค่อนข้างง่ายจริงๆ ครึ่งหนึ่งกำลังคัดลอกตัวเลขไปทั่ว อีกครึ่งหนึ่งใช้ร่วมกันระหว่างคณิตศาสตร์ 16 บิต การข้ามแบบมีเงื่อนไข และยังเป็นการคัดลอกตัวเลขรอบๆ อีกด้วย ให้ฉันผ่านมันไปและบอกคุณว่ามันทำงานอย่างไร
NS
การเริ่มต้นเพียงแค่ตั้งค่าการลงทะเบียนบางส่วนสำหรับใช้งานโดยโปรแกรม โปรแกรมวนรอบนั้นซับซ้อนกว่าเล็กน้อย แต่ไม่มากทั้งหมด ขั้นแรก รับอินพุตไปยังรีจิสเตอร์ A บนพอร์ต 00 จากนั้นรีจิสเตอร์ E จะถูกเขียนลงในหน่วยความจำ ในสองลูปแรก E register มีข้อมูลขยะ ดังนั้นเราจึงพยายามเขียนมันลงในพื้นที่ ROM สองไบต์สุดท้ายเพราะจะไม่ถูกเขียนจริงๆ ตัวชี้ที่อยู่ (IY) จะเพิ่มขึ้น ค่าที่เก็บไว้ใน D จะถูกย้ายไปยัง E เพื่อเขียนต่อไป จากนั้นโหลด A ลงใน D และ L และ E จะถูกคัดลอกไปยัง H. HL เป็นที่ที่การเปรียบเทียบค่าเกิดขึ้นผ่านการลบและการตรวจสอบ ZF (แฟล็กศูนย์) ค่าแรกที่เปรียบเทียบจะถูกเก็บไว้ในรีจิสเตอร์ B และ C B และ C ถือเป็นรีจิสเตอร์ 16 บิตเดียว BC หากค่าเท่ากัน โปรแกรมจะกระโดดตรงไปยังพื้นที่ RAM โดยที่รหัสผู้ใช้จะคงอยู่ หากรหัสใน BC ไม่ตรงกัน HL จะถูกโหลดใหม่ด้วยค่าเริ่มต้นจาก D และ E และเปรียบเทียบอีกครั้งกับค่าใน SP ในลักษณะเดียวกับที่เปรียบเทียบกับ BC หากเป็นการจับคู่ จะมีผลลัพธ์เหมือนกัน แต่มีการเขียนไบต์พิเศษสามไบต์ลงในหน่วยความจำ ไบต์คือรหัสที่ทำให้ CPU กระโดดกลับไปที่จุดเริ่มต้นของโปรแกรม (การรีเซ็ตซอฟต์แวร์) หากการเปรียบเทียบครั้งที่สองไม่ตรงกัน โปรแกรมจะวนซ้ำไปยังตำแหน่งที่ดึงค่าจากผู้ใช้
NS
LD SP, EDBFH; รหัส exe (เพิ่มการกระโดด)
NS
LD IY, FFEH; ตัวชี้หน่วยความจำเริ่มต้นสำหรับการจัดเก็บรหัส
NS
LD BC, EDC3H; รหัส exe (ไม่มีการวนซ้ำ)
NS
ห่วง; assembler directive จะได้ไม่ต้องรู้ว่าส่วนนี้อยู่ตรงไหน
NS
ใน, (00H); รับข้อมูลโปรแกรม
NS
LD (IY+00H), E; E มีรหัสที่จะจัดเก็บ
NS
อิงค์ ไอ วาย; ย้ายไปยังตำแหน่งหน่วยความจำถัดไป
NS
แอลดี อี, ดี; ld D เท่ากับ E
NS
แอลดี ดี เอ; จาก A เป็น D
NS
แอลดี เอช, อี; ld E เท่ากับ H
NS
แอลดี แอล ดี; ld D เท่ากับ L
NS
หรือ; รีเซ็ตธงพกพา
NS
SBC HL, BC; คืนค่า 0 หากป้อนรหัส exe 2
NS
JP Z, 1000H; ถ้าใช่ ให้ข้ามไปที่และรันโปรแกรม
NS
แอลดี เอช, อี; มิฉะนั้น ให้รีเฟรชสิ่งเหล่านี้เป็นค่าที่เหมาะสม
NS
LD L, D
NS
หรือ; การลบครั้งแรกอาจมีการตั้งค่าสถานะการพกพา เคลียร์เลย
NS
เอสบีซี เอชแอล เอสพี; คืนค่า 0 หากป้อนรหัส exe 1
NS
JP NZ, ลูป; ถ้าไม่ ทำซ้ำขั้นตอน (เริ่มต้นด้วยการรับค่า)
NS
LD (IY+00H), C3H; มิฉะนั้น ให้ใส่รหัสกระโดดที่ส่วนท้ายของโปรแกรมผู้ใช้
NS
LD (IY+01H), 00H; โดยทั่วไปการกระโดดจะทำหน้าที่เป็นการรีเซ็ตซอฟต์แวร์
NS
LD (IY+02H), 00H; เป็นการรีเซ็ตแบบเต็มในกรณีที่รีจิสเตอร์ถูกแก้ไข
NS
JP 1000H; ข้ามไปที่และรันโปรแกรมผู้ใช้
แนะนำ:
Z80-MBC2 การเขียนโปรแกรม Atmega32a: 6 ขั้นตอน
Z80-MBC2 การเขียนโปรแกรม Atmega32a: ก่อนที่คุณจะสามารถใช้ z80-MBC2 หลังจากสร้าง คุณต้องตั้งโปรแกรม Atmeg32 คำแนะนำเหล่านี้แสดงวิธีใช้ Arduino mini ราคาถูกเป็นโปรแกรมเมอร์เพื่ออัปโหลดรหัส
Z80 MBC2 - คอมไพล์ QP/M Bios และ Loader อีกครั้ง: 6 ขั้นตอน
Z80 MBC2 - คอมไพล์ QP/M Bios และ Loader ใหม่: หากคุณพบว่าตัวเองอยู่ในตำแหน่งที่คุณต้องคอมไพล์ QP/M bios สำหรับ MBC2 ของคุณใหม่ - นี่คือวิธีที่คุณทำ ฉันบันทึกไว้ ขั้นตอนวิธีการคอมไพล์เวอร์ชันที่มีอยู่ใหม่ การเปลี่ยนแปลง Bios จริงขึ้นอยู่กับคุณ
Z80-mbc2 ไฟ LED ผู้ใช้รหัส Z80: 3 ขั้นตอน
Z80-mbc2 Z80 Code Flash User LED: นี่เป็นตัวอย่างโปรแกรม LED สำหรับผู้ใช้ที่เขียนด้วย Z80 assembler สำหรับคอมพิวเตอร์ z80-mbc2 ฉันได้ทดสอบและแก้ไขแบบฝึกหัดนี้เป็นโปรแกรม Z80 แรกของฉันมากว่า 35 ปี ขอให้สนุก
Z80 MBC2 - คอมไพล์ CPM2.2 Bios อีกครั้ง: 4 ขั้นตอน
Z80 MBC2 - คอมไพล์ CPM2.2 Bios ใหม่: ถ้าอย่างฉัน คุณพบว่าตัวเองอยู่ในตำแหน่งที่คุณต้องคอมไพล์ CP/M bios (2.2) ใหม่สำหรับ MBC2 ของคุณ - นี่คือวิธีที่คุณทำใน กรณีของฉัน ฉันต้องการลบข้อความ "WARM BOOT" ทุกครั้งที่มีโปรแกรมหรือเมื่อคุณทำ ctrl-c ฉัน
การใช้เทอร์มินัล ESP32/VGA32 สำหรับ Z80-MBC2: 7 ขั้นตอน
การใช้เทอร์มินัล ESP32/VGA32 สำหรับ Z80-MBC2: วิธีสร้างและติดตั้งซอฟต์แวร์เทอร์มินัล ANSI บนบอร์ด ESP32/VGA32 จากนั้นเชื่อมต่อกับบอร์ด Z80-MBC2