Files
VGMPLAY.WMF/src_sdcc/build.bat
T
alex 54112347f5 Add large-file (>1MB) OPL4 loading and fix track-end hang
- One-shot cold loader (asm/opl4_loader.asm, overlaid into plugin
  page 5) uploads embedded PCM sample blocks into ZXM-MoonSound SRAM
  and compacts the VGM stream in place, letting files over the normal
  64-page megabuffer budget play back through the existing pipeline.
- instant_abort() was filling only one of the two ISR command buffers
  with the shutdown chain; the chain (SILENCE_OPL + WAVE_OFF/TL +
  CMD_ISR_DONE) doesn't fit in one buffer, so after the first
  CMD_END_BUF the ISR swapped into stale data and never reached
  CMD_ISR_DONE, hanging at the end of long tracks instead of
  advancing to the next one. Now fills both buffers while frozen and
  syncs update_buffer()'s own ready-tracking state.
- Switch to 14MHz before the SRAM upload (previously ran at whatever
  speed WC's file I/O left active) and show "Loading..." for .vgz and
  files >= 1MB, since the busy-waited upload takes several seconds.
- Confirmed on real hardware: long OPL4 tracks (previously stuck
  looping at the end) now finish and advance normally, ESC exits
  cleanly.
2026-09-16 20:14:06 +03:00

183 lines
8.1 KiB
Batchfile
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
@echo off
chcp 65001 >nul
REM ===========================================================================
REM build.bat — Сборка VGM Player Plugin (SDCC/Z80)
REM
REM Инструменты:
REM sdcc — компилятор C (sdcccall(1), mz80, без frame pointer)
REM sdas — ассемблер SDCC (ASM файлы)
REM sdld / sdcc --link-cmd-file — линковщик
REM node — JS-скрипты (gen_pos_table, ihx2wmf)
REM
REM Структура вывода: build/ (временные .rel) → vgmplay.wmf
REM ===========================================================================
setlocal
cd /d "%~dp0"
REM --- Папка для временных файлов ---
if not exist build mkdir build
REM --- Флаги SDCC ---
REM -mz80 : целевая архитектура Z80
REM --sdcccall 1 : соглашение вызова sdcccall(1) (регистровая передача)
REM --no-std-crt0 : не линковать стандартный crt0 (наш в asm/crt0.s)
REM --opt-code-size : оптимизация по размеру (важно для 8-бит)
REM --no-peep-asm : не трогать __naked asm-блоки
set CFLAGS=-mz80 --sdcccall 1 --no-std-crt0 --opt-code-size -I inc --disable-warning 85
REM --- Флаги ассемблера (sdas) ---
set ASFLAGS=-plosff
REM --- Читаем параметры варианта из variant_cfg.h ---
for /f "tokens=3" %%a in ('findstr /C:"#define VARIANT_POS_ENTRIES" inc\variant_cfg.h') do set POS_ENTRIES=%%a
for /f "tokens=3" %%a in ('findstr /C:"#define VARIANT_POS_STEP" inc\variant_cfg.h') do set POS_STEP=%%a
for /f "tokens=3" %%a in ('findstr /C:"#define VARIANT_DATA_LOC" inc\variant_cfg.h') do set DATA_LOC=%%a
echo variant_cfg: entries=%POS_ENTRIES% step=%POS_STEP% data-loc=%DATA_LOC%
echo [1/8] Генерация pos_table.s...
node scripts\gen_pos_table.js --entries %POS_ENTRIES% --step %POS_STEP%
if errorlevel 1 ( echo FAIL gen_pos_table && goto :err )
echo [2/8] Генерация freq_tables.bin...
node scripts\gen_freq_tables.js --page-base 1 --binary build\freq_tables.bin --cheader inc\freq_lut_map.h
if errorlevel 1 ( echo FAIL gen_freq_tables && goto :err )
echo [3/9] Сборка inflate.asm (sjasmplus)...
..\tools\sjasm\sjasmplus.exe asm\inflate.asm >nul 2>&1
if errorlevel 1 ( echo FAIL inflate.asm && goto :err )
REM inflate.asm имеет SAVEBIN "build/inflate.bin" внутри
REM Паддинг inflate.bin до 16KB (чтобы cmdblocks.bin начинался на границе страницы)
powershell -NoProfile -Command "$f=[IO.File]::ReadAllBytes('build\inflate.bin'); if($f.Length -lt 16384){$pad=New-Object byte[] (16384-$f.Length); [IO.File]::WriteAllBytes('build\inflate.bin',$f+$pad); Write-Host (' inflate.bin padded: '+$f.Length+' -> 16384')}"
if errorlevel 1 ( echo FAIL pad inflate && goto :err )
echo [3a/9] Сборка cold OPL4 loader...
..\tools\sjasm\sjasmplus.exe asm\opl4_loader.asm >nul 2>&1
if errorlevel 1 ( echo FAIL opl4_loader.asm && goto :err )
echo [3b/9] Сборка cmdblocks.asm (sjasmplus)...
..\tools\sjasm\sjasmplus.exe asm\cmdblocks.asm >nul 2>&1
if errorlevel 1 ( echo FAIL cmdblocks.asm && goto :err )
node scripts\overlay_bin.js build\cmdblocks.bin build\opl4_loader.bin 0x1800
if errorlevel 1 ( echo FAIL overlay OPL4 loader && goto :err )
REM cmdblocks.asm имеет SAVEBIN "build/cmdblocks.bin" внутри
echo [4/9] Компиляция C файлов...
sdcc %CFLAGS% -c main.c -o build\main.rel >nul
if errorlevel 1 ( echo FAIL main.c && goto :err )
sdcc %CFLAGS% -c lib\vgm.c -o build\vgm.rel >nul
if errorlevel 1 ( echo FAIL vgm.c && goto :err )
sdcc %CFLAGS% -c lib\keys.c -o build\keys.rel >nul
if errorlevel 1 ( echo FAIL keys.c && goto :err )
REM txtlib is now hand-written assembly (asm\txtlib.s), assembled below
echo [5/9] Сборка ASM файлов...
sdasz80 %ASFLAGS% build\crt0.rel asm\crt0.s >nul
if errorlevel 1 ( echo FAIL crt0.s && goto :err )
sdasz80 %ASFLAGS% build\isr.rel asm\isr.s >nul
if errorlevel 1 ( echo FAIL isr.s && goto :err )
sdasz80 %ASFLAGS% build\pos_table.rel asm\pos_table.s >nul
if errorlevel 1 ( echo FAIL pos_table.s && goto :err )
call lib\wc_api\build_lib.bat >nul
if errorlevel 1 ( echo FAIL wc_api.lib && goto :err )
sdasz80 %ASFLAGS% build\txtlib.rel asm\txtlib.s >nul
if errorlevel 1 ( echo FAIL txtlib.s && goto :err )
sdasz80 %ASFLAGS% build\inflate_call.rel asm\inflate_call.s >nul
if errorlevel 1 ( echo FAIL inflate_call.s && goto :err )
sdasz80 %ASFLAGS% build\spectrum.rel asm\spectrum.s >nul
if errorlevel 1 ( echo FAIL spectrum.s && goto :err )
sdasz80 %ASFLAGS% build\cold_return.rel asm\cold_return.s >nul
if errorlevel 1 ( echo FAIL cold_return.s && goto :err )
echo [6/9] Линковка...
REM Порядок важен: crt0 первым (entry point), затем модули
REM Layout: CODE #8000–#B8CF, DATA #B8D0–#BFFF
REM Все секции (DATA + GSINIT + HOME + INITIALIZER) должны
REM уместиться до #BFFF (Win2). Если CODE вырастет →
REM понизить --data-loc или оптимизировать код.
sdcc -mz80 --no-std-crt0 --out-fmt-ihx --code-loc 0x8000 --data-loc %DATA_LOC% ^
build\crt0.rel ^
build\main.rel ^
build\vgm.rel ^
build\keys.rel ^
build\isr.rel ^
build\pos_table.rel ^
build\wc_api.lib ^
build\txtlib.rel ^
build\inflate_call.rel ^
build\spectrum.rel ^
build\cold_return.rel ^
-o build\vgmplay.ihx >nul
if errorlevel 1 ( echo FAIL link && goto :err )
REM --- Вывод карты памяти секций из map-файла ---
powershell -NoProfile -Command ^
"$m=Get-Content build\vgmplay.map -Raw;" ^
"function gs($p){if($m -match '([0-9a-f]{8})\s+'+$p){return $Matches[1]}return '00000000'};" ^
"$secs=@('CODE','DATA','GSINIT','GSFINAL','INITIALIZED','HOME','INITIALIZER');" ^
"Write-Host '';" ^
"Write-Host ' Section Start End Size';" ^
"Write-Host ' -------------- -------- -------- ----------';" ^
"$lastEnd=0;$codeEnd=0;$dataStart=0;" ^
"foreach($s in $secs){" ^
" $st=[Convert]::ToInt32((gs ('s__'+$s)),16);" ^
" $ln=[Convert]::ToInt32((gs ('l__'+$s)),16);" ^
" if($ln -eq 0){continue};" ^
" $en=$st+$ln-1;" ^
" if($en -gt $lastEnd){$lastEnd=$en};" ^
" if($s -eq 'CODE'){$codeEnd=$en};" ^
" if($s -eq 'DATA'){$dataStart=$st};" ^
" Write-Host (' _'+$s.PadRight(14)+' 0x'+$st.ToString('X4')+' 0x'+$en.ToString('X4')+' '+$ln.ToString().PadLeft(5)+' bytes')" ^
"};" ^
"$free=0xBFFF-$lastEnd;" ^
"Write-Host ' -------------- -------- -------- ----------';" ^
"Write-Host (' Last byte: 0x'+$lastEnd.ToString('X4')+' Free before C000: '+$free+' bytes');" ^
"if($codeEnd -ge $dataStart -and $dataStart -gt 0){Write-Host (' *** ERROR: _CODE (end 0x'+$codeEnd.ToString('X4')+') overlaps _DATA (start 0x'+$dataStart.ToString('X4')+')! ***') -ForegroundColor Red; exit 1};" ^
"if($lastEnd -ge 0xC000){Write-Host ' *** ERROR: sections overflow past 0xBFFF! ***' -ForegroundColor Red; exit 1}"
if errorlevel 1 goto :err
echo [7/9] Генерация WMF (multi-page)...
REM Склеить freq_tables.bin + inflate page + cmdblocks.bin
copy /b build\freq_tables.bin+build\inflate.bin+build\cmdblocks.bin build\extra_combined.bin >nul
if errorlevel 1 ( echo FAIL combine extra && goto :err )
node scripts\ihx2wmf.js build\vgmplay.ihx ..\DiskRef\WC\VGMPLAY.WMF --extra build\extra_combined.bin
if errorlevel 1 ( echo FAIL ihx2wmf && goto :err )
copy /Y ..\DiskRef\WC\VGMPLAY.WMF ..\VGMPLAY.WMF >nul
echo [8/9] Проверка размеров binary...
powershell -NoProfile -Command "Get-ChildItem build\*.bin | Select-Object Name, Length | Format-Table -AutoSize"
echo [9/9] Сборка образа диска...
if not exist "..\tools\robimg.exe" (
echo SKIP: tools\robimg.exe не найден
goto :ok
)
del /Q ..\tsconf.img 2>nul
..\tools\robimg.exe -p="..\tsconf.img" -s=280000 -C="..\DiskRef" >nul 2>&1
if errorlevel 1 ( echo FAIL robimg && goto :err )
echo tsconf.img готов
:ok
echo.
echo === BUILD OK ===
goto :end
:err
echo.
echo === BUILD FAILED ===
exit /b 1
:end
endlocal