256바이트 DOS 프로그램 X-87, x87 연산으로 풍경을 그린다
개인 제작자 Onirom(@grz0zrg)은 x87 연산으로 풍경을 그리는 256바이트 DOS 프로그램 X-87을 만들었습니다. 이 프로그램은 256개 상태를 반복 갱신해 픽셀 좌표를 만들고, 픽셀 밝기에 따라 색을 누적합니다. 제작자는 Gforth를 활용해 코드를 줄이고 Bochs와 FreeDOS에서 호환성을 확인했습니다.

개인 제작자 Onirom(@grz0zrg)은 Outline 2026용으로 256바이트 DOS 그래픽 프로그램 X-87을 만들었습니다. x86의 x87 부동소수점 연산으로 풍경의 좌표를 계산하고, 640×400 화면에 픽셀당 32비트로 출력합니다. 제작자가 공개한 p5.js 스케치와 Gforth 구현은 풍경을 반복 계산으로 그리고, DOS용 코드 크기와 실행 호환성을 함께 다듬은 과정을 보여줍니다.
X-87의 바탕이 된 p5.js 스케치는 2021년 중반에 시작됐습니다. 제작자는 2024년 초 이 작업을 다시 시작했고, 2025년 초 황량한 땅과 하늘로 나뉜 장면으로 발전시켰습니다. 오실레이터의 매개변수와 변환값, 특히 크기 조정값을 거듭 바꾸다가 현재의 형태를 얻었다고 설명합니다. 이후 256바이트 안에 구현하는 데 약 2주를 들였습니다.
스케치에는 x와 y 상태 배열이 각각 256개 있습니다. 한 프레임에 65,536번 반복하는 p5.js 버전은 프레임 번호와 현재 x·y 값을 이용해 삼각함수인 코사인과 탄젠트 등을 계산하며 상태를 갱신합니다. 각 반복에서 갱신된 값은 화면 좌표로 변환돼 픽셀을 가리킵니다. 이렇게 계산한 좌표에 점을 차례로 쌓아 풍경을 만듭니다.
색상도 픽셀을 채우는 과정에서 계산합니다. 프로그램은 대상 픽셀에 누적된 RGB 값의 밝기를 바탕으로 팔레트에서 색상 증가량을 고르고, 그 값을 해당 픽셀에 더합니다. 제작자는 이를 디더링과 비슷한 색칠 방식으로 설명합니다. 초기에 만든 회색조 DOS 포트는 약 320바이트였고, 색상을 넣은 뒤에는 코드 크기를 다시 줄여야 했습니다.
제작자는 x87 부동소수점 연산 장치와 Forth가 모두 스택을 사용하는 점이 포팅을 수월하게 했다고 설명합니다. 먼저 만든 Gforth 구현이 작게 나온 것도 DOS 버전을 256바이트에 맞출 수 있다는 판단에 힘을 보탰습니다. 색상 코드를 넣을 공간을 마련하기 위해 부동소수점 상수를 겹쳐 쓰거나 일부를 잘라내고, 색상 증가값을 패킹했으며, FPU 명령 수도 줄였습니다.
코드 크기를 줄인 뒤에는 실행 호환성 문제도 해결했습니다. 초기 버전에는 FPU 초기화 누락과 초기화되지 않은 메모리 같은 문제가 있었고, 검은 사각형 아티팩트는 세그먼트 초기화와 VESA 페이징·뱅킹 처리에서 비롯됐습니다. 이 아티팩트는 DOSBox에서는 거의 보이지 않았지만 Bochs에서는 크게 나타났다고 제작자는 기록했습니다. 팔레트 데이터를 부동소수점 상수와 겹쳐 쓰고 초기화 코드와 픽셀 포화 루프를 최적화해 문제를 수정했습니다. 마지막 최적화에서는 두 주요 반복문을 하나로 합치고 ECX의 상·하위 부분에 프레임 카운터와 오실레이터 인덱스를 나눠 담았습니다. 386 세대 호환을 위해 Pentium Pro에서 추가된 fcomi 명령도 피했습니다.
X-87은 DOS 실모드에서 VESA 그래픽 모드로 실행되며, 제작자는 Bochs와 FreeDOS에서 동작을 확인했습니다. 실제 하드웨어에서는 시험하지 않았습니다. i7-7700 시스템의 DOSBox에서는 사이클 설정이 기본 3,000일 때 렌더링에 약 13분, 20,000일 때 약 2분 30초, 최대 설정일 때 약 2분 10초가 걸렸다고 기록했습니다. 해상도를 바꾸려면 상수와 뱅크 검사 상수를 조정해야 합니다. 해상도에 따라 수렴 속도와 아티팩트의 가시성, 화면의 밝기와 밀도가 달라지며, 색상 증가량이나 오실레이터를 조정해 밝기와 밀도를 보정할 수 있습니다.