ข้อ 6 · 10 คะแนน

ทำซ้ำข้อ 2 สำหรับระบบใหม่
ที่เริ่มด้วย RAM แล้วตามด้วย ROM ทันที

10 คะแนนนี้ได้ฟรีถ้าเข้าใจข้อ 2 แล้ว — วิธีคิดเหมือนเดิมทุกอย่าง เปลี่ยนแค่ค่าบิต แต่ มีประเด็นหนึ่งที่ถ้าเขียนถึงจะแยกจากคนอื่นได้ทันที

6.1 ผังใหม่

ผังเดิม (ข้อ 1–2)

0000H – 0FFFHROM 4 KB
1000H – 1FFFHRWM 4 KB
2000H – FFFFHว่าง
CEROM = A15+A14+A13+A12 + MREQ
CERAM = A15+A14+A13+A12 + MREQ

ผังใหม่ (ข้อ 6)

0000H – 0FFFHRWM 4 KB
1000H – 1FFFHROM 4 KB
2000H – FFFFHว่าง
CERAM = A15+A14+A13+A12 + MREQ
CEROM = A15+A14+A13+A12 + MREQ

สลับแค่ว่าขา A12 ของใครมีวงกลม — วงจรเหลือเหมือนเดิมทุกอย่าง

6.2 ประเด็นสำคัญที่ทำให้ข้อนี้ไม่ใช่แค่การสลับตัวเลข

Z80 หลัง RESET จะเริ่มทำงานที่ 0000H เสมอ

เมื่อ RESET ถูกดึงลง (อย่างน้อย 3 clock) Z80 จะทำ PC ← 0000H, I ← 00H, R ← 00H, ปิด interrupt, ตั้ง interrupt mode 0
แปลว่า คำสั่งแรกที่ CPU ดึงมา execute อยู่ที่ตำแหน่ง 0000H

ถ้าเอา RAM ไปวางที่ 0000H — ตอนเปิดเครื่อง RAM ยังไม่มีข้อมูล (ค่าสุ่มหรือ 00H/FFH ทั้งหมด) CPU จะ fetch เจอขยะแล้วทำงานมั่ว ระบบบูตไม่ขึ้น

ตำแหน่งพิเศษที่โดนกลืนไปด้วย

Addressใช้ทำอะไรผลเมื่อกลายเป็น RAM
0000HReset vector · RST 00Hไม่มีโค้ดตอนบูต
0008HRST 08Hต้องเขียนโค้ดลงไปก่อนใช้
0010H / 0018H / 0020H
0028H / 0030H / 0038H
RST 10H–38H · และ 0038H คือปลายทางของ INT mode 1interrupt mode 1 ใช้ไม่ได้จนกว่าจะเขียนโค้ดลง RAM
0066Hปลายทางของ NMINMI จะกระโดดไปที่ RAM ว่างเปล่า

ถ้าจำเป็นต้องทำจริง ทำได้ไหม

ได้ แต่ต้องเพิ่มวงจร — เขียนถึงข้อใดข้อหนึ่งก็พอ

  1. ROM shadow ตอนบูต (นิยมที่สุด) ใช้ flip-flop ตัวหนึ่งที่ถูก reset พร้อม CPU ให้ ROM ตอบที่ 0000H ชั่วคราว โปรแกรมบูตคัดลอกตัวเองลง RAM แล้ว OUT ไปพลิก flip-flop หลังจากนั้น 0000H จึงเป็น RAM จริง
  2. Bank switching ใช้ latch เก็บหมายเลข bank แล้วเอา output ของ latch ไปร่วม decode สลับ ROM/RAM เข้าออกช่วง 0000H ได้ตามต้องการ
  3. ยอมรับว่าเป็นระบบที่ต้องโหลดโปรแกรมจากภายนอก เช่นบอร์ดทดลองที่มี monitor ROM อยู่ที่อื่น แล้ว JP ลงมาที่ RAM — แบบนี้ 0000H เป็น RAM ได้ ถ้าไม่ต้องบูตเอง

โจทย์หลักตามที่อาจารย์ประกาศ

โจทย์หลัก · 10 คะแนน

จงทำซ้ำข้อที่ 2 สำหรับการออกแบบระบบใหม่ โดยออกแบบให้เริ่มด้วยหน่วยความจำแบบ RAM และตามด้วย ROM ทันที

ดูเฉลย

ส่วนที่ 1 · แผนที่และเงื่อนไขการเลือกชิป

ชิปช่วงเข้าชิปเงื่อนไข decodeสมการ
RWM 4 KB0000H – 0FFFHA11–A0A15 A14 A13 A12 = 0000 CE = A15+A14+A13+A12+MREQ
ROM 4 KB1000H – 1FFFHA11–A0A15 A14 A13 A12 = 0001 CE = A15+A14+A13+A12+MREQ

ส่วนที่ 2 · การเข้าถึงทีละบิต

ตัวอย่าง CPU อ่านตำแหน่ง 1234H (อยู่ในช่วง ROM)

1234H = 0001 0010 0011 0100
        A15–A12 = 0001  → ตรงเงื่อนไขของ ROM ⇒ CEROM = 0
        A11–A0  = 234H  → เซลล์ที่ 234H ภายในชิป ROM
        MEMRD = 0 → เปิด OE → ข้อมูลออก D7–D0

ตัวอย่าง CPU เขียนตำแหน่ง 0234H (อยู่ในช่วง RWM)

0234H = 0000 0010 0011 0100
        A15–A12 = 0000  → CERWM = 0
        A11–A0  = 234H
        MEMWR = 0 → เปิด WE → ข้อมูลจาก D7–D0 ถูกเขียนลงเซลล์
        (ถ้าเขียนที่ 1234H จะไม่เกิดอะไรขึ้น เพราะ ROM ไม่มีขา WE)

ส่วนที่ 3 · Foldback

d = 16 − n − k
d = 0
ภาพต่อชิป
1
สรุป
สลับ ROM ↔ RAM ไม่ทำให้เกิด foldback
foldback ขึ้นกับ “ใช้สาย address กี่เส้น” ไม่ใช่ “วางชิปเรียงยังไง”
ชิปnkd = 16−n−kภาพสรุป
RWM 4 KB12401ไม่มี foldback
ROM 4 KB12401ไม่มี foldback

สรุป: การสลับลำดับ ROM ↔ RAM ไม่มีผลต่อการเกิด foldback เลย เพราะ foldback ขึ้นกับจำนวนสาย address ที่ถูกใช้ ไม่ได้ขึ้นกับว่าชิปวางเรียงยังไง — ตราบใดที่ยัง decode A15–A12 ครบทั้ง 4 เส้น ก็ยังไม่มีภาพซ้ำ และช่วง 2000H–FFFFH ยังคงว่างเหมือนเดิม

ส่วนที่ 4 · ข้อแตกต่างที่สำคัญกว่า foldback (ตรงนี้แหละที่ได้คะแนน)

แม้ผลเรื่อง foldback จะเหมือนเดิมเป๊ะ แต่ระบบใหม่มีปัญหาเชิงการทำงานที่ระบบเดิมไม่มี:

  1. บูตไม่ขึ้น — Z80 หลัง RESET ตั้ง PC = 0000H ซึ่งตอนนี้เป็น RWM ที่ยังไม่มีข้อมูลตอนเปิดเครื่อง CPU จะ fetch ค่าขยะมา execute
  2. เสีย vector ทั้งหมด — RST 00H–38H และปลายทางของ interrupt mode 1 (0038H) รวมถึง NMI (0066H) ตกอยู่ในช่วง RWM ทั้งหมด ใช้ไม่ได้จนกว่าจะมีคนเขียนโค้ดลงไปก่อน
  3. โปรแกรมหายเมื่อดับไฟ — โค้ดที่โหลดลง RWM ไม่คงอยู่

ทางแก้: ต้องเพิ่มวงจร ROM shadow / bank switching ที่ทำให้ ROM ตอบที่ 0000H ชั่วคราวตอน reset แล้วค่อยสลับเป็น RAM ภายหลังด้วยคำสั่ง OUT

ประโยคสรุปที่ควรเขียนปิดท้าย

“การสลับลำดับหน่วยความจำไม่ทำให้เกิด Memory Foldback เพิ่มขึ้นหรือลดลง เพราะ foldback เกิดจากการที่มีสาย address เหลือเป็น don't care เท่านั้น ในการออกแบบนี้ยังใช้ A15–A12 ครบทั้ง 4 เส้นเหมือนเดิม จึงยังเป็น full decoding (d = 0, 1 ภาพ) แต่การวาง RAM ไว้ที่ 0000H จะทำให้ระบบไม่สามารถบูตเองได้ เนื่องจาก Z80 กำหนดให้ PC = 0000H หลัง reset เสมอ จึงต้องมีวงจรเสริมเพื่อให้ ROM ปรากฏที่ตำแหน่งนั้นในช่วงเริ่มต้น”

เปรียบเทียบให้เห็นภาพ

ปรับด้านล่างเพื่อดูว่าถ้า decode ไม่ครบ ผังใหม่จะเกิด foldback แบบไหน

สรุป

แผนที่ 64 KB

ตัวอย่างเพิ่มอีก 5 ข้อ

ตัวอย่างที่ 1

ระบบใหม่: RAM 8 KB ที่ 0000H ตามด้วย ROM 8 KB ทันที จงเขียนสมการ CE ทั้งสอง และบอกช่วง address ของ ROM

เฉลยตัวอย่างที่ 1

ชิป 8 KB ⇒ n = 13 (A12–A0) ⇒ เหลือ A15 A14 A13 = 3 เส้น

RAM  0000H – 1FFFH   ⇒ A15 A14 A13 = 000
ROM  2000H – 3FFFH   ⇒ A15 A14 A13 = 001

CERAM = A15 + A14 + A13 + MREQ
CEROM = A15 + A14 + A13 + MREQ

d = 16 − 13 − 3 = 0 ⇒ ไม่มี foldback · หรือใช้ 74LS138 ก็ได้: Y0 → RAM, Y1 → ROM

ตัวอย่างที่ 2

ถ้าออกแบบ RAM 4 KB ที่ 0000H และ ROM 4 KB ที่ 1000H แต่ decode ด้วย A12 เพียงเส้นเดียว จงหาจำนวนภาพซ้ำและช่วงของแต่ละภาพ

เฉลยตัวอย่างที่ 2

n = 12, k = 1 ⇒ d = 3 ⇒ 2³ = 8 ภาพต่อชิป · don't care = A15 A14 A13 ⇒ ห่างกันทุก 2000H

RAM (A12 = 0): 0000, 2000, 4000, 6000, 8000, A000, C000, E000  (แต่ละภาพยาว 1000H)
ROM (A12 = 1): 1000, 3000, 5000, 7000, 9000, B000, D000, F000
ผลที่ตามมา

RAM ปรากฏที่ 0000H → ยังบูตไม่ขึ้นเหมือนเดิม และตอนนี้ทั้ง 64 KB ถูกจองหมด ขยายไม่ได้เลย
แต่มีจุดน่าสนใจ: ROM ปรากฏที่ F000H–FFFFH ด้วย ถ้าตั้ง SP = 0000H แล้ว PUSH จะเขียนไปที่ FFFFH ซึ่งเป็น ROM → เขียนไม่ติด stack พังทันที

ตัวอย่างที่ 3

จงอธิบายว่าเพราะเหตุใดระบบไมโครโพรเซสเซอร์ส่วนใหญ่จึงวาง ROM ไว้ต้นปริภูมิ address เสมอ และยกตัวอย่างสถาปัตยกรรมที่ทำตรงกันข้าม

เฉลยตัวอย่างที่ 3

เพราะ CPU ส่วนใหญ่กำหนด reset vector ไว้ที่ address ต่ำ ๆ ตายตัว:

CPUหลัง reset PC = ?
Z800000H
8080 / 80850000H
6502อ่าน vector จาก FFFCH–FFFDH ⇒ ROM ต้องอยู่ปลายปริภูมิ
68000อ่าน SP จาก 000000H และ PC จาก 000004H ⇒ ROM ต้องอยู่ต้น

6502 คือตัวอย่างที่ทำตรงกันข้าม — RAM อยู่ต้น (zero page ที่ 0000–00FF ใช้เป็น addressing mode พิเศษที่เร็วกว่า) และ ROM อยู่ปลาย ซึ่งเป็นเหตุผลว่าทำไม Apple II / Commodore 64 / NES จึงวาง ROM ไว้ท้ายแผนที่

ตัวอย่างที่ 4

จงออกแบบวงจร ROM shadow อย่างง่ายที่ทำให้ ROM ตอบที่ 0000H ตอน reset แล้วสลับให้ RAM ตอบแทนเมื่อโปรแกรมสั่ง OUT (FEH),A

เฉลยตัวอย่างที่ 4
ใช้ D flip-flop 1 บิต (เช่น ครึ่งหนึ่งของ 74LS74) ตั้งชื่อว่า BOOT

  CLR ของ flip-flop  ← RESET ของ Z80     ⇒ หลัง reset  BOOT = 0
  CLK ของ flip-flop  ← SEL_FE + IOWR   ⇒ OUT (FEH),A ทำให้ BOOT = 1
  D   ของ flip-flop  ← +5V

สมการเลือกชิป:
  CEROM = ( BOOT · A15A14A13A12=0000 )        ; ตอนบูต ROM ตอบที่ 0000H
          + (  BOOT · A15A14A13A12=0001 )        ; หลังบูต ROM กลับไปที่ 1000H
  CERAM = BOOT · A15A14A13A12=0000                 ; RAM ตอบที่ 0000H เฉพาะหลังบูต

ลำดับการทำงาน:

  1. เปิดเครื่อง → RESET ทำให้ BOOT = 0 → ROM ตอบที่ 0000H
  2. CPU fetch จาก ROM แล้วคัดลอกโค้ดที่จำเป็นลง RAM (ตอนนี้ RAM ยังอยู่ที่อื่นหรือยังเข้าไม่ได้)
  3. โปรแกรมสั่ง OUT (FEH),A → BOOT = 1 → RAM มาตอบที่ 0000H, ROM ย้ายไป 1000H
  4. ระบบเดินต่อด้วยผัง “RAM ก่อน ROM” ตามโจทย์
ตัวอย่างที่ 5

ระบบใหม่วาง RAM 32 KB ที่ 0000H และ ROM 16 KB ต่อทันที จงหาช่วง address, สมการ CE, จำนวนภาพซ้ำ และช่วงที่ยังว่าง

เฉลยตัวอย่างที่ 5
RAM 32 KB ⇒ n = 15 (A14–A0) ⇒ 0000H – 7FFFH ⇒ A15 = 0
ROM 16 KB ⇒ n = 14 (A13–A0) ⇒ 8000H – BFFFH ⇒ A15 A14 = 10

CSRAM = A15 + MREQ                  k = 1 ⇒ d = 16−15−1 = 0
CEROM = A15 + A14 + MREQ            k = 2 ⇒ d = 16−14−2 = 0

ทั้งคู่ decode เต็ม ⇒ ไม่มี foldback

ช่วงว่าง: C000H – FFFFH (16 KB) เพราะ A15 A14 = 11 ไม่มีชิปตอบ
ข้อดีของผังนี้: ตั้ง SP = 8000H ได้พอดี (stack โตลงมาในช่วง RAM) ข้อเสียเดิม: ยังบูตไม่ได้ เพราะ 0000H เป็น RAM

← ข้อ 5 · Timing สไลด์ผิด →