Дзен компиляции ужасмом, создание трд, и запуск анрила из bat(cmd)-файла

К вопросу (не)умения пользоваться командной строкой виндовс для компиляции и сборки проектов для спекки.

Мой дзен получился в такой последовательности и наборе:
1. Все утилиты и рабочие файлы находятся на одном диске. У меня это диск К:. Все находится в облаке в папочке ZX и командой subst цепляется на диск К: — в результате на любом моем компе все находится по одному пути, хотя в данном конкретном случае это неважно.
2. В корне диска имеем 2 папки: с рабочими проектами и утилитами — в моем случае это _work и вложенной _utils. В данном примере в папке утилит должны лежать ужасм и trdtool.
3. Проекты располагаются в отдельных папках внутри _work
4. Именем проекта (и соответственно именем файла) является имя папки — самая главная фишка этой мутотени.
6. Внутри папки проекта должна содержаться папка sourses и в ней файл main.asm — именно он и компилируется, это основное требование моего метода.
7. Также папка проекта должна содержать файлы make.cmd и make_trd.cmd — об этих файлах подробнее далее.

make.cmd

rem make.cmd
@echo off

setlocal enabledelayedexpansion

set currDir=%cd%
set currDisk=%~d0

cd ..
set PROJECT=!currDir:%cd%\=!
cd %currDir%

:MAIN
@echo Project: %PROJECT%

SET UTILS_PATH=%currDisk%\_Work\_utils\

SET UNREAL_DIR=%currDisk%\_PC\us\u0376_pentevofix\
SET UNR_EXE=emul.exe


SET UNREAL_PATH=%UNREAL_DIR%%UNR_EXE%

ren %PROJECT%.trd tmp.%PROJECT%.trd
del /q %PROJECT%.*
ren tmp.%PROJECT%.trd %PROJECT%.trd

%UTILS_PATH%\sjasmplus.exe --dos866 --lst=%PROJECT%.lst --inc=sources\. sources\main.asm

IF NOT EXIST main.sna GOTO ERROR

ren main.bin %PROJECT%.bin
ren main.sna %PROJECT%.sna
copy %PROJECT%.bin %PROJECT%.C
call make_trd

copy user.l %UNREAL_DIR% > nul
taskkill /im %UNR_EXE% /f > nul
%UNREAL_PATH% %PROJECT%.sna > nul
GOTO END

:ERROR
@echo not exist .sna file
EXIT 1

:END
endlocal


Строки

SET UNREAL_DIR=%currDisk%\_PC\us\u0376_pentevofix\
SET UNR_EXE=emul.exe

соответственно задают путь и имя файла анрила
make_trd.cmd


rem make_trd.cmd
@echo off

setlocal enabledelayedexpansion

set currDir=%cd%
set currDisk=%~d0

cd ..
set PROJECT=!currDir:%cd%\=!
cd %currDir%

:MAIN
SET UTILS_PATH=%currDisk%\_Work\_utils\

IF EXIST %PROJECT%.trd GOTO COPY_FILES

:CREATE_TRD
%UTILS_PATH%\trdtool.exe # %PROJECT%.trd

:COPY_FILES
%UTILS_PATH%\trdetz.exe %PROJECT%.trd del %PROJECT%.C
%UTILS_PATH%\trdtool.exe @ %PROJECT%.trd
%UTILS_PATH%\trdtool.exe + %PROJECT%.trd %PROJECT%.C
%UTILS_PATH%\trdetz.exe %PROJECT%.trd fprop %PROJECT%.C start 32768

GOTO END

:END
endlocal


Сохранение бинарника в main.asm должно выглядеть так

        ; build
	IF (_ERRORS == 0 && _WARNINGS == 0)
		LABELSLIST "user.l"
		SAVEBIN "main.bin",BEGIN,EOP-BEGIN
		PAGE 0
		SAVESNA "main.sna",BEGIN
	ENDIF


В дальнейшем достаточно копировать эти два батника из проекта в проект и при необходимости менять адрес загрузки при создании трд.

51 комментарий

avatar
В автосборщике запилятора (R.I.P.) похожий батник. Совпадение? ;-)
  • nyuk
  • +1
avatar
не знаю, не видел)
avatar
Добавлю 5 копеек — когда компилируем один из эффектов, который состоит из основного блока и опционально данных в странице — удобно видеть что сколько занимает и насколько хорошо пакуется:

@"system/MegaLZ.exe" compile/effect.bin compile/effect.bin.mlz > nul
@for /f %%i in ("compile/effect.bin") do @set SizeBin=%%~zi
@for /f %%i in ("compile/effect.bin.mlz") do @set SizeBinCompress=%%~zi
@set /a Percent= 100-100*SizeBinCompress/SizeBin
@
@"system/MegaLZ.exe" compile/pg0.bin compile/pg0.bin.mlz > nul
@for /f %%i in ("compile/pg0.bin") do @set SizeBin0=%%~zi
@for /f %%i in ("compile/pg0.bin.mlz") do @set SizeBinCompress0=%%~zi
@set /a Percent0= 100-100*SizeBinCompress0/SizeBin0
@
@"system/MegaLZ.exe" compile/pg7.bin compile/pg7.bin.mlz > nul
@for /f %%i in ("compile/pg7.bin") do @set SizeBin7=%%~zi
@for /f %%i in ("compile/pg7.bin.mlz") do @set SizeBinCompress7=%%~zi
@set /a Percent7= 100-100*SizeBinCompress7/SizeBin7
@echo --------------------------------
@echo FX PACKED SIZE: from %SizeBin% to %SizeBinCompress%, SAVED: %Percent% percent
@echo PG0 PACKED SIZE: from %SizeBin0% to %SizeBinCompress0%, SAVED: %Percent0% percent
@echo PG7 PACKED SIZE: from %SizeBin7% to %SizeBinCompress7%, SAVED: %Percent7% percent
@echo --------------------------------


И не всегда при компиляции требуется запуск (в данному случае просто запуск, но можно как у тебя).

@set /p input="1 to execute"
@if %input% == 1 start demo.trd
exit
  • TmK
  • +5
avatar
TmK, если верить моим тестам пакеров, MegaLZ, видимо, уже морально устарел как пакер. Средняя скорость распаковки у него медленнее чем у бесстекового Hrust или Appack, по средней степени сжатия и Hrust и Appack тоже бьют его. Exomizer существенно лучше жмёт, ZX7 существенно быстрее распаковывает. Обновляй себе тулчейн :)
avatar
а упаковщики под винду есть? и если можно ссылочек бы отсыпать до кучи)
avatar
Без упаковщиков под винду я вообще не рассматриваю даже :)

Хороший (насколько я помню, неоптимальный) упаковщик для Hrust сделал lvd: archive.is/mhmt.googlecode.com (я не знаю, где находится современная версия репозитория); там же есть распаковщики. На zx-pk.ru пролетал альтернативный, якобы более оптимальный упаковщик; я его не тестировал.
Вот здесь подборка материалов для Appack: karoshi.auic.es/index.php?topic=2416.0 (изначально это сеговский упаковщик).
Exomizer берут тут: hem.bredband.net/magli143/exo/
ZX7 берут тут: www.worldofspectrum.org/infoseekid.cgi?id=0027996
avatar
appack (aPLlib) изначально был пакером 16-битных exe-шников для MS-DOS. Потом его портировали на кучу 8-16 битных платформ, что и является его главным преимуществом. Например, я постоянно использую его на SNES.
avatar
На спектруме, будьте осторожны, есть баг в распаковщиках пошустрее: важно сбросить флаг С в AF'. Т.е. перед запуском распаковки реально важно сделать что-то типа
ex af,af' : or a : ex af,af'
avatar
я вот что не понял: у какого распаковщика?
и зачем ex af,af'?
avatar
У Appack. Ответ на твой второй вопрос — в коде распаковщика. Авторы забыли проинициалировать нужный им флаг С.
avatar
Вау, ребята! Мои батники намного проще :)
avatar
Меряться батниками топик!

@echo off

SET PROJECT=sosochi2016

SET UTILS_PATH=..\!utils
SET EMUL_PATH=Z:\zx\pc\emuls\us\unreal.exe
rem SET EMUL_PATH=Z:\ZX\pc\emuls\Spectaculator\Spectaculator.exe

del /q %PROJECT%.*

%UTILS_PATH%\sjasmplus.exe --lst=%PROJECT%.lst --inc=sources\. sources\%PROJECT%.asm

IF NOT EXIST %PROJECT%.sna GOTO ERROR

rem Make release archive
%UTILS_PATH%\PKZIP25.EXE -add .\!release\%PROJECT%.zip %PROJECT%.trd > nul
%UTILS_PATH%\PKZIP25.EXE -add .\!release\%PROJECT%.zip .\!release\file_id.diz > nul

rem Test it
%EMUL_PATH% %PROJECT%.sna

GOTO END


:ERROR
EXIT 1

:END
  • nyuk
  • +4
avatar
ну сам костяк я у тебя спер в свое время, но мне быстро надоело (начиная со второго раза) писать
SET PROJECT=<project name>

:)
avatar
Ура!
@echo off
_bin\scrsplit graphics\mmcm2_intro.scr res\mmcm2_intro.6144 res\mmcm2_intro.768 >nul
del /q res\mmcm2_intro.6144.rcs res\mmcm2_intro.6144.rcs.zx7 >nul
_bin\rcs res\mmcm2_intro.6144 res\mmcm2_intro.6144.rcs >nul
_bin\zx7 res\mmcm2_intro.6144.rcs res\mmcm2_intro.6144.rcs.zx7 >nul
_bin\appack c res\mmcm2_intro.768 res\mmcm2_intro.768.appack >nul

_bin\appack c graphics\mmcm_loading.scr res\mmcm_loading.appack >nul
_bin\scrsplit graphics\mmcm_loading.scr res\mmcm_loading.6144 res\mmcm_loading.768 >nul
_bin\appack c res\mmcm_loading.768 res\mmcm_loading.768.appack >nul

_bin\sjasmplus.exe mmcm.asm

_bin\appack c hypetro.bin hypetro.appack >nul
del /q hypetro.bin
_bin\sjasmplus.exe hwprobe.asm
_bin\appack c hwprobe.bin hwprobe.appack >nul
_bin\sjasmplus.exe hwinstall.asm

_bin\mktap -b "MMCM-TBY" 0 <mmcm.bas >p1.tap
_bin\bin2tap -c hw.bin p2.tap "hw" 40000 >nul
_bin\bin2tap -c mmcm.bin p3.tap "mmcm" 24320 >nul
copy /b /y p1.tap+p2.tap+p3.tap mmcm.tap >nul
del /q p1.tap p2.tap p3.tap >nul

_bin\mktap -b -rr "boot" 10 <boot.bas >boot.bin
del /q mmcm.trd mmcm.scl
_bin\sjasmplus trdos.asm

del /q hw.bin hwprobe.bin hwprobe.appack hypetro.appack >nul

del /q mmcm.bin mmcm_tby.trd mmcm_tby.tap mmcm_tby.scl
ren mmcm.tap mmcm_tby.tap
ren mmcm.scl mmcm_tby.scl
ren mmcm.trd mmcm_tby.trd

7z a -tzip -mx9 mmcm_tby.zip mmcm_tby.nfo mmcm_tby.tap mmcm_tby.scl mmcm_tby.trd mmcm_tby.nfo.png mmcm_tby.title.screen.png >nul
avatar
Я вообще компилирую без батников.
На стадии написания и отладки В исходнике пишу savesna "%path_to_unreal%/qsave1.sna", start
— и держу наготове уже запущенный унрил. И после компиляции просто нажимаю в нем ALT+F3 — и снапшот сразу же запускается.
  • sq
  • +6
avatar
ишь, какой хитрый способ))
avatar
А или вы про автосборщик?)
  • sq
  • +2
avatar
ну в моем случае скорее автосборщик, да не скорее, а он и есть
avatar
да уж.
f12 (build) в sublime text.
потом батник:
spgbld.exe -b spgbld.ini zifi.spg
  • VBI
  • +2
avatar
естественно на абсолютную истину не претендую)))
просто мне, как мегаленивому и стольже полоротому, лень в текстах писать имя проекта
типа
spgbld.exe -b spgbld.ini zifi.spg
имя проекта пишу 1 раз, когда создаю папку проекта.
потом ctrl+b, все компиляется с нужными именами, собирается в трдэшник, киляется существующий экземпляр анрила, и запускается новый.
avatar
ну конечно. я тоже пишу имя один раз :))
но это мелочи всё.
я говорю о том что в сублим текст с плагом под з80 эти вопросы (батников) уже решены.
avatar
кхм… тогда вопрос как это делается? ибо саблим с плагом имеются, собсна в саблиме и пушу
avatar
наверное некоторое недопонимание возникло :)
Z80Asm > Settings > Build script (win)
тут и батничек уже готовый
avatar
Z80Asm > Settings > Build script (win)
слона-то я и не приметил!)))
этож красивее и умнее можно сделать!))
как минимум проверять на маке. бат и запускать его если имеется, иначе по дефолту сделать как у меня.
/me потирает руки
avatar
отметь что там есть ещё отдельные скрипты для разных систем, и по запуску тоже, и ваще хороших плаг :)
avatar
ага, уже обратил внимание))
avatar
Меня не устроил билдер. встроенный в саблим-плагин. Корячить готовый продукт не хотелось, по-быстрому накидал свой. По F7 собираю проект и сразу запускаю, прямо из саблима.

{
	"working_dir": "$file_path\\..\\",
	"cmd": "make.cmd",
	"file_regex": "^[ ]*File \"(...*?)\", line ([0-9]*)",
	"encoding": "cp866"
}
avatar
нечитаторы мана по ужасм и ниасиляторы ужасм в треде!


;--------------------------------------------------------------------
 macro	sectors datab,datae

 IF low (datae-datab)=0
   db 1,5,high (datae-datab)
 ELSE
   db 1,5,(1+high (datae-datab))
 ENDIF

	endm

 MODULE boot
Basic:
 db #00,#01;номер строки
 DW EndLine1 - Line1
Line1:
 db #EA;REM
 ld sp,#5FE0

 xor a:out ($FE),a
 ld hl,$5AFF,de,$5AFE,bc,6912,(hl),0:lddr
;----------------------------demo------------
 di
;pic
 ld de,(#5CF4)
 ld hl, #4000
 sectors titl_b,titl_e
 call #3d13
;demo
 ld a,#10,bc,#7FFD:out (c),a
 ld de,(#5CF4)
 ld hl, #6000
 sectors begin,end
 call #3d13

;p0
 ld de,(#5CF4)
 ld hl, #C000
 sectors page0b,page0e
 call #3d13

;p1
 ld a,#11,bc,#7FFD:out (c),a
 ld de,(#5CF4)
 ld hl, #C000
 sectors page1b,page1e
 call #3d13
;p3
 ld a,#13,bc,#7FFD:out (c),a
 ld de,(#5CF4)
 ld hl, #C000
 sectors page3b,page3e
 call #3d13
;p4
 ld a,#14,bc,#7FFD:out (c),a
 ld de,(#5CF4)
 ld hl, #C000
 sectors page4b,page4e
 call #3d13
;p6
; ld a,#16,bc,#7FFD:out (c),a
; ld de,(#5CF4)
; ld hl, #C000
; sectors page6b,page6e
; call #3d13
;p7
 ld a,#17,bc,#7FFD:out (c),a
 ld de,(#5CF4)
 ld hl, #DD00
 sectors page7b,page7e
 call #3d13

 jp #6000

 db "AAA-stupid moron"
 db #0D
EndLine1:
 db #00,#02
 DW EndLine2 - Line2
Line2:
 db #20,#FD,#B0
 db #22,#32,#34,#35,#37,#35,#22;clear val "24575"
 db #3A; :
 db #F9,#C0,#28,#35;randomize usr (5+256*peek val "23635"+peek val "23636"
 db #0E,#00,#00,#05,#00,#00,#2B
 db #32,#35,#36
 db #0E,#00,#00,#00,#01,#00,#2A,#BE

 db #B0
 db #22,#32,#33,#36,#33,#36,#22;"23635"
 db #2B;???
 db #BE
 db #B0
 db #22,#32,#33,#36,#33,#35,#22;"23636"
 db #29,#0D;)
 db #80
 db #AA,1,0;;;;;;;;;;;;;autorun line,change program length to -4, e.g. 83-4=79
EndLine2:
EndBasic:
 ENDMODULE

    EMPTYTRD "verita.trd" ;create empty TRD image
	SAVETRD "verita.trd", "boot.B", boot.Basic, boot.EndBasic - boot.Basic

 savetrd "verita.trd","pic.C",titl_b,titl_e-titl_b
 savetrd "verita.trd","demo.C",begin,end-begin
 
 page 0
 savetrd "verita.trd","p0.C",page0b,page0e-page0b



сборка:


sjasmplus man.asm
if errorlevel 1 goto :exit
:exit
pause


Если нужны дополнительные файлы, размер которых не больше 16384 байт, то удобнее раскидать по страницам и сохранять на .TRD непосредственно при сборке.
Если файл не помещается. поможет Writetrd.exe(наверное)
avatar
Нечто подобное я и использую, причем давно уже. Возьми любой запиляторный запил и убедись :-)
Просто, для начала стоит давать что-то попроще, не?
avatar
я писал на портале вцт статью о создании trd/csl/tap, но заметка пропала.
avatar
Не батник, но всё же:

#!/bin/bash

read -p"source: " SOURCE
read -p"output: " OUTPUT

wct $SOURCE $OUTPUT
b2t -b $OUTPUT
  • Mihip
  • +2
avatar
Раз пошла такая пьянка, признаюсь: я пользуюсь Makefile'ами :) Правда, под пингвином. Выглядят они как-то так. Удобно то, что пересобираются только изменённые файлы, при этом отслеживаются зависимости. Например, команда make run сначала соберёт снапшот (при его отсутствии), а уже потом запустит эмуль с ним ;) А виндовых батников я действительно опасаюсь, это да.
avatar
Ахаха, этот коммент лучше всего остального топика со всеми его комментами! :)
avatar
Если бы время сборки оправдывало эти усилия, я бы тебя понял. Но так, положа руку на сердце…
avatar
Кстати, о сборках(быдлокод внутри:)

scl_e:

	savebin "huj.scl",scl_b,scl_e-scl_b

	LUA

	local fp
	local checksum
-- never rename file
	fp = assert(io.open("huj.scl", "rb"))
	checksum=0
	while true do
		local byte = fp:read(1)
		if byte==nil then
			break
		end
		checksum=checksum+string.byte(byte)
	end
	assert(fp:close())
	print("writing",string.format("%08X",checksum))
	fp = assert(io.open("huj.scl", "a"))

	for i=1,4 do
    	fp:write(string.char(checksum%256))
    	checksum=math.floor(checksum/256)
    end

--	assert(fp:flush())
	assert(fp:close())

--	os.rename("huj.scl", "Xtermin.scl")

	local ss=""
	for i=0,7,1 do
		ss=ss..string.char( sj.get_byte( sj.get_label("file1")+i ) )
	end

	ss=ss:match "^%s*(.-)%s*$"
--	print(ss)
	os.rename("huj.scl", ss..".scl")

	ENDLUA
avatar
Отчасти согласен. Но отчасти. Но согласен ;)
Мейкфайл я не пишу каждый раз заново, просто беру предыдущий и немного правлю (это можно заметить по его корявости, хехе). Поэтому особых усилий как бы и нету. Зато я ленивый, рассеянный и люблю часто собирать, ничего не могу с собой поделать ;) Сборка собственно кода времени особо не занимает, да, но вот в пеппе, например, было двадцать с чем-то картинок, которые постоянно подправлялись. После каждой правки — опять конверсия, упаковка и всё такое. А ещё Олежа выдаёт по десять новых версий трека в секунду, когда разойдётся ;) Так что лично мне просто проще один раз написать мейкфайл и потом не париться.
avatar
Нене, я всё это понимаю. Но, как ты понимаешь, у меня в точности то же самое, только батником. Когда время полной сборки меряется десятыми долями секунды, намного труднее оправдать make. Здесь вам не C++ :)

На самом деле, было бы интересно услышать реальные доводы в пользу make, кроме, понятно, привычки, индустриальных стандартов и т.д. На #z80 было несколько баталий, все аргументы которых свелись примерно к тому, что make — это «правильно». Но почему это так в нашем случае — никто так и не узнал.
avatar
Привычка, да. Ну, еще make заменяет пачку батников (все в одном файле и без лишних условий). Но по скорости, конечно, если ресурсы делаются долго — выручает. Бывает не только запаковать чего. У меня самое долгое был конверт молелей из obj, там еще искались зеркальные/зеркальные c коэфициентом вершины, очень наивная реализация, (n^хрензнаетсколько), секунды на модель.

А вообще, было бы круто создать общую репу со скриптами (я так понимаю, питон?) для сборок(trd, например, хотя я из сжасма делал)/конверсий(форматы, спрайты, гифки:)/генераций табличек(логарифмы/синусы).
avatar
Вот я сейчас собрал дему и думаю о том же самом. Куча идей витает в воздухе, но никто их вместе не знает. Постараюсь на следующей неделе набросать костяк. У меня куча утилит командной строки, часть своих, часть стандартных. Но их даже найти бывает сложно…
avatar
Да, такой репозиторий очень был бы полезен.
avatar
Make будет работать везде: и на пингвине и на маке и на windows 10 с башем :)
avatar
Python тоже. Я вот сейчас для рабочего проекта скрипты сборки написал на чистом питончике. А там есть и SCons.
avatar
Плюсую. Makeфайлы и вправду избавляют от кучи хлопот.
avatar
до сих пор вспоминаю, как бегал по папкам и запускал make.bat, чтобы собрать ldd, да еще и за 2 часа до дедлайна :)
даже инструкция внутри ридмика от проекта осталась:
howto make it:
1. run "make.bat" in ALL directories
2. run "build.bat" in "\loader"
3. use "\loader\ldd.spg" as resulting file


На самом деле, как раз здесь я и использовал принцип «разделяй и властвуй» — делаем одну часть, отлаживаем, затем линкуем с остальной демой, максимально абстрагируясь от внутренней структуры части (главное — войти и потом выйти :).
avatar
Лол

@ECHO OFF
Tasm.exe -80 file.asm
move FILE.obj file.hex
hextobin.exe -c file.hex

bin2trd aaa.trl

del file.hex
del file.lst
del file.bin
aaa.trd
pause
avatar
Простенько и со вкусом.
А вот тасм я недолюбливаю.
avatar
бугага, где ты его нашел?

я для Altair и проц 8080 писал проги и выходили бинарники:

tasm -85  -b -g3 bl.asm bl.bin
avatar
хренассе топик развел)
тогда уж давайте придумаем универсальный скрипт
avatar
А ещё лучше сделать онлайн компилятор. Вводишь код, компилируешь, забираешь бинарник. Как на wctportal.ru/builder/
avatar
Есть такой, хотя и не рабочий.
avatar
Я познал Makefile. Ну ладно, ок, не совсем еще познал. Как минимум, талмуд стоило бы прочитать.

В общем, все части демы, сколько бы их не было, собираются и пакуются одним сценарием. Чтобы добавить сборку еще одной части, просто добавляю её имя в перечисление. Ну и там контроль наличия файлов, чтобы каждый раз не пересобирались.

gist.github.com/akanyuk/7d98ffeeac1316b42d10917f208b85e2
  • nyuk
  • 0
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.