[ บทความ : เรียนรู้ z80 ] ตอนที่ 4 เรื่อง โปรแกรมต้นแบบ และข้อมูลที่จำเป็น |
สวัสดีครับ เรามาเจอกันอีกครั้ง ในเรื่องของ z80 ตอนแรกนั้น ผมคาดว่าจะ เป็นบทความที่เน้นทั้ง การใช้โปรแกรม มอนิเตอร์ และเขียนเองจาก assembler [ download assembler ] ตอนนี้เอาเป็นว่า เขียนเองด้วย assembler เลยดีกว่านะครับ จะได้เป็นการฝึกหัด และเพิ่มทักษะการเขียนโปรแกรมด้วยตนเองไปด้วยกันเลย... ก่อนที่เราจะเริ่มเขียนโปรแกรมได้นั้น นอกจากจะมีตัวแปลภาษาแอสเซมบลีแล้ว เรายังจะต้องเข้าใจถึงความสามารถของไมโครโปรเซสเซอร์ที่ เราใช้ด้วยนะครับ ไม่อย่างนั้น เราจะไม่มีทางเขียนสั่งการไมโครโปรเซสเซอร์ตัวนั้นได้อย่างเต็มประสิทธิภาพเลยทีเดียว ... ยิ่งจะเอาไปประยุกต์ใช้ ด้วยแล้วล่ะก็ยิ่งยากเข้าไปอีกหลายขุม ... ดังนั้น ขอให้อ่านทบทวนบทความเก่า ๆ ให้เข้าใจก่อนนะครับ ... พอเราเข้าใจโครงสร้าง และ ความสามารถของไมโครโปรเซสเซอร์แล้ว ขั้นตอนต่อไปก็มาดูเรื่องฮาร์ดแวร์ที่จะใช้งาน (CPU+MEM+I/O+OS) ... นี่ล่ะที่ลำบากรองลงมา เพราะถ้าเป็นฮาร์ดแวร์ที่เราออกแบบเอง เราก็จะสามารถเข้าใจมันได้เป็นอย่างดี (ผมไม่เคยเห็นคนที่ออกแบบเอง แล้วไม่รู้ว่าตัวเองทำอะไรไป ... ฮา) แต่สำหรับมือสมัครเล่น อย่างผมแล้ว (เน้นนะครับ ว่าผมสมัครเล่น) การออกแบบเอง ยิ่งเป็นไปอย่างยากลำบากทีเดียว (ความยากลำบาก = เกียจคร้าน-1+เกียจคร้าน-2+เกียจคร้าน-3+...+เกียจคร้าน-n+ไม่มีเวลา ... อันนี้ล้อเล่นครับ) เอาเป็นว่าผมเลือกใช้ ET-BOARD V6 ล่ะกันครับ ... ส่วนพวกบอร์ดควบคุม ที่ไม่ใช่ Single board อย่าง บอร์ด jrZ180 ขอเอาไว้กล่าวรายละเอียดทีหลังล่ะกันครับ ...
การจัดสรรหน่วยความจำของ ET-BOARD V6
ขอไม่กล่าวถึงวิธีการใช้โปรแกรมมอนิเตอร์นะครับ เพราะคู่มือของบอร์ดคงอธิบายได้เป็นอย่างดีแล้ว ... เจ้าบอร์ด V6 นั้น มีการ จัดสรรหน่วยความจำดังนี้ครับ
0000H-7FFFH โปรแกรมมอนิเตอร์ และฟังก์ชันเสริม (32KB) 8000H-BDFFH สำหรับผู้ใช้ BE00H-BFFFH ใช้งานโดยโปรแกรมมอนิเตอร์ C000H-DFFFH หน่วยความจำขยาย (ใช้ได้เพียง 8KB)จากการจัดสรรหน่วยความจำดังกล่าว ทำให้เวลาที่เราเขียนโปรแกรมนั้นจะต้องกำหนดให้โปรแกรมของเราทำงานในช่วง 8000H-BDFFH กับ C000H-DFFFH ... ส่วนรายละเอียดของ I/O จะมีดังนี้00H 8255 System I/O - Port A 01H 8255 System I/O - Port B 02H 8255 System I/O - Port C 03H 8255 System I/O - Control port 20H 8255 USER - Port A 21H 8255 USER - Port B 22H 8255 USER - Port C 23H 8255 USER - Control port 4DH SCN2681 - User switch (4 bit, IP0-IP3) 4EH SCN2681 - User LED (Set-Output, 4 bit, OP0-OP3) 4FH SCN2681 - User LED (Reset-Output, 4 bit, OP0-OP3) 60H CH-LCD - Write command 61H CH-LCD - Read command 62H CH-LCD - Write data 63H CH-LCD - Read data 64H GR-LCD - Write command (Page 1) 65H GR-LCD - Read command (Page 1) 66H GR-LCD - Write data (Page 1) 67H GR-LCD - Read data (Page 1) 68H GR-LCD - Write command (Page 2) 69H GR-LCD - Read command (Page 2) 6AH GR-LCD - Write data (Page 2) 6BH GR-LCD - Read data (Page 2)ทั้งหมดเป็นรายละเอียดของบอร์ดที่เราสมควรจะรู้ครับ เพราะ ถ้าเราไม่รู้ว่า เขาออกแบบให้มีอะไรอยู่ที่ใด การเขียนโปรแกรม ก็ทำได้ลำบากมากครับ ยิ่งถ้าไม่มีวงจรให้ไล่ด้วยแล้วล่ะก็ ฝันร้ายสุด ๆ (ใครไม่เคยเจอแบบว่า ... เอาบอร์ดมาให้แล้วก็ให้หาว่า วงจรมันเป็นอย่างไร ... รับรองไม่เข้าใจหรอกครับว่าผมกล่าวถึงอะไร) ตอนนี้รู้รายละเอียดที่จำเป็นไปแล้ว ... คราวนี้มาลอง เขียนโปรแกรมต้นแบบกันก่อนนะครับ
โปรแกรมต้นแบบ สำหรับ ET-V6
เพื่อความสะดวก ผมแยกไฟล์ต้นแบบเป็น 2 ส่วน คือ ส่วนที่เรียกว่าเป็น header-file หรือไฟล์ส่วนหัว (.inz) ซึ่งมีหน้าที่ เป็นไฟล์ที่เก็บข้อมูลของค่าคงที่ต่าง ๆ เช่น ตำแหน่งของหน่วยความจำ , ตำแหน่งของ I/O เป็นต้น ... ส่วนที่ 2 เป็นไฟล์ภาษาแอสเซมบลี (.asz) เอาไว้สำหรับเขียนโปรแกรม
ไฟล์ส่วนหัวมีข้อมูลดังนี้ครับ
; ; filename : etv6.inz ; assembler : az80 ; author : Supachai Budsaratij (raek@se-ed.net) ; hardware : et-board 6 (Z-80 mode) ; date : October 12,2000 ; ; --- MEMORY ; UMEM_ORG EQU 08000h ; User RAM start UMEM_END EQU 0BDFFh ; User RAM end XMEM_ORG EQU 0C000h ; Expand RAM end XMEM_END EQU 0DFFFh ; Expand RAM end ; --- I/O ; S8255_PA EQU 00h ; System 8255 port A S8255_PB EQU 01h ; System 8255 port B S8255_PC EQU 02h ; System 8255 port C S8255_CT EQU 03h ; System 8255 control port ; U8255_PA EQU 20h ; User 8255 port A U8255_PB EQU 21h ; User 8255 port B U8255_PC EQU 22h ; User 8255 port C U8255_CT EQU 23h ; User 8255 control port ; SCN_INP EQU 4Dh ; SCN2681 - Input port (Switch) SCN_SEO EQU 4Eh ; SCN2681 - Set output port (LED) SCN_REO EQU 4Fh ; SCN2681 - Reset output port (LED) ; CLCD_WC EQU 60h ; Character LCD write command CLCD_RC EQU 61h ; Character LCD read command CLCD_WD EQU 62h ; Character LCD write data CLCD_RD EQU 63h ; Character LCD read data ; GLCD_WC1 EQU 64h ; Graphics LCD write command (Page 1) GLCD_RC1 EQU 65h ; Graphics LCD read command (Page 1) GLCD_WD1 EQU 66h ; Graphics LCD write data (Page 1) GLCD_RD1 EQU 67h ; Graphics LCD read data (Page 1) ; GLCD_WC2 EQU 68h ; Graphics LCD write command (Page 2) GLCD_RC2 EQU 69h ; Graphics LCD read command (Page 2) GLCD_WD2 EQU 6Ah ; Graphics LCD write data (Page 2) GLCD_RD2 EQU 6Bh ; Graphics LCD read data (Page 2) ;จากข้อมูลในไฟล์ส่วนหัว จะเห็นว่า ผมสร้างค่าคงที่ขึ้นมาแทนการใช้เป็นค่าตัวเลข ทั้งนี้ก็เพื่อความสะดวก ในการเรียก แถมเมื่อเราต้องการเขียนโปรแกรมแบบ อ้างชื่อเดียวกัน แต่ตำแหน่งต่างกัน เช่น ตำแหน่งของหน่วยความจำเริ่มต้น บนบอร์ด ET-V6 อยู่ที่ 8000H (ตั้งชื่อเอาไว้เป็น UMEM_ORG) แต่ในบอร์ด ET-V3.5 ตำแหน่งจะเป็น 2000h ถ้าเป็นการ เขียนแบบทั่วๆ ไป เราจะต้องเปลี่ยนค่าของตำแหน่งเอง แต่พอเราตั้งชื่อเป็นชื่อเดียวกัน ในไฟล์ส่วนหัว เราก็ไม่ต้องไปแก้ไขข้อมูล เลย ... เป็นการประหยัดเวลา และยืดหยุ่นต่อการเขียนโปรแกรมแบบโครงสร้างเดียว แต่ใช้กับหลาย ๆ บอร์ด เลยล่ะครับ (เหมือน ไลบรารี ภาษาซี สำหรับ MCS-51 : Munc5x ที่ผมเขียนไงครับ) ...
ส่วนข้อมูลด้านล่างนี้เป็นข้อมูลของไฟล์ภาษาแอสเซมบลีที่เราเขียนกัน
; ; filename : tmplate.asz ; assembler : az80 ; author : Supachai Budsaratij (raek@se-ed.net) ; date : October 12,2000 ; ; compile : az80 tmplate.asz -l tmplate.lst -o tmplate.hex ; INCL "etv6.inz" ; Inlude header for ET-V6 ORG UMEM_ORG ; Start at UMEM_ORG main ; --- Your program start here... HALT ; Terminate (HALT) CPU END ; End of source codeเอาล่ะครับ ตอนนี้เราได้ไฟล์ต้นแบบมาแล้วครับ ... โปรแกรมนี้ทำอะไรบ้าง พอมองปุ้บ ก็จะเห็นว่า มันทำอย่างเดียวคือ HALT หรือหยุดทำงานนั่นเอง ... นั่นหมายความว่า เมื่อโปรแกรมองเราเริ่มทำงานปุ๊บ มันก็หยุดทำงานทันทีเลย ... ง่ายไปนิดใช่ไหมครับ เอาไว้คราวหน้าค่อยศึกษากันไปเรื่อยๆ ล่ะกันครับ (นะๆ) ...
การคอมไพล์
ตอนนี้เราก็เหลือขั้นตอนอีก 3 ขั้นตอนเท่านั้น คือ ทำการแปลงให้เป็น machine-code, download ไปที่บอร์ด และ ทดสอบโปรแกรม ... ตอนนี้มาสั่งคอมไพล์กันครับ ... คำสั่งที่ผมใช้ก็คือ
az80 tmplate.asz -l tmplate.lst -o tmplate.hexที่หน้าจอของเครื่องหลังจากที่แปลเสร็จ โดยไม่มีความผิดพลาด จะเป็นดังนี้ครับ ... ส่วนถ้าผิดพลาดจะมีการรายงานว่า ผิดพลาดเป็นจำนวน error เท่าใด แล้วให้ผู้อ่านเปิดไฟล์ .lst มาดูว่ามีบรรทัดใดบ้างที่ผิด (ไม่น่าจะพิมพ์ผิดจริงไหมครับ... มือระดับนี้แล้ว :D)
หลังจากนี้เราจะมีไฟล์เพิ่มขึ้นมา 2 ไฟล์ คือ .lst และ .hex เราจะเอาไฟล์ .hex มาใช้สำหรับ download ลงบอร์ดครับ...
Download ไฟล์ .hex
ก่อนที่จะทำการ download เรามาทำความรู้จักกับคำว่า download กันก่อน ... download ก็คือ กระบวนการที่เรา นำข้อมูลจากเครื่องคอมพิวเตอร์ของเรา ส่งไปยังเครื่องคอมพิวเตอร์ หรืออุปกรณ์ปลายทาง ... ดังนั้น การ download ไฟล์ .hex ก็คือ การส่งไฟล์ .hex จากเครื่องคอมพิวเตอร์ที่เราเขียนโปรแกรม ส่งไปยังบอร์ด z80 นั่นเอง ... ขั้นตอนเป็นดังนี้ครับ
1. จ่ายไฟเลี้ยงแก่บอร์ด
2. ต่อสาย RS232 ระหว่างเครื่องคอมพิวเตอร์กับบอร์ด
3. เรียกโปรแกรม hyper terminal หรือ โปรแกรมสื่อสารอนุกรม แล้วกำหนดค่าในการทำงานของ hyperterminal ดังนี้
3.1 เลือก File, Properties แล้วจะแสดงหน้าจอดังนี้4. เลือกโหมดการทำงานของบอร์ดเป็น remote debugger โดยกด FUNC,3,INC แล้วที่หน้าจอของโปรแกรม hyper terminal จะแสดงดังนี้
3.2 เลือกว่าเราใช้พอร์ตใดอยู่จาก Connect using: (ตามรูปด้านบน ผมใช้ COM1)
3.3 เลือกกดที่ปุ่ม Configure... แล้วแสดงหน้าจอดังนี้
3.4 ให้กำหนดข้อมูลต่าง ๆ ตามรูปตัวอย่างด้านบน
5. ตอนนี้แสดงว่าเราพร้อมที่จะทำการ download แล้วครับ ... สั่ง L แล้วจะแสดงผลดังนี้
6. ตอนนี้ บอร์ดกำลังรอให้เราส่งไฟล์ไปให้อยู่ครับ ... เราก็เลือกส่งไฟล์ โดยเลือกที่เมนู Transfer, Send Text file... ดังรูปด้านล่าง
7. เมื่อเราเลือกตามข้อ 6 ก็จะมีหน้าจอ ให้เราเลือกไฟล์ที่จะ download คล้าย ๆ กับรูปด้านล่างนี้ โดยให้ผู้อ่านหาไฟล์ tmplate.hex ให้เจอ แล้วกดปุ่ม Open
8. เสร็จแล้ว ที่หน้าจอโปรแกรม Hyper Terminal ก็จะรายงานออกมาว่า ส่งไฟล์เป็นที่เรียบร้อย ดังรูปด้านล่างนี้
เรียบร้อยไปลแวครับ สำหรับขั้นตอน download ...
เรียกโปรแกรมให้ทำงาน
ตอนนี้โปรแกรมที่เราเขียนเสร็จไปลแวนั้นจอยู่ที่หน่วยความจำของบอร์ด เป็นที่เรียบร้อย ขั้นตอนสุดท้ายของเราก็คือ การ เรียกโปรแกรมที่เรา download ไปที่บอร์ดให้มันทำงาน ... การสั่งการก็ง่ายมากครับ คือ กด g แล้วกด Enter โปรแกรมก็จะทำงานทันที ดังรูปด้านล่างครับ
หลังจากทำงานแล้วมันก็แน่นิ่งไปเลยใช่ไหมครับ แถมที่บอร์ดนั้น หลอด LED สีเขียว (ด้านซ้ายบนของบอร์ด) ก็สว่างขึ้นมา (ดังรูปด้านล่าง) นั่นหมายความว่าเราประสบความสำเร็จแล้วครับ... เย้ !
ส่งท้าย
ตอนนี้เราก็เขียนโปรแกรม และ download พรอ้มทั้ง เรียกใช้เป็นกันแล้วนะครับ คราวหน้า ผมก็จะเริ่มเข้าสู่คำสั่ง ของ Z80 แล้วนะครับ ... บทความนี้เราเริ่มจาก 0 กันเลยนะเนี่ย ... อธิบายค่อนข้างหลายตอนแล้ว ยังไม่ได้เริ่มจริงๆ จัง เสียที ...