One of the difficulties about working with 2 sets of code (6507 assembly and C) is there's some common info that both need to know. Manually maintaining that info in 2 places is error prone, so you want to limit that as much as possible. While developing Stay Frosty 2 I came up with the idea of having the 6507 assembly maintain that info, and output it for C via echo commands:
echo "#define SUB queue[",ARMsub,"]"echo "#define SWCHA queue[",ARMswcha,"]"echo "#define SWCHB queue[",ARMswchb,"]"echo "#define INPT1 queue[",ARMinpt1,"]" echo "#define INPT4 queue[",ARMinpt4,"]"echo "#define ElevatorHM26 ",ElevatorHM26echo "#define ElevatorHM31 ",ElevatorHM31
which dasm would output in the terminal:
#define SUB queue[ $0 ]#define SWCHA queue[ $1 ]#define SWCHB queue[ $2 ]#define INPT1 queue[ $3 ]#define INPT4 queue[ $4 ]#define ElevatorHM26 $f7d1#define ElevatorHM31 $f804
I would manually copy/paste that into a C header file, followed by an additional step to find/replace the $ with 0x as dasm and C use incompatible formats for representing hex values.
#define SUB queue[ 0x0 ]#define SWCHA queue[ 0x1 ]#define SWCHB queue[ 0x2 ]#define INPT1 queue[ 0x3 ]#define INPT4 queue[ 0x4 ]#define ElevatorHM26 0xf7d1#define ElevatorHM31 0xf804
Eventually I discovered that dasm could out values in decimal by wrapping the value in brackets followed by a d:
echo "#define SUB queue[", [ARMsub]d ,"]"echo "#define SWCHA queue[", [ARMswcha]d ,"]"echo "#define SWCHB queue[", [ARMswchb]d ,"]"echo "#define INPT1 queue[", [ARMinpt1]d ,"]" echo "#define INPT4 queue[", [ARMinpt4]d ,"]"echo "#define ElevatorHM26 ", [ElevatorHM26]decho "#define ElevatorHM31 ", [ElevatorHM31]d
which would output:
#define SUB queue[ 0 ]#define SWCHA queue[ 1 ]#define SWCHB queue[ 2 ]#define INPT1 queue[ 3 ]#define INPT4 queue[ 4 ]#define ElevatorHM26 63441#define ElevatorHM31 63492
Still had to copy/paste the values, but less work.
Then in 2016, while we were working on Bus Stuffing, cd-w came up with this:
dasm testrom1.asm -f3 -otestrom1.cu | awk '!x[$$0]++' | grep "#define" > $(BASE)/defines_dasm.h
It uses awk and grep to automatically capture the echoed out #defines and stash them in the header file for the C code. Awesome!
After implementing that in SpiceC I wondered if I could improve upon it as writing all those echo statements would be tedious. After reading up on awk and realizing it could process columns of data, I got to thinking that the symbol file dasm outputs was in columns:
--- Symbol List (sorted by symbol)0.FREE_BYTES 0000 1.CLEAR_STACK 7c02 (R )2.KernelSize 0100 (R )2.PageCount 0001 (R )2.Start 7c41 (R )AMPLITUDE 0022 ARMaudc0 000b ARMaudc1 000c ...VerticalBlank 7c2a (R )VerticalSync 7c19 (R )VSYNC 0000 (R )WSYNC 0002 (R )--- End of Symbol List.
If I could format the results I could use columns 1 and 2 to create the define file. One issue is the first and last line would be invalid, as would the symbols that started with numbers like 2.Start, so I'd also need to include some selection logic.
After some trial and error, and a bit of pondering, I came up with the following:
dasm ../../Include/main.asm -I$SPICEC_INCLUDE -f3 -v0 -s$PROJECT.sym -l$PROJECT.lst -o$PROJECT.binawk '$0 ~ /^__/ {printf "#define %-20s 0x%s\n", $1, $2}' $PROJECT.sym >> $DASM_TO_C
The dasm step does a normal compile and creates a symbol file. The awk step scans the symbol file for anything starting with __ and creates the define file for C. Given this:
--- Symbol List (sorted by symbol)0.FREE_BYTES 0000 1.CLEAR_STACK 7b02 (R )2.VBwait 7c02 (R )5.KernelSize 0015 (R )5.PageCount 0001 (R )5.ScoreLoop 7d0a (R )5.Start 7d00 (R )__ARMmode 0009 __AUDC0 000b __AUDC1 000c __AUDF0 000d __AUDF1 000e __AUDIO 0000 (R )__AUDIO_MUSIC 0001 (R )__AUDIO_SAMPLES 0002 __AUDIO_TIA_ONLY 0000 (R )__AUDV0 000f __AUDV1 0010 __COLUBK 0012 __COLUPF 0011 __DISPLAY_DATA_4_ARM 0013 __FRAME 000a __FUNC 0000 __INPT1 0005 __INPT3 0006 __INTP4 0003 __INTP5 0004 __OSTIME 0008 __RUN_GAME_OS 0004 __RUN_GAME_VB 0003 __RUN_INIT 0000 __RUN_INIT_LEVEL 0007 __RUN_MENU_OS 0002 __RUN_MENU_VB 0001 __RUN_SPLASH_OS 0006 __RUN_SPLASH_VB 0005 __SWCHA 0001 __SWCHB 0002 __VBTIME 0007 __WAVE_SIZE 0020 AMPLITUDE 0022 (R )ARM_CODE 0800 (R )ARM_CODE_SIZE 0fe1 (R )AUDC0 0015 AUDC1 0016 AUDF0 0017 ...VerticalBlank 7d3d (R )VerticalSync 7d20 VSYNC 0000 (R )WSYNC 0002 (R )--- End of Symbol List.
the resulting file contains:
#define __ARMmode 0x0009#define __AUDC0 0x000b#define __AUDC1 0x000c#define __AUDF0 0x000d#define __AUDF1 0x000e#define __AUDIO 0x0000#define __AUDIO_MUSIC 0x0001#define __AUDIO_SAMPLES 0x0002#define __AUDIO_TIA_ONLY 0x0000#define __AUDV0 0x000f#define __AUDV1 0x0010#define __COLUBK 0x0012#define __COLUPF 0x0011#define __DISPLAY_DATA_4_ARM 0x0013#define __FRAME 0x000a#define __FUNC 0x0000#define __INPT1 0x0005#define __INPT3 0x0006#define __INTP4 0x0003#define __INTP5 0x0004#define __OSTIME 0x0008#define __RUN_GAME_OS 0x0004#define __RUN_GAME_VB 0x0003#define __RUN_INIT 0x0000#define __RUN_INIT_LEVEL 0x0007#define __RUN_MENU_OS 0x0002#define __RUN_MENU_VB 0x0001#define __RUN_SPLASH_OS 0x0006#define __RUN_SPLASH_VB 0x0005#define __SWCHA 0x0001#define __SWCHB 0x0002#define __VBTIME 0x0007#define __WAVE_SIZE 0x0020
One of the benefits of using __ as a prefix is it lessens the chance of these defines conflicting with any end-user code.
-
5
3 Comments
Recommended Comments