Skip to content

Instantly share code, notes, and snippets.

@Pokeman2003
Created April 4, 2024 22:47
Show Gist options
  • Save Pokeman2003/9795ebb04e1036d0099efa765a1c898f to your computer and use it in GitHub Desktop.
Save Pokeman2003/9795ebb04e1036d0099efa765a1c898f to your computer and use it in GitHub Desktop.
Makes assembling with WLA-DX on Windows even easier.
@echo off
REM Pokeman's omni-assembler
REM Essentially a fancy makefile script
REM Verison 4/4/2024 variant B
REM Modifiable settings are found at line 17-32.
echo Pokeman's omni-assembler called
if [%1] EQU [] echo No target!&goto :EOF
REM Counters, don't touch these! Settings are below!
set totalFiles=0
set totalProjects=0
set totalErrors=0
set listErrors=
set listFiles=
REM Locations
REM Where all of the WLA* files are.
set baseLocation="%~dp0
REM Where all of the object files are placed before it.
set dumpZone="%temp%\dump\"
REM Where the output is placed after it's done. Should be in 8.3 format.
set outLocation=%~sdp1..\
REM A bunch of defaults.
REM The output name.
set "doutname=a.out"
REM Assembler and linker flags.
set "dasmflag=-v2"
set "dlinflag=-v2"
REM Generic linker script.
set "dlinker=call %0 :genlinkprog %%~sdp0 %%~sdp1 %dumpZone%"
REM Special circumvention rule for labels.
REM PROGRAMMERS: While you can access /any/ label, the one you probably want to
REM access is the default linker, genlinkprog seen @ line 155
set testLabel=%~1
set runLabel=%testLabel:~1%
set testLabel=%testLabel:~0,1%
if [%testLabel%] EQU [:] goto runLabel
set testLabel=
set runLabel=
REM You'd never need to call main loop nor completed with the label bypass.
REM That said, you /can/ create 3 optional files to interact with the various stages.
REM OAF_pre.bat Executed before assembly begins.
REM OAF_inter.bat Executed between assembly and linkage.
REM OAF_post.bat Executed after linkage.
REM There are additional, mandatory files which can be found in :initializeFiles
REM and the the defaults.
echo Started %time% @ %date%
:mainLoop
REM Initialization.
rmdir %dumpZone% /S /Q 1>nul 2>nul
set projectFiles=0
set projectErrors=0
if [%1] EQU [] goto completed
mkdir %dumpZone% 1>nul 2>nul
echo Now processing project %1
cd "%~f1"
call :getStringLength %~sdp1
set /a currentLength=%length%+1
call :initializeFiles
REM Attempt to assemble.
if exist "OAF_preasm.bat" call "OAF_pre.bat" %0 %1
for /f %%a in ('dir /b %baseLocation%wla-*.exe"') do (
call :procfiles %%a
)
REM Begin linkage.
if exist "OAF_inter.bat" call "OAF_inter.bat" %0 %1
call "OAF_linker.bat" %0 %1
if exist "OAF_post.bat" call "OAF_post.bat" %0 %1
REM Complete loop.
shift
echo Done %time% @ %date%
set /a totalProjects=%totalProjects%+1
set /a totalFiles=%totalFiles%+%projectFiles%
set /a totalErrors=%totalErrors%+%projectErrors%
set listFiles=%listFiles%%projectFiles%,
set listErrors=%listErrors%%projectErrors%,
goto mainLoop
:completed
REM End of file.
echo Finished %time% @ %date%
echo Projects: %totalProjects%
echo Files: %totalFiles%
echo Errors: %totalErrors%
echo Readout of each project
echo Files: %listFiles%
echo Errors: %listErrors%
goto :eof
:initializeFiles
REM Initializes files.
REM Output name is stored in OAF_outname.oaf
if not exist "OAF_outname.oaf" echo %doutname%>"OAF_outname.oaf"
REM Assembly flags are stored in OAF_asmflag.oaf
if not exist "OAF_asmflag.oaf" echo %dasmflag%>"OAF_asmflag.oaf"
REM Linker flags are stored in OAF_linflag.oaf (May have no effect if you choose not to use :genlinkprog)
if not exist "OAF_linflag.oaf" echo %dlinflag%>"OAF_linflag.oaf"
REM The linker script is stored in OAF_linker.bat
if not exist "OAF_linker.bat" echo %dlinker%>"OAF_linker.bat"
set /p outname=<"OAF_outname.oaf"
set /p asmflag=<"OAF_asmflag.oaf"
set /p linflag=<"OAF_linflag.oaf"
goto :eof
:runLabel
REM Circumvention system. Do not execute this label, it requires special setup.
shift
echo Executing %runLabel%
call :%runLabel% %1 %2 %3 %4 %5 %6 %7 %8 %9
goto :eof
:procFiles
REM Clownery.
REM 1: Which architecture to target.
set shortHand=%1
set shortHand=%shortHand:~4,-4%
for /f "delims=" %%a in ('dir /b /s "*.%shortHand%" 2^>nul') do (
call :assembleFile "%%a" %shortHand% %%~sdpa
)
goto :eof
:assembleFile
REM Constructs the .o in the dumpzone
REM 1: File
REM 2: Assembler
REM 3: Dumpzone additional path.
set dumpFolder=%3
call set dumpFolder=%%dumpFolder:~%currentLength%%%
if [%dumpFolder%] NEQ [] if not exist [%dumpZone%%dumpFolder%] mkdir "%dumpZone%%dumpFolder%
%baselocation%wla-%2.exe" %asmflag% -o "%dumpZone:~1,-1%%dumpFolder%%~n1.o" "%~f1"
if %errorlevel% NEQ 0 echo ERROR ASSEMBLING! &type %dumpZone%error.log&set /a projectErrors=%projectErrors%+1
set /a projectFiles=%projectFiles%+1
goto :eof
:getStringLength
REM Looks for the length of a string. Theoretically can parse 8191 characters.
REM Realistically, it can only really parse about 7989.
REM 1: String
set length=0
set _=%1
:getStringLengthLoop
REM Don't call this label. Ever.
set _=%_:~1%
if [%_%] NEQ [] set /a length=%length%+1&goto :getStringLengthLoop
set _=
goto :eof
:genlinkprog
REM Generic generator for programs. It would be a good idea to study it.
REM 1: Location of executing script
REM 2: Location of the linker
REM 3: Location of the dumpzone.
REM Additional files can be placed in %1\OAFLink\ to be appended.
REM OAF_library.oaf [libraries]
REM OAF_header.oaf [header]
REM OAF_footer.oaf [footer]
REM OAF_define.oaf [definitions]
REM OAF_ram.oaf [ramsections]
REM OAF_rom.oaf [sections]
REM OAF_romwo.oaf [sectionwriteorder]
REM OAF_ramwo.oaf [ramsectionwriteorder]
cd %3
REM Check if any files exist first.
set _=
for /f %%a in ('dir /b "*.o" 2^>nul') do (set _=0)
if [%_%] EQU [] echo No objects!&goto :eof
set _=
REM Begin construction.
echo Constructing...
echo [objects]>linker.log
for /f %%a in ('dir /b /s "*.o" 2^>nul') do (
echo %%a>>linker.log
)
REM Optionals
echo [libraries]>>linker.log
if exist "%~1OAFLink\OAF_library.oaf" type "%~1linkage\OAF_library.oaf">>linker.log
echo [header]>>linker.log
if exist "%~1OAFLink\OAF_header.oaf" type "%~1linkage\OAF_header.oaf">>linker.log
echo [footer]>>linker.log
if exist "%~1OAFLink\OAF_footer.oaf" type "%~1linkage\OAF_footer.oaf">>linker.log
echo [definitions]>>linker.log
if exist "%~1OAFLink\OAF_define.oaf" type "%~1linkage\OAF_define.oaf">>linker.log
echo [ramsections]>>linker.log
if exist "%~1OAFLink\OAF_ram.oaf" type "%~1linkage\OAF_ram.oaf">>linker.log
echo [ramsectionwriteorder]>>linker.log
if exist "%~1OAFLink\OAF_ramwo.oaf" type "%~1linkage\OAF_ramwo.oaf">>linker.log
echo [sections]>>linker.log
if exist "%~1OAFLink\OAF_rom.oaf" type "%~1linkage\OAF_rom.oaf">>linker.log
echo [sectionwriteorder]>>linker.log
if exist "%~1OAFLink\OAF_romwo.oaf" type "%~1linkage\OAF_romwo.oaf">>linker.log
REM Now we execute the linker.
echo Executing...
"%~2wlalink.exe" %linflag% linker.log "%outLocation%%outname%" 2>error.log
if %errorlevel% NEQ 0 echo ERROR LINKING! &type %dumpZone%error.log
cd %1
goto :eof
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment