Sonic and Sega Retro Message Board: Help request: C-Programmer to add new function to WLA DX - Sonic and Sega Retro Message Board

Jump to content

Hey there, Guest!  (Log In · Register) Help
Page 1 of 1
    Locked
    Locked Forum

Help request: C-Programmer to add new function to WLA DX to help with Sonic 1 Master System disassembly

#1 User is offline Kroc 

  Posted 06 December 2013 - 10:08 AM

  • Code is Art
  • Posts: 37
  • Joined: 27-May 13
  • Gender:Not Telling
  • Project:MaSS1VE: The Master System Sonic 1 Visual Editor
Hello.
I am working on a complete disassembly of Sonic 1 Master System for the purposes of a full editing suite for the game.

I am working toward porting the ROM from 256K to 512K. This requires properly labelling and structuring the disassembly so that the code and data is portable and can be moved around the different banks.

I am using WLA DX and whilst it is an excellent tool for the job I am coming across instances of code and data that are not simple enough to make portable.

I would like to ask for the help of a C-programmer to add some new functions to WLA DX in order to solve some portability problems in the code.

Here's my first proposal for a new function:

".TABLE": Portable indexes

Here's a real-world problem I want to solve: making index numbers used in data, portable. In Sonic 1 SMS each level has a list of which objects (enemies, powerups &c.) appear where in the level. In the ROM a pointer table provides which object index number runs which code. This style of index-based functionality is very common, I imagine in most other games too.

How can we add to / remove from / rearrange the object code and function pointer list in the game without making all the level data invalid; pointing to the wrong objects? The current situation is that nobody bothers and just works around the ugly picture. The lists are included as binary and the pointer tables are only appended to. This is not flexible enough for me, especially if I want to head toward providing an editing suite with total-conversion capabilities.

My proposal is a new declaration for WLA DX: ".TABLE".

First you define the 'columns' of your table using a standard .STRUCT definition.

.STRUCT pointerList
    address: dw
.ENDST


Here's where the magic happens. Each row has it's own label, this label does not point to the output address of that data, but instead provides the index number of the row. I.e. 'badnick_motobug` = 2

.TABLE objectPointers INSTANCEOF pointerList
    .ROW badnick_crabmeat DATA $1234
    .ROW badnick_chopper  DATA $5678
    .ROW badnick_motobug  DATA $9ABC
    [...]
.ENDT


Now in your data statements you can refer to these labels rather than hard values

;list of objects in the level: (object ID, X, Y)
.db badnick_chopper, $20, $20
.db monitor_ring, $43, $12
[...]


.TABLE is also excellent for data that combines different data types (bytes, words, strings &c.). Currently in WLA DX this quite painful, e.g.

.db $FF
.dw $1234
.db $80
[...repeat 100 times...]


Doing this with .TABLE will be far more elegant and flexible:

.STRUCT hypotheticalTableDef
    first: db
    second: dw
    third: db
.ENDST

.TABLE hypotheticalTable INSTANCEOF hypotheticalTableDef
.ROW DATA $FF, $1234, $80
.ROW DATA $11, $5678, $A0
[...]
.ENDT


.TABLE would also define `_sizeof_[table name]` which will give how many rows are in the table -- perfect for initialising your loop in a flexible, portable way!




I also have a proposal for a block form of .DSTRUCT that will help with self-documentation, but I will post details of this soon.

Is there any one out there that would be willing to volunteer their efforts to help?

#2 User is offline MainMemory 

Posted 06 December 2013 - 10:50 AM

  • Every day's the same old thing... Same place, different day...
  • Posts: 3369
  • Joined: 14-August 09
  • Gender:Not Telling
  • Project:SonLVL
  • Wiki edits:1,339
I don't know about WLA DX, but in AS your problem could be solved with macros.

#3 User is offline Kroc 

Posted 06 December 2013 - 11:16 AM

  • Code is Art
  • Posts: 37
  • Joined: 27-May 13
  • Gender:Not Telling
  • Project:MaSS1VE: The Master System Sonic 1 Visual Editor
I must admit that I am new to WLA DX, since I am likewise new to Z80 which I have taken to learning for the purpose of this project. I've read over the WLA DX documentation several times and I am not aware of a way that I could replicate the desired functionality _elegantly_. If someone can show me otherwise, I'd be glad as it would mean less work for everybody involved.

#4 User is offline Glitch 

Posted 06 December 2013 - 02:43 PM

  • Posts: 157
  • Joined: 22-September 08
  • Gender:Male
  • Project:Sonic 2 LD
  • Wiki edits:22
Something like this should work:

    .ORG $200

    .MEMORYMAP
        SLOTSIZE    $4000
        SLOT        0 $0000
        SLOT        1 $4000
        SLOT        2 $8000
        DEFAULTSLOT 0
    .ENDME

    .ROMBANKMAP
        BANKSTOTAL  16
        BANKSIZE    $4000
        BANKS       16
    .ENDRO

    .MACRO def_object ARGS obj_name, logic_ptr
    _def_object_\@:
        .dw \2
        .def \1 (_def_object_\@ - OBJ_TABLE_START)/2
        .export \1
    .ENDM

    OBJ_TABLE_START:
        def_object  object1, object1_handler
        def_object  object2, object2_handler
        def_object  object3, object3_handler


    object1_handler:
        ld a, object1
        ret

    object2_handler:
        ld a, object2
        ret

    object3_handler:
        ld a, object3
        ret




Which generates the following symbols:

    0000:0000 object1
    0000:0001 object2
    0000:0002 object3
    0000:0200 OBJ_TABLE_START
    0000:0200 _def_object_0
    0000:0202 _def_object_1
    0000:0204 _def_object_2
    0000:0206 object1_handler
    0000:0209 object2_handler
    0000:020c object3_handler




#5 User is offline Kroc 

Posted 07 December 2013 - 09:38 AM

  • Code is Art
  • Posts: 37
  • Joined: 27-May 13
  • Gender:Not Telling
  • Project:MaSS1VE: The Master System Sonic 1 Visual Editor
That'll work, but it won't suit my needs:

* It requires a macro for each instance of a table rather than for each definition

* It doesn't define _sizeof_tablename automatically, that would have to be maintained manually which I'm looking to avoid

* It's less readable, less intuitive and would make the source more difficult to learn. It's really important to me to maximise accessibility. I would want anybody like myself who was interested and was learning Z80 to have an easy to understand and descriptive piece of code

#6 User is offline Kroc 

Posted 09 December 2013 - 03:25 AM

  • Code is Art
  • Posts: 37
  • Joined: 27-May 13
  • Gender:Not Telling
  • Project:MaSS1VE: The Master System Sonic 1 Visual Editor
I'm trying to solve the sizeof problem with macros, but I can't see a way in WLADX to reference the name of one variable using another. I.e.

.MACRO TABLE ARGS tableName
	;define the current position as the table name
__TABLE\@__:
	.DEF \1 __TABLE\@__
	;then define a reference used for counting the row index
	.REDEF __TABLE_size__ 0
	;define the size of the table
	 ;we need to increase this with each 'ROW` macro
	.DEF _sizeof_\1 0
.ENDM

.MACRO ROW ARGS rowIndexLabel
__ROW\@__:
	.IFDEFM \1
		.DEF \1 __TABLE_size__
	.ENDIF
	;increase the index number
	.REDEF __TABLE_size__ (__TABLE_size__+1)
	;how do we increase '_sizeof_[tableName]` without
	 ;having the table name as an argument?
.ENDM


It could be possible by having an 'ENDT` macro using the table name, but I'd rather avoid having to give the tablename twice, the reason why I'd prefer changes to WLA DX rather than using macros alone.
This post has been edited by Kroc: 09 December 2013 - 05:35 AM

#7 User is offline MainMemory 

Posted 09 December 2013 - 10:37 AM

  • Every day's the same old thing... Same place, different day...
  • Posts: 3369
  • Joined: 14-August 09
  • Gender:Not Telling
  • Project:SonLVL
  • Wiki edits:1,339
Rather than trying to find someone willing and able to rewrite parts of WLA DX, you could try using AS, which already allows you to construct symbol names using other symbols.

#8 User is offline Kroc 

Posted 09 December 2013 - 10:38 AM

  • Code is Art
  • Posts: 37
  • Joined: 27-May 13
  • Gender:Not Telling
  • Project:MaSS1VE: The Master System Sonic 1 Visual Editor
Stupid question, but what's AS?

#9 User is offline flamewing 

Posted 09 December 2013 - 12:58 PM

  • Emerald Hunter
  • Posts: 831
  • Joined: 11-October 10
  • Gender:Male
  • Location:Brasil
  • Project:Sonic Classic Heroes; Sonic 2 Special Stage Editor; Sonic 3&K Heroes (on hold)
  • Wiki edits:12
AS is the macro assembler (here). It is a multiprocessor assembler which is used in the S2 and S3&K disassemblies because it can assemble their z80 sound drivers alongside their m68k main code.

#10 User is offline Kroc 

Posted 13 December 2013 - 02:25 AM

  • Code is Art
  • Posts: 37
  • Joined: 27-May 13
  • Gender:Not Telling
  • Project:MaSS1VE: The Master System Sonic 1 Visual Editor
Thank you for pointing me to that @flamewing. I've discovered many more bugs and limitations of WLA DX that I don't think would be solvable any time soon and whilst AS is nice I feel it suffers from the same design problems with WLA DX that I'm looking to overcome.

To that end I'm formulating a spec for a new ASM script language, here's a very rough draft to show what I'm getting at:
https://gist.github.com/Kroc/7940880

#11 User is offline MainMemory 

Posted 13 December 2013 - 10:41 AM

  • Every day's the same old thing... Same place, different day...
  • Posts: 3369
  • Joined: 14-August 09
  • Gender:Not Telling
  • Project:SonLVL
  • Wiki edits:1,339
Writing an assembler is hard work that not everyone can do, and those who can only will if they feel that the current assemblers are lacking features or have bugs that they cannot work around. Then if you add to that most people are only interested in the Mega Drive games, the number of people willing to do this becomes even smaller.

I will say though that FraGag is currently working on a new assembler architecture, and given that the MD has a Z80 processor, he'll probably add support for it eventually. Current estimations put the first release sometime within the next century. :v:/>

It is probably possible to get all of the functionality you want with some sort of macros, but I don't know anything about SMS or Z80 so I won't be much help unfortunately.

Edit: If you want a type of table that automatically assigns IDs, you could have a macro at the start of the table that sets a variable to 0, then each entry is a macro either with a label that becomes the ID constant on the line or a string parameter that names the ID constant, and all the data for the structure. The macro sets the ID constant to the current value of the counter variable, then increases the variable by 1.
This post has been edited by MainMemory: 13 December 2013 - 10:57 AM

#12 User is offline Dr. Kylstein 

Posted 13 December 2013 - 06:46 PM

  • Posts: 84
  • Joined: 05-June 08
  • Gender:Not Telling
Perhaps a pre-processor is in order? I remember reading about somebody piping their assembly through gpp (GNU C PreProcessor) to handle a problem like this. Or you might have an easier time finding a Python [or Perl, or whatever] programmer to make a custom pre-processor than a C programmer willing to create/hack an assembler.
This post has been edited by Dr. Kylstein: 13 December 2013 - 06:49 PM

#13 User is offline Kroc 

Posted 13 December 2013 - 10:21 PM

  • Code is Art
  • Posts: 37
  • Joined: 27-May 13
  • Gender:Not Telling
  • Project:MaSS1VE: The Master System Sonic 1 Visual Editor

Quote

Perhaps a pre-processor is in order?


There are limitations in WLA DX that would prevent that from solving some problems -- I'll just copy in the reply I made on the SMSPower thread where this is also being discussed.




I'll give you an example where WLA DX is slipping up and where a preprocessor really won't help --

I need to calculate offsets from the start of a bank to the data, but in a portable way since I will be providing 256K and 512K ROM layouts.

You can't calculate using a bank number, nor can you pass it as a macro parameter.

_label:
.PRINTV HEX :_label ;this does not work


A preprocessor cannot solve this as it cannot tell what bank a symbol may lie in.

Here's another example of something that really badly needs fixing:

Bank boundaries are a pain to manage. For example, the block mappings in Sonic 1 extend from $10'000 to $15'580, across the bank boundary at $14'000. If I (or anybody) wants to modify that data, they have to manually move the .BANK statement precisely byte-for-byte.

I propose the ability to allow data to not overflow bank boundaries when specified in this manner:

.BANK 3, 4 ;or, also like
.BANK 0-2


This way I can have data that crosses the bank boundary without having to manage the exact byte split.




Quote

It is probably possible to get all of the functionality you want with some sort of macros


Yes, and also no-no-no :) I've got some macros that largely implement the table syntax, but I'm running up against WLA DX bugs and outright holes in functionality that cannot be macro'd or preprocessored around.

I appreciate all the words and feedback. I'm rolling everything around in my head and working out the best strategy.

Page 1 of 1
    Locked
    Locked Forum

1 User(s) are reading this topic
0 members, 1 guests, 0 anonymous users