
                   GameSite's Genesis Programming Tutorial.
                                       
                                  [INLINE]
                                      
  This tutorial describes the steps necessary to setup the Genesis for
  operation. Check out this month's game selection, Racing Demo.
  Part 2 will provide all the details necessary to program a Genesis game.
  (Except sound).
  
   Download the Genesis C compiler by Paul Lee We'll try to have a
   tutorial covering programming the Genesis in C soon. The example
   programs provide plenty of info.
   You will need our Genesis assembler/disassembler, and the Genesis
   programming FAQ.
   Also helpful the 68000 instruction set reference.
   You may also need UCON v1.41 to convert the binary files generated by
   the assembler to the format used by many cartridge copiers.
   First we start off discussing the Genesis header. The assembler
   handles most of the stuff needed to setup the header. The header is
   the first 512 bytes of a Genesis binary game file. The first 256 bytes
   are system vectors. The first two double words (DWORDs) are stack
   pointer and program counter. The stack pointer is best set to
   $00fffe00. And the program counter is set by the START assembler
   directive. The next 26 DWORDs are best set to $200. This is an example
   of the first line of the header.
        dc.l $00FFFE00,$200,$200,$200,$200

   The next 3 DWORDs are system interrupt vectors.
   The first in called INT2 and is used by external components. I haven't
   seen this on used. The INT2 assembler directive can be used to set it.
   The next interrupt is the Horizontal Blank Interrupt or HBL. It can be
   set with the HBL assembler directive.
   The last interrupt vector is the Vertical Blank Interrupt or VBL. It
   can be set with the VBL assembler directive.
   This is an example of setting the START address, the HBL and VBL
   interrupts.
        START
        tst.l   $a10008.l        ;This is the code that runs first.
        bne.s   SkipJoyDetect


        HBL
        ...code done each HBL...

        VBL
        movem.l  d0-d7/a0-a4,-(a6)
SpriteRoutine:

   The next 256 bytes of the header describe the program. The Genesis
   uses this area to setup the system.
   Genesis Rom fully describes this area.
   The areas That must be setup are:
   $100-$110: This is the security code that starts the Genesis.
   $18E-$18F: Checksum. This area is optional. The assembler will put the
   checksum in the header if it is called with the -c command line
   option. (ie asm -c source.asm) The Genesis doesn't
   use the checksum. The program may check it.
   $1A0-$1A3: Start of Genesis Memory. Always set to $00000000.
   $1A4-$1A7: End of Program Memory. This area is set by the assembler.
   $1A8-$1AB: Start of Ram. Always set to $FF000000.
   $1AC-$1AF: End of Ram. Always set to $FFFFFFFF.
   $1B0-$1BB: Indicates External Save Ram. Usually filled with spaces
   ($20) to indicate no Save Ram is present.
   Refer to Genesis Rom for more details.
   $1BC-$1EF: Not normally used. fill with spaces ($20).
   Refer to Genesis Rom for more details.
   $1F0-$1F2: Country Code. Put 'JUE' to allow play in Japan, USA, and
   Europe. If a letter is left out the rest are moved up.
   $1F3-$1FF: Filled with spaces ($20).
   If you are unclear on any of this, or just to be safe use the header
   in
   SEGA.ASM included with the assembler.
   Ok now that we have the header out of the way we can move onto the
   code.

        nop
        nop
        rte

   This handles all unassigned system vectors.
        START
        tst.l   $a10008.l
        bne.s   SkipJoyDetect
        tst.w   $a1000c.l
SkipJoyDetect:
        bne     SkipSetup

   I'm a little unclear on the above code. It seems to check for a
   joystick and skips the setup routine if one isn't found.

        lea     Table(pc),a5
        movem.w (a5)+,d5-d7
        movem.l (a5)+,a0-a4

   The above code loads registers:
   D5 with $8000. This is used to transfer initial values into VDP
   registers.
   Refer to Programming FAQ for more info on VDP registers.
   D6 with $3fff
   D7 with $0100. Used in setting VDP registers.
   A0 with $a00000. This points to the Z80 area. (Used for music)
   A1 with $a11000. This points to the system info area.
   A2 with $a11200. This points to the Z80 control area.
   A3 with $c00000. This points to the VDP\VRAM\SRAM\CRAM data port.
   A4 with $c00004. This points to the VDP\VRAM\SRAM\CRAM control port.

        move.b  -$10ff(a1),d0          ;Check Version Number

        andi.b  #$0f,d0
        beq.s   WrongVersion
        move.l  #$53454741,$2f00(a1)   ;Sega Security Code (SEGA)
WrongVersion:

   This checks version number and puts the security code in the system
   area. I believe the Genesis locks up in a short time if this code
   isn't put into the system area. Older Genesis don't require the
   security code.

        move.w  (a4),d0
        moveq   #$00,d0
        movea.l d0,a6
        move    a6,usp

   The value in $c00004 is saved for later use.

        moveq   #$17,d1                ; Set VDP registers
FillLoop:
        move.b  (a5)+,d5
        move.w  d5,(a4)
        add.w   d7,d5
        dbra    d1,FillLoop

   This transfers byte data to VDP registers. The format is ($80+VDP
   register number)


        move.l  (a5)+,(a4)
        move.w  d0,(a3)

   Sets up VRAM for write access to $0000. Also puts in $00 to be used to
   clear VRAM by DMA. DMA is started by putting clear value into $c00000.
   DMA was set up when VDP registers were initialized.
   Refer to Programming FAQ for more info on VDP registers.

        move.w  d7,(a1)
        move.w  d7,(a2)
L0250:
        btst    d0,(a1)
        bne.s   L0250
        moveq   #$25,d2                ; Put initial values into a00000

Filla:
        move.b  (a5)+,(a0)+
        dbra    d2,Filla

   Resets and clears Z80 area.

        move.w  d0,(a2)
        move.w  d0,(a1)
        move.w  d7,(a2)
L0262:
        move.l  d0,-(a6)
        dbra    d6,L0262
        move.l  (a5)+,(a4)
        move.l  (a5)+,(a4)
        moveq   #$1f,d3                ; Put initial values into c00000

Filc0:
        move.l  d0,(a3)
        dbra    d3,Filc0

   Sets up Video Scroll Ram for write access. Clears Video Scroll Ram.

        move.l  (a5)+,(a4)
        moveq   #$13,d4                ; Put initial values into c00000

Fillc1:
        move.l  d0,(a3)
        dbra    d4,Fillc1
        moveq   #$03,d5                ; Put initial values into c00011

Fillc2:
        move.b  (a5)+,$0011(a3)
        dbra    d5,Fillc2

   Address $c00011 has something to due with the Sound Generator. Puts
   initial values into Sound Generator area.

        move.w  d0,(a2)
        movem.l (a6),d0-d7/a0-a6
        move    #$2700,sr

   Disables Interrupts. Restores values to registers.

SkipSetup:
        bra.s   Continue
Table:
        dc.w    $8000, $3fff, $0100, $00a0, $0000, $00a1, $1100, $00a1
        dc.w    $1200, $00c0, $0000, $00c0, $0004, $0414, $302c, $0754
        dc.w    $0000, $0000, $0000, $812b, $0001, $0100, $00ff, $ff00

        dc.w    $0080, $4000, $0080, $af01, $d91f, $1127, $0021, $2600
        dc.w    $f977, $edb0, $dde1, $fde1, $ed47, $ed4f, $d1e1, $f108

        dc.w    $d9c1, $d1e1, $f1f9, $f3ed, $5636, $e9e9, $8104, $8f01

        dc.w    $c000, $0000, $4000, $0010, $9fbf, $dfff

   Contains values to load into registers, VDP registers, $c00000,
   $c00004, and $c00011

Continue:
        tst.w     $00C00004

   Ensures DMA is done.
   Don't forget to come back next month when we'll get into the REAL
   Genesis stuff. We'll discuss screen setup, sprites, joystick control
   and VBL.
   
                                    Back
                            Back to Welcome Page
