Jump to content



1

usage of datatypes/structures in dasm possible?


6 replies to this topic

#1 roland p OFFLINE  

roland p

    Stargunner

  • 1,413 posts
  • RLA
  • Location:The Netherlands

Posted Sat May 23, 2009 4:52 AM

I wonder if it is possible to have something like datatypes in dasm. I'll illustrate my 'problem':

Right now, I've the following declaration for RAM usage:

Ship1Struct
PositionShip1X		.word
PositionShip1Z		.word
VelocityShip1X		.word
VelocityShip1Z		.word
DirectionShip1		.byte

Ship2Struct
PositionShip2X		.word
PositionShip2Z		.word
VelocityShip2X		.word
VelocityShip2Z		.word
DirectionShip2		.byte


I wonder if it would be possible to use something like:
Type ShipStruct
  PositionX			.word
  PositionZ			.word
  VelocityX			.word
  VelocityZ			.word
  Direction			.byte
End Type

Ship1Struct		.ShipStruct
Ship2Struct		.ShipStruct

Any ideas are welcome.

Edited by roland p, Sat May 23, 2009 4:55 AM.


#2 Andrew Davie OFFLINE  

Andrew Davie

    Stargunner

  • 1,314 posts
  • Location:Tasmania

Posted Sat May 23, 2009 5:14 AM

View Postroland p, on Sat May 23, 2009 8:52 PM, said:

Any ideas are welcome.


How about using a macro?


			MAC SHIP;  1st parameter the var name prefix
{1}_PositionX	.word
{1}_PositionZ	.word
{1}_VelocityX	.word
{1}_VelocityZ	.word
{1}_Direction	.byte
			ENDM


; declare the ships...
  SHIP Ship1
  SHIP Ship2

Then you'd access the vars as "Ship1_PositionX", etc. The above will work, barring any minor typos.
Having said that, I don't think this is a great way to define variables. I'd have each variable indexed by ship number. Where you have word variables, split into two with a low/high, or double the index before lookup.

Just for reference, macros can do interesting stuff... here's a few to browse through...

ROM_BANK_SIZE			   = $800



			MAC NEWBANK; bank name
				SEG {1}
				ORG ORIGIN
				RORG $F000
BANK_START	  SET *
{1}			 SET ORIGIN / 2048
ORIGIN		  SET ORIGIN + 2048
_CURRENT_BANK   SET {1}
			ENDM

			MAC DEFINE_1K_SEGMENT; {seg name}
				ALIGN $400
SEGMENT_{1}	 SET *
BANK_{1}		SET _CURRENT_BANK
			ENDM

			MAC CHECK_BANK_SIZE; name
.TEMP = * - BANK_START
	ECHO {1}, "(2K) SIZE = ", .TEMP, ", FREE=", ROM_BANK_SIZE - .TEMP
#if ( .TEMP ) > ROM_BANK_SIZE
	ECHO "BANK OVERFLOW @ ", * - ORIGIN
	ERR
#endif
			ENDM


			MAC CHECK_HALF_BANK_SIZE; name
  ; This macro is for checking the first 1K of ROM bank data that is to be copied to RAM.
  ; Note that these ROM banks can contain 2K, so this macro will generally go 'halfway'
.TEMP = * - BANK_START
	ECHO {1}, "(1K) SIZE = ", .TEMP, ", FREE=", ROM_BANK_SIZE/2 - .TEMP
#if ( .TEMP ) > ROM_BANK_SIZE/2
	ECHO "BANK OVERFLOW @ ", * - ORIGIN
	ERR
#endif
			ENDM

			MAC OVERLAY; {name}
	SEG.U OVERLAY_{1}
	org Overlay
			ENDM

  ;--------------------------------------------------------------------------

	MAC VALIDATE_OVERLAY
		LIST OFF
		#if * - Overlay > OVERLAY_SIZE
			ERR
		#endif
		LIST ON
	ENDM

  ;--------------------------------------------------------------------------
  ; Macro inserts a page break if the object would overlap a page

	MAC OPTIONAL_PAGEBREAK; { string, size }
		LIST OFF
		IF (>( * + {2} -1 )) > ( >* )
EARLY_LOCATION  SET *
			ALIGN 256
			ECHO "PAGE BREAK INSERTED FOR ", {1}
			ECHO "REQUESTED SIZE = ", {2}
			ECHO "WASTED SPACE = ", *-EARLY_LOCATION
			ECHO "PAGEBREAK LOCATION = ", *
		ENDIF
		LIST ON
	ENDM


	MAC CHECK_PAGE_CROSSING
		LIST OFF
#if ( >BLOCK_END != >BLOCK_START )
	ECHO "PAGE CROSSING @ ", BLOCK_START
#endif
		LIST ON
	ENDM
	MAC CHECKPAGE
	LIST OFF
		IF >. != >{1}
			ECHO ""
			ECHO "ERROR: different pages! (", {1}, ",", ., ")"
			ECHO ""
		ERR
		ENDIF
		LIST ON
	ENDM

	MAC CHECKPAGE_BNE
		LIST OFF
		IF 0;>(. + 2) != >{1}
			ECHO ""
			ECHO "ERROR: different pages! (", {1}, ",", ., ")"
			ECHO ""
			ERR
		ENDIF
		LIST ON
			bne	 {1}
	ENDM

	MAC CHECKPAGE_BPL
		LIST OFF
		IF (>(.+2 )) != >{1}
			ECHO ""
			ECHO "ERROR: different pages! (", {1}, ",", ., ")"
			ECHO ""
			ERR
		ENDIF
		LIST ON
			bpl	 {1}
	ENDM


IDENTITY	SET 0
	MAC IDENT; {object}
#if DEBUG=YES
		lda #IDENTITY
		sta debug_ident
		lda {1}
		sta debug_object
#endif
IDENTITY	SET IDENTITY + 1
	ENDM


Cheers
A

#3 roland p OFFLINE  

roland p

    Stargunner

  • 1,413 posts
  • RLA
  • Location:The Netherlands

Posted Sat May 23, 2009 5:48 AM

View PostAndrew Davie, on Sat May 23, 2009 1:14 PM, said:

Then you'd access the vars as "Ship1_PositionX", etc. The above will work, barring any minor typos.
Having said that, I don't think this is a great way to define variables. I'd have each variable indexed by ship number. Where you have word variables, split into two with a low/high, or double the index before lookup.

Thanks,
I didn't know that labels can be generated too.
I have to agree that indexing looks cleaner than the macro. Actually accessing the data through indexing will be easier too.

#4 selgus OFFLINE  

selgus

    Moonsweeper

  • 293 posts
  • Location:Orlando, Florida

Posted Sat May 23, 2009 6:08 AM

Here is how I do data structures in my engine:
; -------------------------------------------------------------------------------------------
; STRUCTURE BUILDING MACROS
;
 
; -------------------------------------------------------------------------------------------
; Function:	vcs_CORE_STRUCT
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; Purpose:		Define the start of a structure
; Parameters:
;		_offset		=	Initial offset for the structure
; Inputs:	   None
; Returns:	  None
;
		 mac vcs_CORE_STRUCT; _offset
 __struct_offset	set {1}
 __struct_base	set {1}
		 endm
 
; -------------------------------------------------------------------------------------------
; Function:	vcs_CORE_LABEL
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; Purpose:		Define a label inside of a structure
; Parameters:
;		_name		=	Name of the label to define
; Inputs:	   None
; Returns:	  None
;
		 mac vcs_CORE_LABEL; _name
 {1}			equ __struct_offset
		 endm
 
; -------------------------------------------------------------------------------------------
; Function:	vcs_CORE_ENUM
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; Purpose:		Define an enumerated label inside of a structure
; Parameters:
;		_name		=	Name of the label to define
; Inputs:	   None
; Returns:	  None
;
		 mac vcs_CORE_ENUM; _name
 {1}				equ __struct_offset
 __struct_offset	set __struct_offset+1
		 endm
 
; -------------------------------------------------------------------------------------------
; Function:	vcs_CORE_BYTE
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; Purpose:		Define an 8-bit structure value
; Parameters:
;		_name		=	Name of the label to define
; Inputs:	   None
; Returns:	  None
;
		 mac vcs_BYTE; _name
 {1}				equ __struct_offset
 __struct_offset	set __struct_offset+1
		 endm
 
; -------------------------------------------------------------------------------------------
; Function:	vcs_CORE_WORD
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; Purpose:		Define a 16-bit structure value
; Parameters:
;		_name		=	Name of the label to define
; Inputs:	   None
; Returns:	  None
;
		 mac vcs_WORD; _name
 {1}				equ __struct_offset
 __struct_offset	set __struct_offset+2
		 endm
 
; -------------------------------------------------------------------------------------------
; Function:	vcs_CORE_ARRAY
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; Purpose:		Define an array embedded inside of a structure
; Parameters:
;		_name		=	Name of the array to define
;		_size		=	Size of the array
; Inputs:	   None
; Returns:	  None
;
		 mac vcs_CORE_ARRAY; _name, _size
 {1}				equ __struct_offset
 __struct_offset	set __struct_offset+_size
		 endm
 
; -------------------------------------------------------------------------------------------
; Function:	vcs_CORE_END
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; Purpose:		Define the end of a structure
; Parameters:
;		_prefix		=	Prefix name of the finishing structure
; Inputs:	   None
; Returns:	  None
;
		 mac vcs_CORE_END; _prefix
 {1}_SIZEOF	equ __struct_offset
 {1}_END		equ __struct_offset-__struct_base
		 endm
 
; -------------------------------------------------------------------------------------------
; Function:	vcs_CORE_BITDEF
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; Purpose:		Define a bit definition and mask
; Parameters:
;		_prefix		=	Prefix name for the bit definition
;		_name		=	Name of the bit definition
;		_bit		=	Starting bit number
;		_mask		=	Bit mask
; Inputs:	   None
; Returns:	  None
;
		 mac vcs_CORE_BITDEF; _prefix, _name, _bit, _mask
 {1}B_{2}	equ {3}
 {1}F_{2}	equ {4}<<{3}
		 endm
--Selgus

#5 roland p OFFLINE  

roland p

    Stargunner

  • 1,413 posts
  • RLA
  • Location:The Netherlands

Posted Mon May 25, 2009 7:58 AM

I've decided to keep the declaration as it is. I think constructing the variable names is a case of bad practise, at least from my point of view.

But the previous posts gave me the idea to change my macros, and only pass the ship number when you call them. The macro will then reconstuct the variables (like: LDA position{1}X). This will make my macro calling routines much cleaner which was my main goal.


View Postselgus, on Sat May 23, 2009 2:08 PM, said:

Here is how I do data structures in my engine:

What's the benefits of of your macros compared to using the ORG functionality and the DS,byte,word keywords?

#6 selgus OFFLINE  

selgus

    Moonsweeper

  • 293 posts
  • Location:Orlando, Florida

Posted Mon May 25, 2009 8:14 AM

View Postroland p, on Mon May 25, 2009 9:58 AM, said:

What's the benefits of of your macros compared to using the ORG functionality and the DS,byte,word keywords?
I try not to make my source code dependent on any one assembler.

I have done this in engines for all different platforms/assemblers so that I can have a consistent way of defining structures, format them like you would in a higher-level language, allow for readability, etc. Plus I have additional macros that allow me to allow negative offsets when you set an indirect register addressing (like on the 68k).
--Selgus

#7 roland p OFFLINE  

roland p

    Stargunner

  • 1,413 posts
  • RLA
  • Location:The Netherlands

Posted Wed May 27, 2009 4:22 AM

The refactoring of my code is getting along nicely.

The structure of my variables looks now like:

;ships data
SHIP1_POS_X
SHIP1_POS_Z
SHIP1_VEL_X
SHIP1_VEL_Y
SHIP1_DIR

SHIP2_POS_X
SHIP2_POS_Z
SHIP2_VEL_X
SHIP2_VEL_Y
SHIP2_DIR

;playfield data (for drawing playfield)
PLAYFIELD1_GRP0_PTR
PLAYFIELD1_GRP1_PTR
etc.

PLAYFIELD2_GRP0_PTR
PLAYFIELD2_GRP1_PTR
etc.

I can now call my macros like:
CALC_SPRITE SHIP2, PLAYFIELD1   ;ship2 is shown in the upper playfield
CALC_SPRITE SHIP1, PLAYFIELD2   ;ship1 is shown in the lower playfield

I looks now how it whould look like if you where having types.

The downside of this is that the macro's generate unrolled code, maybe I should index the variables like an array, like Andrew said, but the macros can get pretty complex. I don't know what the best way is.




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users