Wake up! 16b ที่ตื่นขึ้น
(hellmood.111mb.de)- Wake up! 16b คือเดโมอินโทร DOS แบบ x86 real mode ขนาด 16 ไบต์ ที่เปิดตัวในงาน Outline Demoparty โดยสร้างแฟรกทัล Sierpinski และเสียงพร้อมกันผ่าน text buffer
- ด้วยการตั้งค่า
int 10hและds=0xb800มันใช้หน้าจอเริ่มต้นของ โหมดข้อความ 40x25 เป็นพื้นที่คำนวณ โดยไบต์ช่องว่างและไบต์สีส่งผลต่อผลลัพธ์ที่แสดง xor [si], alทำงานคล้าย การบวกแบบไม่มีแคร์รี ทำให้เกิดโครงสร้าง Sierpinski ของ bit 1 และส่งไบต์เดียวกันไปยังลำโพง PC ด้วยout 61h, al- ลูปจริงจะเลื่อนตำแหน่ง -56 ไบต์ ในแต่ละรอบ แล้วรีเซ็ตหลังครบ 8,192 สเต็ป ทำให้เสียงต่ำลงหนึ่งอ็อกเทฟ และเกิดแพทเทิร์นที่ถูกเฉือนเฉียงเป็นเสาตัวอักษร 10 เสาบนหน้าจอ
- สภาพแวดล้อมการรัน เช่น แพตช์
0xB000สำหรับ MDA/Hercules และความต่างของ BIOS กับสถานะ RAM สามารถเปลี่ยนผลลัพธ์ได้ ทำให้อาร์ติแฟกต์ตามธรรมชาติของฮาร์ดแวร์กลายเป็นส่วนหนึ่งของ sizecoding
โครงสร้างหลักของอินโทร x86 ขนาด 16 ไบต์
- Wake up! 16b เป็นอินโทรแอสเซมบลี DOS แบบ x86 real mode ขนาด 16 ไบต์ ที่เปิดตัวในเดือนพฤษภาคม 2026 ที่งาน Outline Demoparty เมือง Ommen ประเทศเนเธอร์แลนด์
- มันใช้ text buffer ของ VGA/CGA เป็นพื้นที่คำนวณ เพื่อสร้าง แฟรกทัล Sierpinski แบบไร้ที่สิ้นสุด บนหน้าจอ และส่งข้อมูลชุดเดียวกันไปยังพอร์ตลำโพง PC เพื่อสร้างเสียง
- โค้ดทั้งหมดมีขนาด 16 ไบต์
int 10h ; 2바이트 mov bh, 0xb8 ; 2바이트 mov ds, bx ; 2바이트 L: lodsb ; 1바이트 sub si, byte 57 ; 3바이트 xor [si], al ; 2바이트 out 61h, al ; 2바이트 jmp short L ; 2바이트 - ระหว่างพัฒนา มีการสำรวจการใช้ cellular automata กับทั้งภาพและเสียง, คำสั่งแอสเซมบลีแบบโพลีมอร์ฟิกที่ทำให้
add [bx+si],alกลายเป็น0x0000, และเทคนิค sizecoding ที่กระโดดเข้ากลางคำสั่งเพื่อใช้ไบต์และ opcode ซ้ำ - ผลงานก่อนหน้านี้ "M8trix" เป็นอินโทร 8 ไบต์และ 7 ไบต์จากปี 2014 ที่ทำให้อักขระสุ่มเทียมกระจายบนหน้าจอ ส่วนใน Wake up! 16b นั้นเสียงจะมาก่อนแล้วจึงค่อยมีเอฟเฟ็กต์ภาพตามมาประกบ
หน้าจอข้อความที่ถูกเตรียมค่าเริ่มต้น
int 10hจะตั้งค่า โหมดวิดีโอ 0 เพื่อสร้างกริดโหมดข้อความ 40x25mov bh, 0xb8และmov ds, bxจะตั้งค่า data segmentdsไปยัง0xb800ซึ่งเป็นที่อยู่ของ text buffer ของ VGA/CGA- เมื่อ BIOS ล้างหน้าจอ มันไม่ได้เติมหน่วยความจำด้วยศูนย์ แต่เติมช่องอักขระ 2,000 ช่องด้วยไบต์อักขระ
0x20(space) และแอตทริบิวต์สี0x07(เทาอ่อนบนพื้นหลังดำ) - หน้าจออาจดูเหมือนว่างเปล่า แต่ในหน่วยความจำยังมีแพทเทิร์นที่สม่ำเสมอค้างอยู่ และสถานะเริ่มต้นนี้ส่งผลต่อทั้งเสียงและภาพที่ได้
- ข้อมูลก่อนและหลังวิดีโอเมมโมรีที่มองเห็นได้ รวมถึงวิธีเตรียมค่าหลัง “clear screen” ก็ถูกผสมเข้ากับผลลัพธ์ ทำให้ได้เสียงที่หยาบและมีเอกลักษณ์กว่าที่คาด
ผลรวมสะสมและโครงสร้างแบบทวินาม
- หากมองเฉพาะโครงสร้างทางคณิตศาสตร์ สามารถสมมติให้สถานะเป็น 0 แทน
0x20, ใช้addแทนxor, เลื่อนไปครั้งละ 16 ไบต์ และให้alเริ่มต้นที่ 2 - DOS segment มีขนาด 65,536 ไบต์ พอดี และถ้าเดินทีละ 16 ไบต์ จะใช้เวลา 4,096 สเต็ป ในการวนครบทั้ง segment
- 4,096 เป็นพหุคูณของ 256 ซึ่งเป็นขนาดของรีจิสเตอร์ 8 บิต ดังนั้นเมื่อ segment วนกลับ การแคร์รีโอเวอร์จะจัดแนวพอดี และ
alจะกลับไปเป็น 2 ที่จุดเริ่มของแต่ละรอบกวาด - เมื่อนำค่าระหว่างเซลล์มาบวกสะสมต่อเนื่อง จะเกิดเป็น ผลรวมส่วนหน้า (prefix sum) และค่าจะคลี่ออกคล้ายลำดับสัมประสิทธิ์ทวินามที่สเกลด้วย 2
- หากดูหลาย ๆ pass ของ 16 เซลล์แรก จะเห็นว่าค่าถูกสะสมเป็นรายแถว และเพราะเป็นค่า 8 บิต ส่วนที่เกิน 256 จะวนกลับและปรากฏเป็นค่าขนาดเล็กอีกครั้ง
XOR และโครงสร้าง Sierpinski
- ตามคุณสมบัติเชิงจัดหมู่แบบโมดูโล 2 จะเกิดเป็น สามเหลี่ยม Sierpinski และบิตนี้จะถูกส่งออกไปยังลำโพง PC โดยตรง
- ในระดับบิต การบวกแบบไม่มีแคร์รีคือ XOR ดังนั้นในโค้ดจึงใช้
xor [si], alแทนadd - ค่าเริ่มต้น 2 คือเลขฐานสอง
00000010ดังนั้นมีเพียง bit 1 ที่สลับไปมาระหว่าง0x00และ0x02 - แพทเทิร์นนี้สอดคล้องกับ rule 60 ของ elementary cellular automata
- ตามทฤษฎีบทของ Lucas แพทเทิร์นนี้ตรงกับ bit 1 ของตารางการบวก และในตารางตำแหน่งที่ bit 1 ติดจะปรากฏเป็น
2
วิธีที่ข้อมูลกลายเป็นเสียง
out 61h, alจะส่งไบต์ที่คำนวณได้ไปยังพอร์ต61hที่เชื่อมกับ ลำโพง PC- bit 1 ของพอร์ต
61hจะกำหนดสถานะว่ากรวยลำโพงถูกผลักออกหรือดึงเข้า - โค้ดจะคำนวณแฟรกทัลด้วย XOR, เขียนผลลงหน่วยความจำ แล้วส่งไบต์เดียวกันนั้นไปยังพอร์ตลำโพงทันที
- ค่า 1 และ 0 จากแฟรกทัลจะสร้าง คลื่นสี่เหลี่ยม (square wave) ที่มีทั้งความกว้างพัลส์และความถี่เปลี่ยนไปตามธรรมชาติ และเมื่อเล่นแบบ linewise จะกลายเป็น bytebeat ที่มีความเป็น self-similar และแทบคงจังหวะไว้ได้ตลอด
- เสียงเอาต์พุตไม่ได้ผสมแค่ text buffer แต่รวมถึงไบต์ส่วนที่เหลือของ segment 64KB ด้วย และเพราะมีโค้ด shadowed video ROM BIOS อยู่ในนั้น จึงได้เสียงหยาบและ funky ที่ต่างจาก Sierpinski line based overlayed rectangle wave bytebeat ตามที่คาดไว้
สเต็ป 56 ไบต์: อ็อกเทฟและการเฉือนแนวทแยง
- โค้ดจริงไม่ได้เดินทีละ 16 ไบต์ แต่ใช้การจับคู่ของ
lodsbและsub si, byte 57เพื่อเลื่อนถอยหลัง -56 ไบต์ ในแต่ละรอบ - ระยะก้าวนี้ช่วยให้เติมภาพบนหน้าจอแบบเบาบาง โดยที่บัฟเฟอร์เสียงไม่ใหญ่เกินไป และถูกใช้เพื่อสร้างเอฟเฟ็กต์ภาพแบบเดียวกับ M8trix
-
เสียง
- 56 ไม่สามารถหาร 65,536 ลงตัว
- โค้ดจะเข้าถึงเฉพาะออฟเซ็ตที่เป็นพหุคูณของ 8 และจะรีเซ็ตได้ก็ต่อเมื่อผ่านไป 8,192 สเต็ป และวนครบรอบ 7 ครั้งแล้ว
- เมื่อความยาวของรอบเพิ่มเป็นสองเท่า ความถี่พื้นฐานจึงลดลงครึ่งหนึ่ง ทำให้เสียง ต่ำลงหนึ่งอ็อกเทฟ
-
ภาพ
- บนหน้าจอที่กว้าง 80 ไบต์ การเลื่อน -56 ไบต์ เทียบเท่ากับเดินไปข้างหน้า 24 ไบต์ หรือ 12 คอลัมน์
- คอลัมน์ที่ถูกเข้าถึงจริงมีเพียง 10 คอลัมน์ เท่านั้น
- แฟรกทัลจึงไม่ปรากฏเป็นภาพเต็ม แต่เป็นรูปที่ถูกเฉือนเฉียงอยู่บนเสาตัวอักษร 10 เสา ซึ่งเคลื่อนขึ้นไปทางด้านบนของหน้าจอ
- ตัวสามเหลี่ยมจริงมีความกว้าง 8,192 “พิกเซล” แต่ตัวอักษรหนึ่งบรรทัดมีเพียง 80 ไบต์ จึงรับรู้การเคลื่อนไหวได้แต่ยากจะเห็นโครงสร้างทั้งหมดโดยตรง
- หากวาดรวดเดียวโดยไม่ข้ามพิกเซล หรือใช้หน้าจอที่ใหญ่กว่ามาก ก็จะมองเห็นรูปสามเหลี่ยมได้
การรันบนฮาร์ดแวร์จริง
- scener miragept ได้แพตช์แอดเดรสจาก
0xB800เป็น0xB000ที่ MDA ใช้ เพื่อให้ได้ข้อความสีเขียวแบบ MDA/Hercules และรันบนฮาร์ดแวร์จริง - อุปกรณ์ที่ใช้ไม่ใช่เครื่อง IBM ตรงรุ่น แต่เป็น 286 ที่มีการ์ด EGA ซึ่งจำลอง MDA/Hercules ได้ พร้อมจอ MDA จริง
- เสียงที่บันทึกได้มี noise ต่อเนื่องจากตัวเครื่องปะปนอยู่ และจอ IBM 5151 ก็มี ภาพค้างของฟอสฟอร์ที่ยาวนาน ซึ่งไม่เหมาะกับการแสดงผลที่เร็วมาก
- แม้การเปลี่ยนไบต์ของแอดเดรสจะทำให้เสียงต่างไปเล็กน้อย แต่มันยังทำงานได้ตามตั้งใจ และช่วงท้าย ๆ โครงสร้าง Sierpinski มองเห็นได้ชัดกว่าเวอร์ชันเดิม
- อาร์ติแฟกต์ที่ค้างใน RAM จะแตกต่างกันไปตาม emulator และเวอร์ชัน BIOS และเพราะโค้ดทำ XOR กับสถานะหน่วยความจำนั้น เอาต์พุตจึงไวต่อสภาพแวดล้อมที่รันอย่างมาก
- หากล้างหน่วยความจำก่อน ก็จะได้ผลลัพธ์ที่สม่ำเสมอขึ้น แต่ต้องใช้ไบต์เพิ่ม และแนวทางที่ยอมรับสภาพฮาร์ดแวร์ตามธรรมชาตินี้ก็ยังเป็นเสน่ห์อย่างหนึ่งของ sizecoding
แหล่งข้อมูลที่เกี่ยวข้อง
- Nanogems - รายการคัดสรร Tiny Intro เด่น ๆ ของ demoscene
- HellMood's productions on Pouet
- Capture on a 286/MDA/Hercules - วิดีโอบันทึกบนฮาร์ดแวร์จริงโดย miragept
- Sizecoding Wiki
- "Rainbow Surf" - อินโทร x86 ขนาด 16 ไบต์ของ Plex
- "M8trix" - อินโทร 8 ไบต์ของ HellMood
1 ความคิดเห็น
ความคิดเห็นจาก Hacker News
https://youtu.be/b-Fa6HtvGtQ?si=LpQszgA9_K-m3V3-
ทั้งคู่ทั้งมีไหวพริบและชอบทดลอง Parker เอนไปทางคณิตศาสตร์แบบตรงสายมากกว่า ส่วน Mould ข้ามไปมาหลายสาขาและตอบโจทย์สายทดลอง/DIY ได้เต็มที่
ถ้าชอบวิดีโอนี้ แนะนำอย่างยิ่งให้ไปดูทั้งสองช่องต่อ
https://www.youtube.com/@standupmaths
https://www.youtube.com/@SteveMould
เดโมนั้นไม่มีแม้แต่เสียงด้วยซ้ำ
นี่เป็นงานที่น่าทึ่งมาก และเป็น ผลงานชิ้นเอก ที่เอาไปใช้เป็นงานทิ้งทวนได้เลย หรือพูดให้สมจริงกว่านั้นก็คงเป็นการไล่ล่าต่อบนสถาปัตยกรรมอื่นอีก
บราโว
https://www.youtube.com/watch?v=QKLhH_ANwIc
ชุมชน size coding ของพวกเราคิดว่าเราเจอลูกเล่น cellular automata กันหมดแล้วตั้งแต่หลายปีก่อน แต่แล้ว Plex ก็โผล่มาพิสูจน์ว่าไม่จริง ♥
ไม่แน่ใจว่าเคยมีบทความเกี่ยวกับงานรุ่นก่อนหน้าอย่าง m8trix หรือเปล่า แต่ฉันเคยลองแกะดูอยู่ครั้งหนึ่งตอนมันออกมาใหม่ ๆ ในปี 2014: https://scot.tg/2014/05/31/amazing-code-density/
ทุกอย่างสวยงามมาก และเป็นศิลปะอย่างแท้จริง น่าเสียดายที่ในวงการทุกวันนี้เอาแต่พูดถึง AI อะไรพวกนี้ จนแทบไม่มีโอกาสได้สร้างอะไรแบบนี้