Sega Genesis System Initialization

Ask anything your want about Megadrive/Genesis programming.

Moderator: BigEvilCorporation

Post Reply
walker7
Interested
Posts: 45
Joined: Tue Jul 24, 2012 6:27 am

Sega Genesis System Initialization

Post by walker7 »

This is the code that I use when initializing my Sega Genesis programs. It comes in at 154 bytes and 722,858 cycles:

Code: Select all

	org	$000200
START:
;------------------------------------------------------------------------------
; First things first: Satisfy the TMSS.
;------------------------------------------------------------------------------
	move.b	($A10001),d0		; Get System Type.
	andi.b	#$F,d0			; If it isn't type 0...
	beq.b	.0			; ...
	move.l	#'SEGA',($A14000)	; ...write "SEGA" to TMSS register.
	.0:				;
	move.w	#$2700,sr		; Disable Interrupts.
;------------------------------------------------------------------------------
; Initialize Joypads.
;------------------------------------------------------------------------------
	moveq	#$40,d0			; Load the value $40.
	lea	$A10009,a0		; Point to $A10009.
	move.b	d0,(a0)			; Write $40 to $A10009.
	move.b	d0,2(a0)		; Write $40 to $A1000B.
	move.b	d0,4(a0)		; Write $40 to $A1000D.
;------------------------------------------------------------------------------
; Initialize VDP Registers.
;------------------------------------------------------------------------------
	lea	$C00000,a0		; Load VDP Data Port.
	lea	4(a0),a1		; Load VDP Control Port.
	move.w	#$8000,d0		; Load Register Command.
	moveq	#22,d1			; Initialize Loop Counter.
	lea	.2(pc),a2		; Point to Register Data.
	.1:				;
	move.b	(a2)+,d0		; Get Value.
	move.w	d0,(a1)			; Load Value into Register.
	add.w	#$100,d0		; Increment Register.
	dbra	d1,.1			; Loop for next Register.
	bra.b	.3			; Branch to next code.
	.2:				;
	dc.b	$06			; Register $80
	dc.b	$74			; Register $81
	dc.b	$30			; Register $82
	dc.b	$2C			; Register $83
	dc.b	$07			; Register $84
	dc.b	$56			; Register $85
	dc.b	$00			; Register $86
	dc.b	$00			; Register $87
	dc.b	$00			; Register $88
	dc.b	$00			; Register $89
	dc.b	$FF			; Register $8A
	dc.b	$00			; Register $8B
	dc.b	$81			; Register $8C
	dc.b	$2A			; Register $8D
	dc.b	$00			; Register $8E
	dc.b	$02			; Register $8F
	dc.b	$11			; Register $90
	dc.b	$00			; Register $91
	dc.b	$00			; Register $92
	dc.b	$00			; Register $93
	dc.b	$00			; Register $94
	dc.b	$00			; Register $95
	dc.b	$00			; Register $96
	dc.b	$00			; Register $97 - Doesn't need to be initialized
	.3:				;
;------------------------------------------------------------------------------
; Clear CRAM.
;------------------------------------------------------------------------------
	moveq	#0,d0			; Load 0 value.
	moveq	#$1F,d1			; Initialize Loop Counter.
	move.l	#$C0000000,(a1)		; Point to Beginning of VRAM.
	.6:				;
	move.l	d0,(a0)			; Clear out CRAM.
	dbra	d1,.6			; Loop for next iteration.
;------------------------------------------------------------------------------
; Clear VRAM.
;------------------------------------------------------------------------------
	lsr.w	#2,d1			; Initialize Loop Counter.
	move.l	#$40000000,(a1)		; Point to Beginning of VRAM.
	.4:				;
	move.l	d0,(a0)			; Clear out VRAM.
	dbra	d1,.4			; Loop for next iteration.
;------------------------------------------------------------------------------
; Clear RAM.
;------------------------------------------------------------------------------
	move.l	d0,a6			; Point to End of RAM.
	lsr.w	#2,d1			; Initialize Loop Counter.
	.5:				;
	move.l	d0,-(a6)		; Clear out RAM.
	dbra	d1,.5			; Loop for next iteration.
;------------------------------------------------------------------------------
; Clear Registers.
;------------------------------------------------------------------------------
	movem.l	(a6)+,d0-a7		; Clear all registers.
	sub.l	a6,a6			;
	move.l	a0,usp			; Clear USP.
	move.w	#$2000,sr		; Enable Interrupts.
What do you think? I know that there is more you can do, such as initialize VSRAM, check to see if Reset is pressed, etc. Can someone come up with a way to do initialization with a smaller number of bytes?
Last edited by walker7 on Sat Oct 27, 2012 4:19 am, edited 1 time in total.
Chilly Willy
Very interested
Posts: 2994
Joined: Fri Aug 17, 2007 9:33 pm

Post by Chilly Willy »

Unless you're doing this as part of a contest on smallest/fastest init, it doesn't matter. Cycle and byte counting on the init for regular homebrew is as useful as tits on a man. :lol:

And if this IS part of a contest, SHAME ON YOU FOR TRYING TO CHEAT! :evil:

:D
Charles MacDonald
Very interested
Posts: 292
Joined: Sat Apr 21, 2007 1:14 am

Re: Sega Genesis System Initialization

Post by Charles MacDonald »

Nice code! I like what you did with the leftover value from dbra in the following loops. Looks tidy and compact.

Don't write to VDP register $97 during initialization; when you do that on the real thing the VDP is primed for DMA and expects the next command written to be for DMA. Just go up to $96. You don't strictly have to initialize any of the DMA registers since they won't affect the display.

I'd poll the DMA busy bit to make sure a VRAM copy or fill is not in progress. When the reset button is pressed, the VDP isn't reset, only the 68K. So DMA can still be running when the 68000 starts up and your initialization routine gets trashed.

If you want speed over size (sounds like you don't) using VRAM DMA to clear CRAM/VSRAM and VRAM fill to clear VRAM is faster than what the 68000 can do; or you can unroll your VDP memory and work RAM clearing loops so you spend more time writing and less time executing dbra.
walker7
Interested
Posts: 45
Joined: Tue Jul 24, 2012 6:27 am

Post by walker7 »

This isn't part of a contest, but it just shows a nice way to initialize the system. The $97-register problem is fixed above. And as for speed over size, it doesn't matter much in this case, as someone else stated above. If a routine was time-sensitive, then I would code for speed.

Also, when choosing a 68K assembler, I currently use EASY68K. It can be found at http://www.easy68k.com/index.html.
TmEE co.(TM)
Very interested
Posts: 2452
Joined: Tue Dec 05, 2006 1:37 pm
Location: Estonia, Rapla City
Contact:

Post by TmEE co.(TM) »

I see no Z80 in the mix :P
Mida sa loed ? Nagunii aru ei saa ;)
http://www.tmeeco.eu
Files of all broken links and images of mine are found here : http://www.tmeeco.eu/FileDen
Chilly Willy
Very interested
Posts: 2994
Joined: Fri Aug 17, 2007 9:33 pm

Post by Chilly Willy »

walker7 wrote:This isn't part of a contest, but it just shows a nice way to initialize the system. The $97-register problem is fixed above. And as for speed over size, it doesn't matter much in this case, as someone else stated above. If a routine was time-sensitive, then I would code for speed.

Also, when choosing a 68K assembler, I currently use EASY68K. It can be found at http://www.easy68k.com/index.html.
The contest thing was a joke. :D

My own init code just does up through $92 - I don't think there's ANY reason to init any of the DMA registers since you'll have to set them all anyway when you want to do a DMA operation.

I try to use gcc/binutils tools as much as possible to keep it portable and easy to update. Of course, the Z80 just has to be different - there I use zasm and sdcc. At least those are also portable and still being updated.
walker7
Interested
Posts: 45
Joined: Tue Jul 24, 2012 6:27 am

Z80 Initialization

Post by walker7 »

Here is the code I use to initialize the Z80:

Code: Select all

Init_Z80:
	move.w	#$100,($A11100)
	move.w	#$100,($A11200)		
	.1:
	btst	#0,($A11100)
	bne.b	.1
	lea	.3(pc),a0
	lea	$A00000,a1
	moveq	#.4-.3-1,d1
	.2:
	move.b	(a0)+,(a1)+
	dbra	d1,.2
	move.w	#0,($A11200)
	move.w	#0,($A11100)
	move.w	#$100,($A11200)
	rts
	;======================================================================
	.3:
	dc.w	$AF01,	$D91F,	$1127,	$0021,	$2600,	$F977	
	dc.w	$EDB0,	$DDE1,	$FDE1,	$ED47,	$ED4F,	$D1E1
	dc.w	$F108,	$D9C1,	$D1E1,	$F1F9,	$F3ED,	$5636
	dc.w	$E9E9
	.4:
Post Reply