Repository navigation
v0.0.191
rePIU v0.0.191
이전 릴리스 v0.0.190 이후의 변경입니다(Tasks 735–740). pumpitea가 Linux x64와 Windows
양쪽에서 시작해 플레이까지 갑니다. Linux x64 플레이에서 화살표 노트가 멈췄다 뛰어넘던 증상과
음악 노이즈가 사라졌습니다(사용자 확인). 창 제목에 플랫폼·아키텍처·빌드 구성이 표시되고, Linux
빌드 스크립트가 --target 없이 그대로 동작합니다.
pumpitea: 어디까지 왔나
| v0.0.190 | v0.0.191 | |
|---|---|---|
| Linux x64 시작 | AOT 이미지 decode 검증 거절로 시작 못 함 | 시작 → 타이틀 → 곡 선택 → 플레이 |
| Linux x64 23초 | 타이머 ISR 중첩으로 segfault | 90초 이상 정상 |
| Windows 시작 | 8초에 0xC0000005 |
90초 타이틀 도달 |
| 플레이 중 노트 | 멈췄다 뛰어넘음 | 부드러움 |
| 플레이 중 음악 | 간헐 노이즈 | 없음 |
고친 것
Linux x64에서 pumpitea 시작 실패 (Task 735) — AOT 이미지 decode 검증이 guest 82 68 10 01
(sub byte [eax+0x10],1) 하나를 거절했습니다. opcode 82는 80 group-1 연산의 별칭이고 long
mode에서는 #UD입니다. long-mode 경로가 82를 80 표기로 판단·방출합니다. 빌드 실패 메시지는
이제 단계와 첫 실패 항목, 방출 바이트를 담습니다.
pumpitea 타이머 ISR 중첩 (Task 736) — PIT를 51.9 kHz로 프로그램한 단계에서 타이머 ISR의
cli 뒤 back-edge에 tick이 다시 주입되어 ISR이 중첩되고 스택이 넘쳤습니다(user mode에서 IF는
cli를 반영하지 않습니다). PIC의 IRQ0 in-service 비트를 모델링해 EOI(0x20/0x60 → 포트
0x20) 전에는 주입하지 않고, EOI 뒤 guest sti에서 밀린 tick을 전달합니다(연속 sti 전달은
금지, 주입 frame에서 TF 제거). REPIU_PIC_TIMER_IN_SERVICE=0으로 이전 동작.
Windows pumpitea 시작 크래시 (Task 737) — 세 겹이었습니다. (1) i386 간접 CALL fallback이
x64 규칙(피호출에서 계속)대로 push를 유지해 반환 주소를 두 번 push → i386에서는 legacy가 CALL을
재실행하므로 되돌립니다. miss tail의 CALL도 +8. (2) i386 kCopy가 16-bit code object의 3 stub
바이트를 그대로 복사해 dynamic 이미지 전부가 거절됨 → 16-bit 기록은 INT3 HLE 경계. (3) ISR 입력
스캔의 cmp; jge exit; jmp back 형식을 지연 루프 batcher가 거절 → 뒤집은 형식 수용(Windows
19,001 batch/90초).
Linux x64 플레이의 노트 끊김과 노이즈 (Task 740) — MP3 frame-sync 토글과 decoder의 refill이
모두 SDL 장치가 PCM을 가져가는 계단(장치 buffer 단위)에 매여 있었습니다. 한 계단 안의 frame 경계
여러 개가 한 호출에서 함께 토글되고(240 Hz로 폴링하는 guest는 짝수 개를 변화 없음으로 봄), decoder도
계단 단위로 몰아 채워 guest의 demand와 frame 카운터가 같은 계단으로 움직였습니다. 장치 계단 사이를
PCM 속도로 보간하는 재생 시계가 토글과 decode 게이트를 움직입니다. 장치 buffer 2048 frame 강제
시 초당 4~6회이던 토글 뭉침이 0이 되었고, 사용자 환경에서 노트 끊김과 노이즈가 모두 사라졌습니다.
바뀐 것
- 창 제목(Task 738):
rePIU v0.0.191 (Win/x86 Debug) - Build … - Glide 2 OpenGL [dynamic] - FPS : ….Linux/x64 Release처럼 플랫폼/아키텍처 빌드 구성이 붙습니다.
repiu::platform::BuildIdentityLabel(), CMakeREPIU_BUILD_CONFIG. - Linux 빌드 스크립트(Task 739):
scripts/build_linux_x64.sh·build_linux_i386.sh가--target
없이 전체를 빌드합니다.repiu_exe가 Linux에서GL을PUBLIC으로 링크해
repiu_instruction_census와 i386 core probe의 링크 오류가 없어졌습니다. i386 스크립트에
--build-dir와 구성 불일치 안내가 생겼고,--headless는 X11/Wayland 개발 패키지가 없을 때
configure 오류를 막는 스위치일 뿐 데스크톱 드라이버는 그대로 빌드됩니다. - 최종 보고에
PIU10 MP3 received/dropped/decoded/starvation/toggles/multi/pcm-empty/ pcm-low-water-bytes/device-buffer-frames와timer IRQ0 in-service …줄이 추가됐습니다.
새 진단 (설정하지 않으면 동작 없음)
| 변수 / 도구 | 내용 |
|---|---|
REPIU_PIU10_MP3_CENSUS_MS=<ms> |
MP3 파이프라인 census 한 줄(수신·decode·큐·시계 지연·demand·토글·뭉침·기아·빈 큐·tick) |
REPIU_PIC_TIMER_IN_SERVICE=0 |
IRQ0 in-service 모델을 끄고 이전 주입 동작으로 |
SDL_AUDIO_DEVICE_SAMPLE_FRAMES=<frames> |
(SDL 힌트) 장치 buffer를 강제해 큰 buffer의 host를 재현 |
scripts/task740_mp3_census_capture.sh |
위 census로 한 번 실행하고 초당 요약을 냄 |
알려진 것
- Windows legacy backend의 pumpitea 크래시(
0x040FD010)는 재확인하지 않았습니다. Windows
pumpitea의 곡 선택·플레이 진행도 확인하지 않았습니다. - pumpitea의 ISR 입력 스캔은 tick마다 200회
in을 trap으로 실행합니다(Linux 88초에 405만 회).
결과는 맞지만 비용이 큽니다. - 곡 재생 중 tick이 초당 234
244로 흔들리고, 장면 전환 중 40160 ms의 tick 공백이 있습니다.
조사하지 않았습니다. - v0.0.190의 알려진 것 중 VS 2026(v145) 빌드의
dos4gw_hello크래시, Linux x64 로딩 구간
정지, CD 미리듣기 무음 보고는 그대로입니다. - Linux 측정은 WSLg에서 했습니다.
검증: Linux x64 core probe 33/33, Windows x86 core probe 31/31, Linux i386 core probe 31/31,
WSL 합성 입력으로 pumpitea 코인 → 곡 선택 → 플레이 재현(60~90초, 폴트 0), Windows pumpitea
90초, pumpit2a 회귀 실행, 사용자 플레이 확인.
rePIU v0.0.191
Changes since v0.0.190 (Tasks 735–740). pumpitea now starts and plays on both Linux x64 and
Windows. On Linux x64 the arrows no longer stall and jump during play and the music no longer
carries noise (confirmed by the user). The window title shows platform, architecture and build
configuration, and the Linux build scripts work as they are, with no --target.
Where pumpitea stands
| v0.0.190 | v0.0.191 | |
|---|---|---|
| Linux x64 start | rejected by the AOT image's decode check | starts → title → song select → play |
| Linux x64 at 23 s | segfault from nested timer ISRs | runs past 90 s |
| Windows start | 0xC0000005 at 8 s |
reaches the title at 90 s |
| Arrows during play | stall and jump | smooth |
| Music during play | occasional noise | none |
Fixed
pumpitea did not start on Linux x64 (Task 735): the AOT image's decode check rejected one entry,
guest 82 68 10 01 (sub byte [eax+0x10],1). Opcode 82 is the alias of the 80 group-1
operations and raises #UD in long mode; the long-mode path now judges and emits 82 as its 80
spelling. The build-failure message now names the stage, the first failing entry and the emitted
bytes.
pumpitea's nested timer ISRs (Task 736): with the PIT programmed at 51.9 kHz, ticks were injected
again at the back-edge after the timer ISR's cli (IF does not reflect cli in user mode), nesting
the ISR until the stack overflowed. The PIC's IRQ0 in-service bit is modelled: no injection before the
EOI (0x20/0x60 to port 0x20), and an owed tick is delivered at the guest's sti after it (never
two sti deliveries in a row, TF cleared from the injected frame). REPIU_PIC_TIMER_IN_SERVICE=0
restores the earlier behaviour.
Windows pumpitea start-up crash (Task 737): three layers. (1) The i386 indirect CALL fallback kept
the push as the x64 rule says (x64 continues in the callee), pushing the return address twice; on
i386 the legacy path re-executes the CALL, so the push is undone, and the miss tail's CALL also gets
+8. (2) i386 kCopy copied the three stub bytes of 16-bit code objects verbatim, rejecting every
dynamic image; 16-bit records are now an INT3 HLE boundary. (3) The delay-loop batcher rejected the
ISR input scan's cmp; jge exit; jmp back shape; the inverted form is accepted (19,001 batches in 90
s on Windows).
Arrow stutter and noise during Linux x64 play (Task 740): both the MP3 frame-sync toggles and the
decoder's refills followed the steps in which the SDL device pulls PCM (its buffer size). Several frame
boundaries inside one step toggled in the same call (a guest polling at 240 Hz reads an even number
as no change), and the decoder refilled a whole step at once, so the guest's demand and frame counter
moved in the same steps. A playback clock interpolated at the PCM rate between device steps now drives
both the toggles and the decode gate. With a forced 2048-frame device buffer, collapsed toggles went
from four to six a second to none, and on the user's host both the stutter and the noise are gone.
Changed
- Window title (Task 738):
rePIU v0.0.191 (Win/x86 Debug) - Build … - Glide 2 OpenGL [dynamic] - FPS : …, with the platform/architecture and build configuration such asLinux/x64 Release.
repiu::platform::BuildIdentityLabel(), CMakeREPIU_BUILD_CONFIG. - Linux build scripts (Task 739):
scripts/build_linux_x64.shandbuild_linux_i386.shbuild
everything with no--target.repiu_exelinksGLPUBLICon Linux, which removes the link
errors ofrepiu_instruction_censusand the i386 core probe. The i386 script gained--build-dir
and the configuration-mismatch guard.--headlessonly suppresses the configure error when the
X11/Wayland development packages are missing; the desktop drivers are built regardless. - The final report gained
PIU10 MP3 received/dropped/decoded/starvation/toggles/multi/pcm-empty/ pcm-low-water-bytes/device-buffer-framesandtimer IRQ0 in-service …lines.
New diagnostics (inert when unset)
| Variable / tool | What it does |
|---|---|
REPIU_PIU10_MP3_CENSUS_MS=<ms> |
one MP3 pipeline census line per interval (received, decoded, queue, clock lag, demand, toggles, collapsed toggles, starvation, empty queue, ticks) |
REPIU_PIC_TIMER_IN_SERVICE=0 |
turns the IRQ0 in-service model off, restoring the earlier injection |
SDL_AUDIO_DEVICE_SAMPLE_FRAMES=<frames> |
(SDL hint) forces the device buffer, to reproduce a host with a larger one |
scripts/task740_mp3_census_capture.sh |
one run with the census above and a per-second summary |
Known
- The Windows legacy backend's pumpitea crash (
0x040FD010) was not re-checked, nor was Windows
pumpitea's progress to song select and play. - pumpitea's ISR input scan runs 200
ininstructions per tick through traps (4.05 million in 88 s on
Linux). The results are right; the cost is high. - The tick rate wanders between 234 and 244 a second during a song, and there are 40–160 ms tick gaps
during scene loads. Not investigated. - From v0.0.190's list, the VS 2026 (v145)
dos4gw_hellocrash, the Linux x64 loading stalls and
the CD-preview silence report remain as they were. - Linux figures were measured under WSLg.
Verified by Linux x64 core probe 33/33, Windows x86 core probe 31/31, Linux i386 core probe 31/31,
an automated WSL reproduction of pumpitea from coin to song select to play (60–90 s, no faults), a
90-second Windows pumpitea run, pumpit2a regression runs, and the user's own play.