From 357817d49ee9bc7a87ded1eb06f51fd6f08977bc Mon Sep 17 00:00:00 2001 From: ggn Date: Sat, 23 Jul 2022 20:09:40 +0300 Subject: [PATCH] Introducing .align directive, thanks to Bastian Schick for most of the implementation. Also, updated documentation and Windows script --- direct.c | 45 +++++++++- direct.tab | 2 + docs/rmac.rst | 29 ++++--- listing.c | 2 +- maketabs.bat | 221 +++++++++++++++++++------------------------------- 5 files changed, 148 insertions(+), 151 deletions(-) rewrite maketabs.bat (68%) diff --git a/direct.c b/direct.c index 585764a..c15d109 100644 --- a/direct.c +++ b/direct.c @@ -90,6 +90,7 @@ int d_prgflags(void); int d_opt(void); int d_dsp(void); int d_objproc(void); +int d_align(void); void SetLargestAlignment(int); // Directive handler table @@ -163,6 +164,7 @@ int (*dirtab[])() = { d_opt, // 66 .opt d_objproc, // 67 .objproc (void *)d_dsm, // 68 .dsm + d_align // 69 .align }; @@ -841,6 +843,47 @@ int d_qphrase(void) return 0; } +// +// Adjust location to bytes +// +int d_align(void) +{ + unsigned bytesToSkip; + uint64_t eval; + + if (abs_expr(&eval) != OK) + return 0; + + if (eval < 2) + { + return error("Invalid .align value specified"); + } + + if (dsp56001) + { + bytesToSkip = eval - sloc % eval; + D_ZEROFILL(bytesToSkip*3); + return 0; + } + + bytesToSkip = eval - (rgpu || rdsp ? orgaddr : sloc) % eval; + if ( bytesToSkip != eval ) + { + if ((scattr & SBSS) == 0) + { + D_ZEROFILL(bytesToSkip); + } + else + { + sloc += bytesToSkip; + + if (orgactive) + orgaddr += bytesToSkip; + } + } + return 0; +} + // // Do auto-even. This must be called ONLY if 'sloc' is odd. @@ -1156,7 +1199,7 @@ int d_ds(WORD siz) if (expr(exprbuf, &eval, &eattr, NULL) < 0) return ERROR; - + // Check to see if the value being passed in is negative (who the hell does // that?--nobody does; it's the code gremlins, or rum, what does it) // N.B.: Since 'eval' is of type uint64_t, if it goes negative, it will diff --git a/direct.tab b/direct.tab index d05e858..eb4581f 100644 --- a/direct.tab +++ b/direct.tab @@ -113,6 +113,8 @@ opt 66 .objproc 67 .dsm 68 dsm 68 +.align 69 +align 69 .if 500 if 500 .else 501 diff --git a/docs/rmac.rst b/docs/rmac.rst index 78e2d34..3e5d91e 100644 --- a/docs/rmac.rst +++ b/docs/rmac.rst @@ -17,12 +17,10 @@ the accuracy of printed or duplicated material after the date of publication and disclaims liability for changes, errors or omissions.* -*Copyright © 2011-2020, Reboot* +*Copyright © 2011-2022, the rmac authors* *All rights reserved.* -*Reboot Document number F00000K-001 Rev. A.* - Contents ======== @@ -127,7 +125,7 @@ Switch Description -fx Atari 800 com/exe/xex output object file format. -i\ *path* Set include-file directory search path. -l\ *[file[prn]]* Construct and direct assembly listing to the specified file. --l\ *\*[filename]* Create an output listing file without pagination. +-l\ *\*[filename]* Create an output listing file without pagination -m\ *cpu* Switch CPU type `68000 - MC68000` @@ -157,12 +155,12 @@ Switch Description +o\ *0-30*/*p* Enable specific optimisation ~o\ *0-30*/*p* Disable specific optimisation - `0: Absolute long adddresses to word (on by default)` - - `1: move.l #x,Dn/An to moveq (on by default)` - - `2: Word branches to short (on by default)` + `0: Absolute long adddresses to word` + + `1: move.l #x,Dn/An to moveq` + `2: Word branches to short` + `3: Outer displacement 0(An) to (An)` `4: lea to addq` @@ -181,7 +179,7 @@ Switch Description `11: 56001 Auto convert short addressing mode to long (default: on)` - `o30: Enforce PC relative (alternative name: op)` + `30: Enforce PC relative (alternative name: op)` -p Produce an executable (**.prg**) output file. -ps Produce an executable (**.prg**) output file with symbols. @@ -638,7 +636,7 @@ and may not be used as symbols (e.g. labels, equates, or the names of macros): a0 a1 a2 a3 a4 a5 a6 a7 Tom/Jerry: r0 r1 r2 r3 r4 r5 r6 r7 - r8 r9 r10 r11 r12 rl3 r14 r15 + r8 r9 r10 r11 r12 r13 r14 r15 6502: x y a DSP56001: @@ -1023,7 +1021,14 @@ Directives relating to the 6502 are described in the chapter on `6502 Support`_. Therefore, to align GPU/DSP code, align the current section before and after the GPU/DSP code. - **.assert** *expression* [,\ *expression*...] +**.align** *expression* + + A generalised version of the above directives, this will align the program + counter to the boundary of the specified value. Note that there is not much + error checking happening (only values 0 and 1 are rejected). Also note that + in DSP56001 mode the align value is assumed to be in DSP words, i.e. 24 bits. + +**.assert** *expression* [,\ *expression*...] Assert that the conditions are true (non-zero). If any of the comma-seperated expressions evaluates to zero an assembler warning is issued. For example: diff --git a/listing.c b/listing.c index d5a2296..e13856e 100644 --- a/listing.c +++ b/listing.c @@ -132,7 +132,7 @@ void date_string(char * buf, uint32_t date) // // Transform letters a-f in the address and data columns of the listing to -// uppercase. (People seem to like uppercase hex better in assembly-language +// uppercase. (People seem to like uppercase hex better in assembly-language // listings....) // void uc_ln(char * ln) diff --git a/maketabs.bat b/maketabs.bat dissimilarity index 68% index 70b8ad6..73425b5 100644 --- a/maketabs.bat +++ b/maketabs.bat @@ -1,137 +1,84 @@ -@echo off -REM Check for file dates and build .h files if needed - -SET FILE1=68k.mch -SET FILE2=68ktab.h -if not exist %FILE2% GOTO BUILD -for /F %%i IN ('dir /b /OD %FILE1% %FILE2% ^| more +1') DO SET NEWEST=%%i -if %NEWEST%==%FILE1% GOTO BUILD - -SET FILE1=direct.tab -SET FILE2=mntab.h -if not exist %FILE2% GOTO BUILD -for /F %%i IN ('dir /b /OD %FILE1% %FILE2% ^| more +1') DO SET NEWEST=%%i -if %NEWEST%==%FILE1% GOTO BUILD - -SET FILE1=kw.tab -SET FILE2=kwtab.h -if not exist %FILE2% GOTO BUILD -for /F %%i IN ('dir /b /OD %FILE1% %FILE2% ^| more +1') DO SET NEWEST=%%i -if %NEWEST%==%FILE1% GOTO BUILD - -SET FILE1=risc.tab -SET FILE2=risckw.h -if not exist %FILE2% GOTO BUILD -for /F %%i IN ('dir /b /OD %FILE1% %FILE2% ^| more +1') DO SET NEWEST=%%i -if %NEWEST%==%FILE1% GOTO BUILD - -SET FILE1=dsp56k.mch -SET FILE2=dsp56ktab.h -if not exist %FILE2% GOTO BUILD -for /F %%i IN ('dir /b /OD %FILE1% %FILE2% ^| more +1') DO SET NEWEST=%%i -if %NEWEST%==%FILE1% GOTO BUILD - -SET FILE1=6502.tab -SET FILE2=6502kw.h -if not exist %FILE2% GOTO BUILD -for /F %%i IN ('dir /b /OD %FILE1% %FILE2% ^| more +1') DO SET NEWEST=%%i -if %NEWEST%==%FILE1% GOTO BUILD - -SET FILE1=op.tab -SET FILE2=opkw.h -if not exist %FILE2% GOTO BUILD -for /F %%i IN ('dir /b /OD %FILE1% %FILE2% ^| more +1') DO SET NEWEST=%%i -if %NEWEST%==%FILE1% GOTO BUILD - -SET FILE1=68kregs.tab -SET FILE2=68kregs.h -if not exist %FILE2% GOTO BUILD -for /F %%i IN ('dir /b /OD %FILE1% %FILE2% ^| more +1') DO SET NEWEST=%%i -if %NEWEST%==%FILE1% GOTO BUILD - -SET FILE1=56kregs.tab -SET FILE2=56kregs.h -if not exist %FILE2% GOTO BUILD -for /F %%i IN ('dir /b /OD %FILE1% %FILE2% ^| more +1') DO SET NEWEST=%%i -if %NEWEST%==%FILE1% GOTO BUILD - -SET FILE1=6502regs.tab -SET FILE2=6502regs.h -if not exist %FILE2% GOTO BUILD -for /F %%i IN ('dir /b /OD %FILE1% %FILE2% ^| more +1') DO SET NEWEST=%%i -if %NEWEST%==%FILE1% GOTO BUILD - -SET FILE1=riscregs.tab -SET FILE2=riscregs.h -if not exist %FILE2% GOTO BUILD -for /F %%i IN ('dir /b /OD %FILE1% %FILE2% ^| more +1') DO SET NEWEST=%%i -if %NEWEST%==%FILE1% GOTO BUILD - -SET FILE1=unary.tab -SET FILE2=unarytab.h -if not exist %FILE2% GOTO BUILD -for /F %%i IN ('dir /b /OD %FILE1% %FILE2% ^| more +1') DO SET NEWEST=%%i -if %NEWEST%==%FILE1% GOTO BUILD - -GOTO END - -:BUILD - -echo Generating files... - -68kgen 68k.tab <68k.mch >68ktab.h -dsp56kgen dsp56k.tab dsp56ktab.h -type direct.tab 68k.tab | kwgen mn >mntab.h -kwgen kw kwtab.h -kwgen mr risckw.h -kwgen dsp dsp56kkw.h -kwgen mp <6502.tab >6502kw.h -kwgen mp <6502.tab >6502kw.h -kwgen mo opkw.h -kwgen reg68 <68kregs.tab >68kregs.h -kwgen reg56 <56kregs.tab >56kregs.h -kwgen reg65 <6502regs.tab >6502regs.h -kwgen regrisc riscregs.h -kwgen unary unarytab.h - -rem touch files that include these header files so they'll recompile -echo Generating tables... -copy /b amode.c +,, >NUL -copy /b direct.c +,, >NUL -copy /b expr.c +,, >NUL -copy /b mach.c +,, >NUL -copy /b procln.c +,, >NUL -copy /b riscasm.c +,, >NUL -copy /b token.c +,, >NUL -copy /b dsp56k_mach.c +,, >NUL - -:END - -REM If eagen0.c is newer than eagen.c then "touch" eagen.c so that visual studio will recompile both. -REM Same for amode.c / parmode.h and mach.c / 68ktab.h - -SET FILE1=eagen0.c -SET FILE2=eagen.c -for /F %%i IN ('dir /b /OD %FILE1% %FILE2% ^| more +1') DO SET NEWEST=%%i -if %NEWEST%==%FILE2% GOTO CHECK2 -Echo touching eagen0.c... -copy /b eagen.c +,, >NUL - -:CHECK2 -SET FILE1=parmode.h -SET FILE2=amode.c -for /F %%i IN ('dir /b /OD %FILE1% %FILE2% ^| more +1') DO SET NEWEST=%%i -if %NEWEST%==%FILE2% GOTO CHECK3 -Echo touching amode.c... -copy /b amode.c +,, >NUL - -:CHECK3 -SET FILE1=68ktab.h -SET FILE2=mach.c -for /F %%i IN ('dir /b /OD %FILE1% %FILE2% ^| more +1') DO SET NEWEST=%%i -if %NEWEST%==%FILE2% GOTO END -Echo touching mach.c... -copy /b mach.c +,, >NUL - -:END - +rem @echo off +REM Check for file dates and build .h files if needed + +call :CHECK_OUT_OF_DATE 68k.mch 68ktab.h +call :CHECK_OUT_OF_DATE direct.tab mntab.h +call :CHECK_OUT_OF_DATE kw.tab kwtab.h +call :CHECK_OUT_OF_DATE risc.tab risckw.h +call :CHECK_OUT_OF_DATE dsp56k.mch dsp56ktab.h +call :CHECK_OUT_OF_DATE 6502.tab 6502kw.h +call :CHECK_OUT_OF_DATE op.tab opkw.h +call :CHECK_OUT_OF_DATE 68kregs.tab 68kregs.h +call :CHECK_OUT_OF_DATE 56kregs.tab 56kregs.h +call :CHECK_OUT_OF_DATE 6502regs.tab 6502regs.h +call :CHECK_OUT_OF_DATE riscregs.tab riscregs.h +call :CHECK_OUT_OF_DATE unary.tab unarytab.h + +GOTO NOGEN + +:BUILD + +echo Generating files... + +68kgen 68k.tab <68k.mch >68ktab.h +dsp56kgen dsp56k.tab dsp56ktab.h +type direct.tab 68k.tab | kwgen mn >mntab.h +kwgen kw kwtab.h +kwgen mr risckw.h +kwgen dsp dsp56kkw.h +kwgen mp <6502.tab >6502kw.h +kwgen mp <6502.tab >6502kw.h +kwgen mo opkw.h +kwgen reg68 <68kregs.tab >68kregs.h +kwgen reg56 <56kregs.tab >56kregs.h +kwgen reg65 <6502regs.tab >6502regs.h +kwgen regrisc riscregs.h +kwgen unary unarytab.h + +rem Touch timestamps of files that include these header files so they'll recompile +echo Generating tables... +copy /b amode.c +,, >NUL +copy /b direct.c +,, >NUL +copy /b expr.c +,, >NUL +copy /b mach.c +,, >NUL +copy /b procln.c +,, >NUL +copy /b riscasm.c +,, >NUL +copy /b token.c +,, >NUL +copy /b dsp56k_mach.c +,, >NUL +copy /b eagen.c +,, >NUL +goto :END + +:NOGEN + +REM If eagen0.c is newer than eagen.c then "touch" eagen.c so that visual studio will recompile both. +REM Same for amode.c / parmode.h and mach.c / 68ktab.h +call :CHECK_AND_TOUCH eagen0.c eagen.c +call :CHECK_AND_TOUCH parmode.h amode.c +call :CHECK_AND_TOUCH 68ktab.h mach.c + +:END +exit /b + +rem Check if second passed file is older compared to the first, or doesn't exist, or is zero size. In which case go generate everything just to be sure +:CHECK_OUT_OF_DATE +SET FILE1=%1 +SET FILE2=%2 +if not exist %FILE2% GOTO BUILD +FOR /F "usebackq" %%A IN ('%FILE2%') DO set size=%%~zA +if "%size%"=="0" GOTO BUILD +for /F %%i IN ('dir /b /OD %FILE1% %FILE2% ^| more +1') DO SET NEWEST=%%i +if %NEWEST%==%FILE1% GOTO BUILD + +exit /b + +rem Check if second passed file is older compared to the first, and "touch" the file stamp of that file if yes +:CHECK_AND_TOUCH +SET FILE1=%1 +SET FILE2=%2 +for /F %%i IN ('dir /b /OD %FILE1% %FILE2% ^| more +1') DO SET NEWEST=%%i +if %NEWEST%==%FILE2% GOTO :CHECK_AND_TOUCH_END +Echo touching %2... +copy /b %2 +,, >NUL + +:CHECK_AND_TOUCH_END +exit /b -- 2.33.0.windows.1