Sonic and Sega Retro Message Board: Super Egg - Viewing Profile - Sonic and Sega Retro Message Board

Jump to content

Hey there, Guest!  (Log In · Register) Help

Group:
Member: Members
Active Posts:
163 (0.09 per day)
Most Active In:
Engineering & Reverse Engineering (38 posts)
Joined:
01-July 10
Profile Views:
4774
Last Active:
User is offline Yesterday, 09:21 PM
Currently:
Offline

My Information

Member Title:
Master of MS Paint.
Age:
21 years old
Birthday:
September 10, 1993
Gender:
Male Male
Location:
Tomball, TEXAS

Contact Information

E-mail:
Private
Website:
Website  http://
Yahoo:
Yahoo  filbily

Previous Fields

Project:
Sonic 2 beta 3 hoax, SONIC X ABRIDGED BITCH!!!
National Flag:
us
Wiki edits:
46
SA2 Emblems:
8

Latest Visitors

Topics I've Started

  1. Sega Homebrew Competition 2015

    23 January 2015 - 11:06 PM

    Howdy Folks, this is SuperEgg, Judge #4 and Media Manager for the Sonic Hacking Contest.

    For years, the staff has been trying to find a meaningful and great way to include homebrew into the contest. Unfortunately, an answer for integrating homebrew into the contest just wasn't meant to be. There's just far too many issues to contend with to be able to shoehorn homebrew into the contest, and we didn't want to turn the contest into another SAGE by just letting in everything. But, we've also had to come to terms with trying to lump together homebrewers with guys who just make fan games is completely unfair and an utter disrespect towards these hardworking individuals and their work. Homebrewers have to ensure their games work with console systems, and as such, it is unfair to pit them against people who can just use C, C++, Game Maker, Multimedia Flash, etc. to make games and not have to worry about the limitations of home consoles.

    In order to keep the Sonic Hacking Contest in line with what it says on print, "Sonic Hacking", and to ensure we respect these individuals, we've come up with a much better solution, the Sega Homebrew Competition!

    "What is the Sega Homebrew Competition, SuperEgg?"

    I'm so glad you asked Matt, sit down in that computer chair and I'll tell you, you little idiot.

    The Sega Homebrew Competition is a week long celebration and competition to showcase and promote users who work with making games outside of the Sonic Series as well as provide a laid-back competitive venue.

    The qualifications are simple.

    1. The entry must be written and built to run on a relatively unmodified Sega console. No ridiculous hardware mods that extend native capabilities, please. That's just ruining the spirit of the competition.
    2. The judges must be able to run the entry. If special conditions are needed to run it, contact the judging staff, and we'll see if we can work something out.

    There you have it folks, that's the only real qualifications we have. Homebrew entries do not have to be Sonic related or even Sonic themed, though a few wouldn't hurt due to it's joint function with the SHC, it isn't even necessary and isn't even being asked. We want people from all walks of Sega life to come together and have a good time. Sonic is great, but there is so much more to SEGA and it's time that we see what all of you are capable of.

    "Wow, I'm excited DuperSegg, but how does the Competition work?"

    This time Josh, you have an excellent question, sit back down and I'll tell you.

    For starters, entries will be set up in a similar manner to the Sonic Hacking Contest. There will be public entries, entries where the general public can play them, and Partial Private entries, entries where the contestant has opted to allow public access to their creation, but is willing to showcase their work via various media outlets.

    Importantly, Entrants who opt to submit their hack under Partial Private must provide at least one video. Showing only still screenshots to the general public is just counterintuitive and not to mention incapable of showcasing your work.

    For the contest, we have three main categories: Music, Art, and general game flow.

    Music- Which homebrew game has the best soundtrack overall. Originally, this was going to be just one song, but the amount of people who can make at least one good song for a game on any of the listed hardware is a bit....easy. We have decided to change this up slightly to make it fair amongst the competitors, and to make our jobs easier.

    Art- Which homebrew game has the best game art overall. In this case, one level can be considered enough.

    Flow- Well, this is a weirdly titled category, ain't it? Trust me, it sounds weird, but flow in a game is important. After years of playing bad Sonic hacks, one of the biggest things that stick out is that the game doesn't flow, or it isn't natural. When you go and play a game and you fall in love with it, art and music are important factors, but the biggest is how fluid the game is. If the game is a bothersome and tiring exercise, why would you bother playing it? Remember, these entries must not only look and sound nice, but they must play nice. In this case, the console is irrelevant, we want to play a game that will begging us for more.

    Now that we have the categories outta the way, it's time to discuss how the contest works.

    For each of the three categories, we have a completely different system.

    Each judge will pick the piece of work as our "Best in _" per category. From there, the final entries chosen for that category are then reviewed by all the judges, then the official "Best in _" for said category.

    Example:
    Judge 1: TomasJester's Steak Adventure (Game Gear)
    Judge 2: DrupaSage's Country Music Race (Saturn)
    Judge 3: SawnukBam's Tetrsex Party (MD/CD)

    Overall Best in Music: DrupaSage's Country Music Race (Saturn)

    Now, why is this kind of system being used in comparison to something more like the Sonic Hacking Contest's trophies?

    Put simply, this competition is meant to be far more laid-back than the Sonic Hacking Contest. We're not here to rigidly compare and pit such a large palette of designs and approaches against each other. We want to provide a platform for homebrew so that, rather than being relegated to dark corners of the Internet, these projects are noticed by larger audiences. In addition, unlike the Sonic Hacking Contest, judging should be quicker.

    There you have it folks, the Sega Homebrew Competition...

    "Wait, wait, wait, who are going to be the judges, besides you?"

    Thanks for interrupting me Donnie, I was about to get to that.

    For now, the official judges for the contest are myself (SuperEgg), and LazloPsylus. We are still scouting for more judges. Stay tuned. And before anybody asks, no, I am not holding tryouts for judges. The magnitude and scale of this contest is one that is unlike any I've seen. We are currently screening for judges to ensure we pick people who are not only qualified, but are also unbiased and are open-minded to things beyond Sonic.

    The deadline for the contest is Sunday, August 2nd (though there will be a grace period until August 9th to provide updates to entries), and will share the Sonic Hacking Contest's Contest Week: Monday, August 24th to Sunday, August 29th. The Sonic Hacking Contest Media Panel will also be covering this competition, so stay tuned.

    All in all, let's get to work people. I want everybody to show the internet gaming culture that Sega truly does what Nintendon't.
  2. Hacking with the Microsoft Surface

    14 June 2014 - 10:36 AM

    So, my main rig, an HP Pavillion dv4, has basically kicked the bucket. It seems that HP was high as a god damned kite when designing it, and decided it would be a great idea to design the laptop with the exhaust fan leading to the bottom of the system. Seems that it overheats due to the poor ventilation and thus melts some of the solder off the GPU and well, you know....

    Anyways, I've got some hacking projects I wanted to work on, and decided to use my Surface tablet to do so. As I went to build my hack, it decided to not build stating "asm68k.exe" can not be run by this PC.

    Now, this could be mean two things.

    A. The ARM processor can not actually run the .exe because it is written for x86 processors......
    or.
    B. Microsoft's 8.1 is being a little bitch because the thing is unsigned.

    Any help on the situation is greatly appreciated.
  3. How to optimize Shield Art loading in Sonic 1

    30 April 2014 - 01:39 AM

    Have you ever been working on a hack in Sonic 1 and realized you don't have enough VRAM to load more art? I know I have, and the idea of not having enough room is quite annoying. Well no more, because with this tutorial,you nice folks will now have 31 free 8x8 blocks of VRAM.

    As a side note, this tutorial is written specifically with the 2005 disassembly in mind. I'm assuming that this tutorial is simple enough to port to the HG disassembly, but as I have little time to actually do it myself, or mental enough to try to waddle my way around the damn thing, port to your own risk. Also, this code should work in all of the Sonic 128 disassemblies as well, in fact this code was written is said disassembly.

    Enjoy

    Step One: Adding the DMA Queue

    If you haven't added this piece of code and it's fixes into your disassembly, go ahead and add it. You may have it already if you've added in the Spin Dash from this tutorial. If that is the case, go down to Step two.

    Look for "PalCycle_SS" and add this piece of code right before it. This will speed things up for later.

    ; ---------------------------------------------------------------------------
    ; Subroutine for queueing VDP commands (seems to only queue transfers to VRAM),
    ; to be issued the next time ProcessDMAQueue is called.
    ; Can be called a maximum of 18 times before the buffer needs to be cleared
    ; by issuing the commands (this subroutine DOES check for overflow)
    ; ---------------------------------------------------------------------------
    ; In case you wish to use this queue system outside of the spin dash, this is the
    ; registers in which it expects data in:
    ; d1.l: Address to data (In 68k address space)
    ; d2.w: Destination in VRAM
    ; d3.w: Length of data
    ; ---------------------------------------------------------------------------
     
    ; ||||||||||||||| S U B R O U T I N E |||||||||||||||||||||||||||||||||||||||
     
    ; sub_144E: DMA_68KtoVRAM: QueueCopyToVRAM: QueueVDPCommand: Add_To_DMA_Queue:
    QueueDMATransfer:
    		movea.l	($FFFFC8FC).w,a1
    		cmpa.w	#$C8FC,a1
    		beq.s	QueueDMATransfer_Done ; return if there's no more room in the buffer
     
    		; piece together some VDP commands and store them for later...
    		move.w	#$9300,d0 ; command to specify DMA transfer length & $00FF
    		move.b	d3,d0
    		move.w	d0,(a1)+ ; store command
     
    		move.w	#$9400,d0 ; command to specify DMA transfer length & $FF00
    		lsr.w	#8,d3
    		move.b	d3,d0
    		move.w	d0,(a1)+ ; store command
     
    		move.w	#$9500,d0 ; command to specify source address & $0001FE
    		lsr.l	#1,d1
    		move.b	d1,d0
    		move.w	d0,(a1)+ ; store command
     
    		move.w	#$9600,d0 ; command to specify source address & $01FE00
    		lsr.l	#8,d1
    		move.b	d1,d0
    		move.w	d0,(a1)+ ; store command
     
    		move.w	#$9700,d0 ; command to specify source address & $FE0000
    		lsr.l	#8,d1
    		move.b	d1,d0
    		move.w	d0,(a1)+ ; store command
     
    		andi.l	#$FFFF,d2 ; command to specify destination address and begin DMA
    		lsl.l	#2,d2
    		lsr.w	#2,d2
    		swap	d2
    		ori.l	#$40000080,d2 ; set bits to specify VRAM transfer
    		move.l	d2,(a1)+ ; store command
     
    		move.l	a1,($FFFFC8FC).w ; set the next free slot address
    		cmpa.w	#$C8FC,a1
    		beq.s	QueueDMATransfer_Done ; return if there's no more room in the buffer
    		move.w	#0,(a1) ; put a stop token at the end of the used part of the buffer
    ; return_14AA:
    QueueDMATransfer_Done:
    		rts
    ; End of function QueueDMATransfer
     
     
    ; ---------------------------------------------------------------------------
    ; Subroutine for issuing all VDP commands that were queued
    ; (by earlier calls to QueueDMATransfer)
    ; Resets the queue when it's done
    ; ---------------------------------------------------------------------------
     
    ; ||||||||||||||| S U B R O U T I N E |||||||||||||||||||||||||||||||||||||||
     
    ; sub_14AC: CopyToVRAM: IssueVDPCommands: Process_DMA: Process_DMA_Queue:
    ProcessDMAQueue:
    		lea	($C00004).l,a5
    		lea	($FFFFC800).w,a1
    ; loc_14B6:
    ProcessDMAQueue_Loop:
    		move.w	(a1)+,d0
    		beq.s	ProcessDMAQueue_Done ; branch if we reached a stop token
    		; issue a set of VDP commands...
    		move.w	d0,(a5)		; transfer length
    		move.w	(a1)+,(a5)	; transfer length
    		move.w	(a1)+,(a5)	; source address
    		move.w	(a1)+,(a5)	; source address
    		move.w	(a1)+,(a5)	; source address
    		move.w	(a1)+,(a5)	; destination
    		move.w	(a1)+,(a5)	; destination
    		cmpa.w	#$C8FC,a1
    		bne.s	ProcessDMAQueue_Loop ; loop if we haven't reached the end of the buffer
    ; loc_14CE:
    ProcessDMAQueue_Done:
    		move.w	#0,($FFFFC800).w
    		move.l	#$FFFFC800,($FFFFC8FC).w
    		rts
    ; End of function ProcessDMAQueue
    


    Once you've finished, go to "loc_CD4", "loc_DAE", "loc_EEE", and loc_FAE"

    Replace this piece of code.
    		tst.b	($FFFFF767).w
    		beq.s	loc_D50
    		lea	($C00004).l,a5
    		move.l	#$94019370,(a5)
    		move.l	#$96E49500,(a5)
    		move.w	#$977F,(a5)
    		move.w	#$7000,(a5)
    		move.w	#$83,($FFFFF640).w
    		move.w	($FFFFF640).w,(a5)
    		move.b	#0,($FFFFF767).w
    

    With this.
                    jsr	(ProcessDMAQueue).l 
    


    Next, go to "Level_ClrVars3". After this piece of code
    		move.w	#$8ADF,($FFFFF624).w
    		move.w	($FFFFF624).w,(a6) 
    
    


    Add this
    		clr.w	($FFFFC800).w
    		move.l	#$FFFFC800,($FFFFC8FC).w
    
    


    Next, go to "loc_47D4". After
                     jsr	Hud_Base 
    
    


    Add

            clr.w 	($FFFFC800).w
    		move.l	#$FFFFC800,($FFFFC8FC).w 
    
    


    The last fix will be fixing the Sonic Object.

    Go to "LoadSonicDynPLC". Replace this.

    ​		moveq	#0,d0
    		move.b	$1A(a0),d0	; load frame number
    		cmp.b	($FFFFF766).w,d0
    		beq.s	locret_13C96
    		move.b	d0,($FFFFF766).w
    		lea	(SonicDynPLC).l,a2
    		add.w	d0,d0
    		adda.w	(a2,d0.w),a2
    		moveq	#0,d1
    		move.b	(a2)+,d1	; read "number of entries" value
    		subq.b	#1,d1
    		bmi.s	locret_13C96
    		lea	($FFFFC800).w,a3
    		move.b	#1,($FFFFF767).w
    
    SPLC_ReadEntry:
    		moveq	#0,d2
    		move.b	(a2)+,d2
    		move.w	d2,d0
    		lsr.b	#4,d0
    		lsl.w	#8,d2
    		move.b	(a2)+,d2
    		lsl.w	#5,d2
    		lea	(Art_Sonic).l,a1
    		adda.l	d2,a1
    
    SPLC_LoadTile:
    		movem.l	(a1)+,d2-d6/a4-a6
    		movem.l	d2-d6/a4-a6,(a3)
    		lea	$20(a3),a3	; next tile
    		dbf	d0,SPLC_LoadTile ; repeat for number of	tiles
    
    		dbf	d1,SPLC_ReadEntry ; repeat for number of entries
    
    locret_13C96:
    		rts	 
    


    With this.

    		moveq	#0,d0
    		move.b	$1A(a0),d0	; load frame number
    		cmp.b	($FFFFF766).w,d0
    		beq.s	locret_13C96
    		move.b	d0,($FFFFF766).w
    		lea	(SonicDynPLC).l,a2
    		add.w	d0,d0
    		adda.w	(a2,d0.w),a2
    		moveq	#0,d5
    		move.b	(a2)+,d5
    		subq.w	#1,d5
    		bmi.s	locret_13C96
    		move.w	#$F000,d4
    		move.l	#Art_Sonic,d6
     
    SPLC_ReadEntry:
    		moveq	#0,d1
    		move.b	(a2)+,d1
    		lsl.w	#8,d1
    		move.b	(a2)+,d1
    		move.w	d1,d3
    		lsr.w	#8,d3
    		andi.w	#$F0,d3
    		addi.w	#$10,d3
    		andi.w	#$FFF,d1
    		lsl.l	#5,d1
    		add.l	d6,d1
    		move.w	d4,d2
    		add.w	d3,d4
    		add.w	d3,d4
    		jsr	(QueueDMATransfer).l
    		dbf	d5,SPLC_ReadEntry	; repeat for number of entries
     
    locret_13C96:
    		rts	 
    
    

    At this point, your ROM should be safe to build, so go ahead and build. Go play a level and see if Sonic appears on screen. If so, that means you did good and you deserve a cookie.

    Step Two: Separating the Shield and Invincibility objects

    This step is probably the most difficult step, but once it is outta the way, it'll make things easier.

    First, go to Object 38, you should see this.

    Obj38:
    		moveq	#0,d0
    		move.b	$24(a0),d0
    		move.w	Obj38_Index(pc,d0.w),d1
    		jmp	Obj38_Index(pc,d1.w)
    ; ===========================================================================
    ;               More more code.
    
    


    Delete the whole object. In it's place put this in.

    Obj38:					; XREF: Obj_Index
    		move.l	#UnC_Shield,d1			        ; Call for Regular Shield Art
    		move.w	#$A820,d2			        ; Load Art from this location (VRAM location*20)
    								; In this case, VRAM = $541*20
    		move.w	#$200,d3
    		jsr	(QueueDMATransfer).l
    ; ---------------------------------------------------------------------------		
    ShieldObj_Main:	
    		moveq	#0,d0
    		move.b	$24(a0),d0
    		move.w  Shield_Index(pc,d0.w),d1
    		jmp     Shield_Index(pc,d1.w)
    ; ===========================================================================		
    Shield_Index:                 
    		dc.w    Shield_Init-Shield_Index		
    		dc.w    ShieldChecks-Shield_Index
    ; ===========================================================================		
    Shield_Init:
    		addq.b	#2,$24(a0)
    		move.l  #Map_Obj38, $0004(A0)			; Load Shield Map into place	
    		move.b  #4,1(a0)						
    		move.b  #1,$18(a0)
    		move.b  #$18,$19(a0)
    		move.w  #$541,2(a0)			        ; Set VRAM location
    		btst    #7,($FFFFD002).w
    		beq.s   ShieldChecks
    		bset    #7,2(a0)
    ; ---------------------------------------------------------------------------		
    ShieldChecks:
    		tst.b   ($FFFFFE2D).w				; Test if Sonic has a shield
    		bne.s   SonicHasShield			        ; If so, branch to do nothing
    		tst.b   ($FFFFFE2C).w				; Test if Sonic got invisibility
    		beq.s   jmp_DeleteObj38       			; If so, delete object temporarily
    ShieldProperties:		
    		move.w  ($FFFFD008).w,8(a0)			; Load Main Character X-position
    		move.w  ($FFFFD00C).w,$C(a0)			; Load Main Character Y-position
    		move.b  ($FFFFD022).w,$22(a0)			; Something about Character status
    		lea     (Ani_obj38).l, a1			; Load Animation Scripts into a1	
    		jsr     AnimateSprite           		
    		jmp     DisplaySprite           		
    SonicHasShield:
    		rts    
    jmp_DeleteObj38: ; loc_12648:
    		jmp     DeleteObject    
    
    


    This object is now just the shield object. Now, let's go add in the invincibility object.

    Find Obj4A, you should see this.

    ; ---------------------------------------------------------------------------
    ; Object 4A - special stage entry from beta
    ; ---------------------------------------------------------------------------
    
    Obj4A:					; XREF: Obj_Index
    		moveq	#0,d0
    		move.b	$24(a0),d0
    		move.w	Obj4A_Index(pc,d0.w),d1
    		jmp	Obj4A_Index(pc,d1.w)
    ;               More code after this
    
    


    Replace the whole object with this.

    ; ---------------------------------------------------------------------------
    ; Object 4A - New Invincibility Object
    ; ---------------------------------------------------------------------------
    
    Obj4A:					; XREF: Obj_Index
    		move.l	#UnC_Stars,d1
    		move.w	#$A820,d2
    		move.w	#$200,d3
    		jsr	(QueueDMATransfer).l
    Invincibility_Main:
    		moveq	#0,d0
    		move.b	$24(a0),d0
    Invincibility_Init:		
    		addq.b	#2,$24(a0)
    		move.l	#Map_obj38,4(a0)	; loads mapping
    		move.b	#4,1(a0)
    		move.b	#1,$18(a0)
    		move.b	#$10,$19(a0)
    		move.w	#$541,2(a0)	; shield specific code
    ; ===========================================================================
    
    Obj4A_Stars:				; XREF: Obj38_Index
    		tst.b	($FFFFFE2D).w	; does Sonic have invincibility?
    		beq.s	Obj4A_Delete2	; if not, branch
    		move.w	($FFFFF7A8).w,d0
    		move.b	$1C(a0),d1
    		subq.b	#1,d1
    		bra.s	Obj4A_StarTrail
    ; ===========================================================================
    		lsl.b	#4,d1
    		addq.b	#4,d1
    		sub.b	d1,d0
    		move.b	$30(a0),d1
    		sub.b	d1,d0
    		addq.b	#4,d1
    		andi.b	#$F,d1
    		move.b	d1,$30(a0)
    		bra.s	Obj4A_StarTrail2a
    ; ===========================================================================
    
    Obj4A_StarTrail:			; XREF: Obj4A_Stars
    		lsl.b	#3,d1
    		move.b	d1,d2
    		add.b	d1,d1
    		add.b	d2,d1
    		addq.b	#4,d1
    		sub.b	d1,d0
    		move.b	$30(a0),d1
    		sub.b	d1,d0
    		addq.b	#4,d1
    		cmpi.b	#$18,d1
    		bcs.s	Obj4A_StarTrail2
    		moveq	#0,d1
    
    Obj4A_StarTrail2:
    		move.b	d1,$30(a0)
    
    Obj4A_StarTrail2a:
    		lea	($FFFFCB00).w,a1
    		lea	(a1,d0.w),a1
    		move.w	(a1)+,8(a0)
    		move.w	(a1)+,$C(a0)
    		move.b	($FFFFD022).w,$22(a0)
    		lea	(Ani_obj38).l,a1
    		jsr	(AnimateSprite).l
    		jmp	(DisplaySprite).l
    ; ===========================================================================
    
    Obj4A_Delete2:				; XREF: Obj4A_Stars
    		jmp	(DeleteObject).l			
    
    


    This completes the object replacement portion of the tutorial, let's move on. If you tried to build at this point, you'll notice it won't as there is a few errors. This next step will remedy that.

    Step Three: Adding and fixing the Art

    This step is the second most easiest step of this tutorial. First, you need to download these two files and save them into the "artunc" folder.

    Uncompressed Invicibility Stars Art
    Uncompressed Shield Art

    (btw, click on the names, they are hyperlinks straight to the art downloads.)

    Once that has been taken care of, go to "nem_Shield". You should see this.
    Nem_Shield:	binclude	artnem/shield.bin	; shield
    		align 2
    Nem_Stars:	binclude	artnem/invstars.bin	; invincibility stars
    		align 2 
    


    Now, assuming you've already placed the art into the correct folder, go ahead and replace that with this.

    UnC_Shield:	binclude		artunc/shield.bin
    		align 2
    UnC_Stars:	binclude	artunc/stars.bin	; invincibility stars
    		align 2           
    


    Now your objects will load the art. But before you go off and build, go open your "Pattern Load Cues.asm" file. You'll need to fix just one portion of the cues.

    Go to "PLC_Main2", and you should see this.

    PLC_Main2:	dc.w 2
    		dc.l Nem_Monitors	; monitors
    		dc.w $D000
    		dc.l Nem_Shield		; shield
    		dc.w $A820
    		dc.l Nem_Stars		; invincibility	stars
    		dc.w $AB80 
    
    


    Replace it with this.

    PLC_Main2:	dc.w 0
    		dc.l Nem_Monitors	; monitors
    		dc.w $D000 
    
    


    This should fix all the art issues. Now, for those wondering why I'm making you load uncompressed art as opposed to Nemesis compressed art, a simple explanation shall be given.

    1. The DMA queue can not load Nemesis compressed art.
    2. Even if it could, you still need to remove the art from the PLC. The reason is that now your art between Invincibility and Shield now shares the same VRAM location, and will simply overwrite each other when the one of the objects is in use.

    Now, there is one last step to finish, and that is....

    Step Four: Object loading from the Monitors

    For those who have noticed, the shield and Invincibility objects are now separate objects. As such, the way that the monitor loads said objects must also be updated. Luckily for us, since only the Invincibility object is the only one that changed, this last step will be the easiest step of all.

    Go to "Obj2E_ChkInvinc". Replace this.

    Obj2E_ChkInvinc:
    		cmpi.b	#5,d0		; does monitor contain invincibility?
    		bne.s	Obj2E_ChkRings
    		tst.b	($FFFFFE19).w
    		bne.s	Obj2E_NoMusic		
    		move.b	#1,($FFFFFE2D).w ; make	Sonic invincible
    		move.w	#$4B0,($FFFFD032).w ; time limit for the power-up
    		move.b	#$38,($FFFFD200).w ; load stars	object ($3801)
    		move.b	#1,($FFFFD21C).w
    		move.b	#$38,($FFFFD240).w ; load stars	object ($3802)
    		move.b	#2,($FFFFD25C).w
    		move.b	#$38,($FFFFD280).w ; load stars	object ($3803)
    		move.b	#3,($FFFFD29C).w
    		move.b	#$38,($FFFFD2C0).w ; load stars	object ($3804)
    		move.b	#4,($FFFFD2DC).w
    		tst.b	($FFFFF7AA).w	; is boss mode on?
    		bne.s	Obj2E_NoMusic	; if yes, branch
    		move.w	#$87,d0
    		jmp	(PlaySound).l	; play invincibility music
    
    


    With this

    Obj2E_ChkInvinc:
    		cmpi.b	#5,d0		; does monitor contain invincibility?
    		bne.s	Obj2E_ChkRings
    		move.b  #1,($FFFFFE2D).w	; Set Invisibility to 1
    		move.w  #$4B0,($FFFFD032).w	; Set Invisibility timer to 4B0
    		move.b	#$4A,($FFFFD200).w ; load stars	object ($3801)
    		move.b	#1,($FFFFD21C).w
    		move.b	#$4A,($FFFFD240).w ; load stars	object ($3802)
    		move.b	#2,($FFFFD25C).w
    		move.b	#$4A,($FFFFD280).w ; load stars	object ($3803)
    		move.b	#3,($FFFFD29C).w
    		move.b	#$4A,($FFFFD2C0).w ; load stars	object ($3804)
    		move.b	#4,($FFFFD2DC).w
    		tst.b	($FFFFF7AA).w		; is boss mode on?
    		bne.s   DontPlayMusic		; If so, don't play music
    		cmpi.w  #$C,($FFFFFE14).w	; Check if Sonic has air left
    		bls.s   DontPlayMusic		; If so, don't play music
    		move.w  #$87,d0			    ; Load Invisibility music
    		jmp     (PlaySound).l        
    DontPlayMusic:
    		rts
    
    


    Once you have finished, save and build. If you've done everything correctly, your ROM will build.

    Special Thanks to Shockwave for double checking and testing this code.
    A thanks to shobiz, who already had the first part already done in a different tutorial. Nevertheless, saved me a bunch of time.