How to resolve the algorithm Yin and yang step by step in the 68000 Assembly programming language

Published on 12 May 2024 09:40 PM

How to resolve the algorithm Yin and yang step by step in the 68000 Assembly programming language

Table of Contents

Problem Statement

One well-known symbol of the philosophy of duality known as yin and yang is the taijitu.

Let's start with the solution:

Step by Step solution about How to resolve the algorithm Yin and yang step by step in the 68000 Assembly programming language

Source code in the 68000 programming language

	pushall
		MOVE.W #1,D0		
		;base sprite number, needed by NEOGEO hardware
		;the yin-yang is 8 sprites total, it is important that
		;two different sprite objects do not overlap!

		MOVE.W #$F800,D4	;x position on screen
		MOVE.W #$1000,D5	;y position on screen
		MOVE.W #$0777,D7	;size parameter
		JSR generateOAM
	popall
	
	pushall
		MOVE.W #$10,D0
		;base sprite number, needed by NEOGEO hardware
		MOVE.W #$F800,D4	;x position on screen
		MOVE.W #$6000,D5	;y position on screen
		MOVE.W #$0444,D7	;size parameter
		JSR generateOAM
	popall
	
forever:
	bra forever				;trap the program counter
	
generateOAM:
        ;this is just boilerplate required to show hardware sprites to the screen, it's not really relevant to the task.
        ;   all this does is copy the sprite data to video memory.

	;INPUT:         D0 = SPRITENUM.
	;		D4 = Y POS
	;		D5 = X POS
	;		D7 = SHRINK FACTOR (SIZE PARAMETER)
        ;               THESE VALUES ARE PASSED IN USING THE ABOVE REGISTERS
	pushWord D0
		ADD.W #$8000,D0		        ;VRAM OFFSET FOR SPRITE 1
		LEA YinYang_Data,A0             ;LOAD ADDRESS OF SPRITE METADATA 
		MOVE.B (A0)+,D2			;SPRITE WIDTH - 8 SPRITES PER OBJECT 
                                                ;    (A NEOGEO SPRITE IS ALWAYS 1 TILE WIDE BUT CAN BE OF ARBITRARY HEIGHT)

		MOVE.B (A0)+,D3			;SPRITE HEIGHT - 8 TILES PER SPRITE
		AND.W #$00FF,D3			;BYTE SANITIZE SPRITE HEIGHT

		MOVE.W #$0200,$3C0004
		;INCREMENT THE VALUE IN $3C0000 BY $200 AFTER EACH WRITE TO 
		;	$3C0002	

		
		MOVE.W D0,$3C0000		;SET DESTINATION ADDRESS OF SIZE PARAMETER
		MOVE.W D7,$3C0002		;WRITE SIZE PARAMETER TO VRAM
		
		;AUTO INCS TO $8201 WHICH IS WHERE Y POS MUST BE STORED.
		
		MOVE.W D4,D1			;GET Y POS
		OR.W D3,D1		        ;COMBINE WITH SPRITE HEIGHT,SINCE NEOGEO STORES THEM TOGETHER AS ONE UNIT.
		MOVE.W D1,$3C0002		;STORE IN VRAM
		
		;AUTO INCS TO $8401 WHICH IS WHERE X POS MUST BE STORED.
		
		MOVE.W D5,D1			;GET X POS
		MOVE.W D1,$3C0002		;STORE IN VRAM
		
		CMP.B #1,D2                     ;IS THIS SPRITE EXACTLY ONE TILE WIDE?
		BEQ skipChainedOAM		;A 1-WIDE SPRITE NEEDS NO CHAINED SPRITES.
                                                ;    IN THIS EXAMPLE THE YIN-YANGS ARE 8 TILES WIDE, THIS BRANCH IS NEVER TAKEN.
	
		pushWord D2
			SUBQ.B #2,D2		;WE NEED TO LOOP (SPRITE_WIDTH-2) TIMES.


loop_generateChainedOAM:
			ADDQ.W #1,D0			;NEXT SPRITE
			MOVE.W D0,$3C0000		;SET VRAM DESTINATION.
			MOVE.W D7,$3C0002		;EACH STRIP HAS ITS OWN SHRINK VALUE.
			MOVE.W #$0040,$3C0002	        ;MARK THIS SPRITE AS CHAINED. CHAINED SPRITES MOVE AND SCALE AS ONE UNIT.
			MOVE.W #$0000,$3C0002	        ;DUMMY MOVE FOR PADDING.
			DBRA D2,loop_generateChainedOAM
		popWord D2
	
skipChainedOAM:
;NOW DO TILE DATA:
		MOVE.W #1,$3C0004	;SET VRAM INC TO 1.
		SUBQ.B #1,D2
		SUBQ.B #1,D3		;DBRA CORRECTION
	popWord D0	
	
	MOVE.W D0,D1
	LSL.W #6,D1			;TILE/PAL OFFSET IS SPRITENUM<<6
	
	LEA YinYang_Tile,A0		;LOAD ADDRESS OF SOURCE DATA
	LEA YinYang_Pal,A1		;LOAD ADDRESS OF SOURCE DATA
	
	MOVE.W D3,D6			
	;BACKUP D3, IT WILL GET RESTORED AT THE OUTER LOOP
		
loop_sprite_OAM:
	MOVE.W D1,$3C0000		;SET VRAM ADDRESS
loop_tile_OAM:
	MOVE.W (A0)+,$3C0002		;SET TILE DATA
	MOVE.W (A1)+,$3C0002		;SET PAL DATA
	DBRA D3,loop_tile_OAM		;NEXT TILE IN STRIP
	
	MOVE.W D6,D3			;RESTORE D3
	ADD.W #$0040,D1			;NEXT SPRITE
	DBRA D2,loop_sprite_OAM		;REPEAT UNTIL ALL SPRITES FINISHED.
	
	RTS
	
YinYang_Data:
	DC.B 8,8		;SPRITE WIDTH,SPRITE HEIGHT

YinYang_Tile:	;EACH NUMBER REPRESENTS A TILE IN THE CHARACTER ROM
                ;THESE VALUES ARE ARBITRARY AND WILL DIFFER DEPENDING ON HOW THE YIN-YANG PIXEL ART IS STORED IN YOUR CARTRIDGE.
	DC.W $0060,$0068,$0070,$0078,$0080,$0088,$0090,$0098
	DC.W $0061,$0069,$0071,$0079,$0081,$0089,$0091,$0099
	DC.W $0062,$006A,$0072,$007A,$0082,$008A,$0092,$009A
	DC.W $0063,$006B,$0073,$007B,$0083,$008B,$0093,$009B
	DC.W $0064,$006C,$0074,$007C,$0084,$008C,$0094,$009C
	DC.W $0065,$006D,$0075,$007D,$0085,$008D,$0095,$009D
	DC.W $0066,$006E,$0076,$007E,$0086,$008E,$0096,$009E
	DC.W $0067,$006F,$0077,$007F,$0087,$008F,$0097,$009F
YinYang_Pal:	;$0100 = USE PALETTE 1.
	DC.W $0100,$0100,$0100,$0100,$0100,$0100,$0100,$0100
	DC.W $0100,$0100,$0100,$0100,$0100,$0100,$0100,$0100
	DC.W $0100,$0100,$0100,$0100,$0100,$0100,$0100,$0100
	DC.W $0100,$0100,$0100,$0100,$0100,$0100,$0100,$0100
	DC.W $0100,$0100,$0100,$0100,$0100,$0100,$0100,$0100
	DC.W $0100,$0100,$0100,$0100,$0100,$0100,$0100,$0100
	DC.W $0100,$0100,$0100,$0100,$0100,$0100,$0100,$0100
	DC.W $0100,$0100,$0100,$0100,$0100,$0100,$0100,$0100

  

You may also check:How to resolve the algorithm Loops/Foreach step by step in the Ruby programming language
You may also check:How to resolve the algorithm Monads/Writer monad step by step in the zkl programming language
You may also check:How to resolve the algorithm Window creation step by step in the Java programming language
You may also check:How to resolve the algorithm Terminal control/Clear the screen step by step in the AutoHotkey programming language
You may also check:How to resolve the algorithm Hello world/Newbie step by step in the Eiffel programming language