I was curious about Neo Geo programming and decided to give it a go using the Chibiakumas tutorial. Their message board is mostly dead sadly so I doubt I'd get a good answer there, so I'm asking here. The problem I'm having is with tilemaps. My tilemap works just fine, I used the same code from the tutorial found here: https://www.chibiakumas.com/68000/platf ... #LessonP26
By itself, the tilemap works perfectly. There's just one major problem: it gets drawn over top of any sprite EXCEPT sprite 0. Scaling the shrink factor of the tilemap reveals the hidden sprites underneath. Sprite 0 gets drawn on top of everything regardless.
In my test rom, sprite 0 is the aiming sight, sprite 1 is the gun (it's the BFG from Doom, I only drew the leftmost strip just to see if it would appear) and sprites 32 and onward are the tilemap. The tilemap is made of the anchor sprite (the leftmost strip) and 39 more strips chained to the anchor sprite. I'm fairly new to NEOGEO programming but I have a basic idea of how to draw something to the screen properly. I just don't understand why this doesn't seem to work correctly, I should be nowhere near the sprite limit (either per-scanline or total sprites)
The source code for all this is a bit lengthy but I can provide it as well. Most of it is irrelevant to the problem I'm having. I'll try to cut what I can.
Main Document:
Code: Select all
;UNCOMMENT ONLY ONE OF THESE AT A TIME! ENSURES COMPATIBILITY BETWEEN HARDWARE.
;NEOGEO_MVS equ 1
NEOGEO_AES equ 1
;CREDITS:
;CHIBIAKUMAS.COM
;Neo-Geo Graphic Tool Suite by evobboy
;YY-CHR
;NEOGEODEV WIKI
; Source code based on the work from www.chibiakumas.com
include "\SrcALL\BasicMacros.asm" ;Needed for Monitor
include "\SrcNEO\NEOGEO_Macros.asm"
; USER RAM: $100000 THRU $10F2FF
flag_VBlank equ $10F2FF ;(byte) vblank flag in ram
Sprite00_X equ $100000 ;Aiming sight X pos (WORD)
Sprite00_X2 equ Sprite00_X+2 ; (WORD)
Sprite00_Y equ Sprite00_X+4 ;Aiming sight Y pos (WORD)
Sprite00_Y2 equ Sprite00_X+6 ; (WORD)
Sprite00_Shrink equ Sprite00_X+8 ;Aiming sight shrink factor (WORD)
tempByte0 equ $10000A ;general purpose temp storage (BYTE)
tempByte1 equ tempByte0+1 ;general purpose temp storage (BYTE)
tempByte2 equ tempByte1+1 ;general purpose temp storage (BYTE)
tempByte3 equ tempByte2+1 ;general purpose temp storage (BYTE)
looptemp equ tempByte3+1 ;temp loop counter (BYTE)
;these can be used as a word or long, but in doing so you will clobber anything else stored in them.
;Example: move.l d0,tempByte0 will split d0 into 4 bytes, storing the first in temp0, the second in temp1, etc.
AimingSensitivity equ $100034 ;The speed at which your cursor moves.
;Ranges from 1 to 8,Not implemented yet (BYTE)
;Even though this processor works with longs and words, each individual memory address only holds 8 bits.
;Moving a long into GameFlags00 for example would clobber the next three memory addresses.
Cursor_X equ $101000 ;Cursor Position for writing text (BYTE)
Cursor_Y equ $101001 ;Cursor Position for writing text (BYTE)
score_ones equ $101002 ;Ones digit of score (BYTE)
score_tens equ $101003 ;Tens digit of score (BYTE)
score_100 equ $101004 ;Hundreds digit of score (BYTE)
score_1000 equ $101005 ;Thousands digit of score (BYTE)
score_10000 equ $101006 ;Ten-Thousands digit of score (BYTE)
score_100000 equ $101007 ;Hundred-Thousands digit of score (BYTE)
AlienShrink equ $10100A ;alien's shrink factor - for anchor sprite. (WORD)
AlienShrink2 equ $10100C ;alien's shrink factor - for chained sprites. (WORD)
TilemapShrink equ $10100E ;tilemap's shrink factor. (WORD)
;GAME CONSTANTS:
TOTAL_MAX_PALETTES equ 4 ;how many palettes your game has (max 256)
; MEMORY MAPPED PORTS
;Hard DIPs:
DIPSW_SETTINGS equ 0
DIPSW_CHUTES equ 1
DIPSW_CTRL equ 2
DIPSW_ID0 equ 3
DIPSW_ID1 equ 4
DIPSW_MULTI equ 5
DIPSW_FREEPLAY equ 6
DIPSW_FREEZE equ 7
;VRAM zones:
SCB1 equ $0000 ;Sprite tilemaps
FIXMAP equ $7000
SCB2 equ $8000 ;Sprite shrink values
SCB3 equ $8200 ;Sprite Y positions, heights and flags
SCB4 equ $8400 ;Sprite X positions
;Basic colors:
BLACK equ $8000
MIDRED equ $4700
RED equ $4F00
MIDGREEN equ $2070
GREEN equ $20F0
MIDBLUE equ $1007
BLUE equ $100F
MIDYELLOW equ $6770
YELLOW equ $6FF0
MIDMAGENTA equ $5707
MAGENTA equ $5F0F
MIDCYAN equ $3077
CYAN equ $30FF
ORANGE equ $6F70
MIDGREY equ $7777
WHITE equ $7FFF
;Zones:
RAMSTART equ $100000 ;68k work RAM
PALETTES equ $400000 ;Palette RAM
BACKDROP equ PALETTES+(16*2*256)-2
MEMCARD equ $800000 ;Memory card
SYSROM equ $C00000 ;System ROM
;Registers:
REG_P1CNT equ $300000
REG_DIPSW equ $300001 ;Dipswitches/Watchdog
REG_SOUND equ $320000 ;Z80 I/O
REG_STATUS_A equ $320001
REG_P2CNT equ $340000
REG_STATUS_B equ $380000
REG_POUTPUT equ $380001 ;Joypad port outputs
REG_SLOT equ $380021 ;Slot select
REG_NOSHADOW equ $3A0001 ;Video output normal/dark
REG_SHADOW equ $3A0011
REG_BRDFIX equ $3A000B ;Use embedded fix tileset
REG_CRTFIX equ $3A001B ;Use game fix tileset
REG_PALBANK1 equ $3A000F ;Use palette bank 1
REG_PALBANK0 equ $3A001F ;Use palette bank 0 (default)
REG_VRAMADDR equ $3C0000 ;Tell this WHERE to draw (equivalent of $2006 on NES)
REG_VRAMRW equ $3C0002 ;Tell this WHAT to draw (equivalent of $2007 on NES)
REG_VRAMMOD equ $3C0004
REG_LSPCMODE equ $3C0006
REG_TIMERHIGH equ $3C0008
REG_TIMERLOW equ $3C000A
REG_IRQACK equ $3C000C
REG_TIMERSTOP equ $3C000E
;System ROM calls:
SYS_INT1 equ $C00438
SYS_RETURN equ $C00444
SYS_IO equ $C0044A
SYS_CREDIT_CHECK equ $C00450
SYS_CREDIT_DOWN equ $C00456
SYS_READ_CALENDAR equ $C0045C ;MVS only
SYS_CARD equ $C00468
SYS_CARD_ERROR equ $C0046E
SYS_HOWTOPLAY equ $C00474 ;MVS only
SYS_FIX_CLEAR equ $C004C2
SYS_LSP_1ST equ $C004C8 ;Clear sprites
SYS_MESS_OUT equ $C004CE
;RAM locations:
BIOS_SYSTEM_MODE equ $10FD80
BIOS_MVS_FLAG equ $10FD82
BIOS_COUNTRY_CODE equ $10FD83
BIOS_GAME_DIP equ $10FD84 ;Start of soft DIPs settings (up to $10FD93)
;Set by SYS_IO:
BIOS_P1STATUS equ $10FD94
BIOS_P1PREVIOUS equ $10FD95
BIOS_P1CURRENT equ $10FD96
BIOS_P1CHANGE equ $10FD97
BIOS_P1REPEAT equ $10FD98
BIOS_P1TIMER equ $10FD99
BIOS_P2STATUS equ $10FD9A
BIOS_P2PREVIOUS equ $10FD9B
BIOS_P2CURRENT equ $10FD9C
BIOS_P2CHANGE equ $10FD9D
BIOS_P2REPEAT equ $10FD9E
BIOS_P2TIMER equ $10FD99
BIOS_STATCURNT equ $10FDAC
BIOS_STATCHANGE equ $10FDAD
BIOS_USER_REQUEST equ $10FDAE
BIOS_USER_MODE equ $10FDAF
BIOS_START_FLAG equ $10FDB4
BIOS_MESS_POINT equ $10FDBE
BIOS_MESS_BUSY equ $10FDC2
;Memory card:
BIOS_CRDF equ $10FDC4 ;Byte: function to perform when calling BIOSF_CRDACCESS
BIOS_CRDRESULT equ $10FDC6 ;Byte: 00 on success, else 80+ and encodes the error
BIOS_CRDPTR equ $10FDC8 ;Longword: pointer to read from/write to
BIOS_CRDSIZE equ $10FDCC ;Word: how much data to read/write from/to card
BIOS_CRDNGH equ $10FDCE ;Word: usually game NGH. Unique identifier for the game that owns the save file
BIOS_CRDFILE equ $10FDD0 ;Word: each NGH has up to 16 save files associated with
;Calendar, MVS only (in BCD, USES YOUR COMPUTER'S CALENDAR IF RUNNING ON MAME)
BIOS_YEAR equ $10FDD2 ;Last 2 digits of year
BIOS_MONTH equ $10FDD3
BIOS_DAY equ $10FDD4
BIOS_WEEKDAY equ $10FDD5 ;Sunday = 0, Monday = 1 ... Saturday = 6
BIOS_HOUR equ $10FDD6 ;24 hour time, load as long to get minute and second in subsequent bytes.
BIOS_MINUTE equ $10FDD7
BIOS_SECOND equ $10FDD8
BIOS_SELECT_TIMER equ $10FDDA ;Byte: game start countdown
BIOS_DEVMODE equ $10FE80 ;Byte: non-zero for developer mode
;Upload system ROM call:
BIOS_UPDEST equ $10FEF4 ;Longword
BIOS_UPSRC equ $10FEF8 ;Longword
BIOS_UPSIZE equ $10FEFC ;Longword
BIOS_UPZONE equ $10FEDA ;Byte: zone (0=PRG, 1=FIX, 2=SPR, 3=Z80, 4=PCM, 5=PAT)
BIOS_UPBANK equ $10FEDB ;Byte: bank
SOUND_STOP equ $D00046
;Button definitions:
CNT_UP equ 0
CNT_DOWN equ 1
CNT_LEFT equ 2
CNT_RIGHT equ 3
CNT_A equ 4
CNT_B equ 5
CNT_C equ 6
CNT_D equ 7
CNT_START1 equ 0
CNT_SELECT1 equ 1
CNT_START2 equ 2
CNT_SELECT2 equ 3
;-------------------------------------------------------------------------
; CARTRIDGE HEADER
;-------------------------------------------------------------------------
; This Header is based on the work from
; "Neo-Geo Assembly Programming for the Absolute Beginner" by freem
; http://ajworld.net/neogeodev/beginner/
; Traps
dc.l $0010F300 ; Initial Supervisor Stack Pointer (SSP)
dc.l $00C00402 ; Initial PC (BIOS $C00402)
dc.l $00C00408 ; Bus error/Monitor (BIOS $C00408)
dc.l $00C0040E ; Address error (BIOS $C0040E)
dc.l $00C00414 ; Illegal Instruction (BIOS $C00414)
dc.l $00C00426 ; Divide by 0
dc.l $00C00426 ; CHK Instruction
dc.l $00C00426 ; TRAPV Instruction
dc.l $00C0041A ; Privilege Violation (BIOS $C0041A)
dc.l $00C00420 ; Trace (BIOS $C00420)
dc.l $00C00426 ; Line 1010 Emulator
dc.l $00C00426 ; Line 1111 Emulator
dc.l $00C00426 ; Reserved
dc.l $00C00426 ; Reserved
dc.l $00C00426 ; Reserved
dc.l $00C0042C ; Uninitialized Interrupt Vector
dc.l $00C00426 ; Reserved
dc.l $00C00426 ; Reserved
dc.l $00C00426 ; Reserved
dc.l $00C00426 ; Reserved
dc.l $00C00426 ; Reserved
dc.l $00C00426 ; Reserved
dc.l $00C00426 ; Reserved
dc.l $00C00426 ; Reserved
dc.l $00C00432 ; Spurious Interrupt
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Interrupts
dc.l VBlank ; Level 1 interrupt (VBlank)
dc.l IRQ2 ; Level 2 interrupt (HBlank)
dc.l IRQ3 ; Level 3 interrupt
dc.l $00000000 ; Level 4 interrupt
dc.l $00000000 ; Level 5 interrupt
dc.l $00000000 ; Level 6 interrupt
dc.l $00000000 ; Level 7 interrupt (NMI)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Traps
dc.l $FFFFFFFF ; TRAP #0 Instruction
dc.l $FFFFFFFF ; TRAP #1 Instruction
dc.l $FFFFFFFF ; TRAP #2 Instruction
dc.l $FFFFFFFF ; TRAP #3 Instruction
dc.l $FFFFFFFF ; TRAP #4 Instruction
dc.l $FFFFFFFF ; TRAP #5 Instruction
dc.l $FFFFFFFF ; TRAP #6 Instruction
dc.l $FFFFFFFF ; TRAP #7 Instruction
dc.l $FFFFFFFF ; TRAP #8 Instruction
dc.l $FFFFFFFF ; TRAP #9 Instruction
dc.l $FFFFFFFF ; TRAP #10 Instruction
dc.l $FFFFFFFF ; TRAP #11 Instruction
dc.l $FFFFFFFF ; TRAP #12 Instruction
dc.l $FFFFFFFF ; TRAP #13 Instruction
dc.l $FFFFFFFF ; TRAP #14 Instruction
dc.l $FFFFFFFF ; TRAP #15 Instruction
dc.l $FFFFFFFF ; Reserved
dc.l $FFFFFFFF ; Reserved
dc.l $FFFFFFFF ; Reserved
dc.l $FFFFFFFF ; Reserved
dc.l $FFFFFFFF ; Reserved
dc.l $FFFFFFFF ; Reserved
dc.l $FFFFFFFF ; Reserved
dc.l $FFFFFFFF ; Reserved
dc.l $FFFFFFFF ; Reserved
dc.l $FFFFFFFF ; Reserved
dc.l $FFFFFFFF ; Reserved
dc.l $FFFFFFFF ; Reserved
dc.l $FFFFFFFF ; Reserved
dc.l $FFFFFFFF ; Reserved
dc.l $FFFFFFFF ; Reserved
dc.l $FFFFFFFF ; Reserved
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Cart Header
dc.b "NEO-GEO"
dc.b $00 ;System Version (0=cart; 1/2 are used for CD games)
dc.w $0FFF ;NGH number ($0000 is prohibited)
dc.l $00080000 ;game prog size in bytes (4Mbits/512KB)
dc.l $00108000 ;pointer to backup RAM block (first two bytes are debug dips)
dc.w $0000 ;game save size in bytes
dc.b $02 ;Eye catcher anim flag (0=BIOS,1=game,2=nothing)
dc.b $00 ;Sprite bank for eyecatch if done by BIOS
dc.l softDips_All ;Software dips for Japan
dc.l softDips_All ;Software dips for USA
dc.l softDips_All ;Software dips for Europe
jmp USER ; $122
jmp PLAYER_START ; $128
jmp DEMO_END ; $12E
jmp COIN_SOUND ; $134
dc.l $FFFFFFFF,$FFFFFFFF,$FFFFFFFF,$FFFFFFFF
dc.l $FFFFFFFF,$FFFFFFFF,$FFFFFFFF,$FFFFFFFF
dc.l $FFFFFFFF,$FFFFFFFF,$FFFFFFFF,$FFFFFFFF
dc.l $FFFFFFFF,$FFFFFFFF,$FFFFFFFF,$FFFFFFFF
dc.l $FFFFFFFF,$FFFFFFFF
;org $00000182
dc.l TRAP_CODE ;pointer to TRAP_CODE
; security code required by Neo-Geo games
TRAP_CODE:
dc.l $76004A6D,$0A146600,$003C206D,$0A043E2D
dc.l $0A0813C0,$00300001,$32100C01,$00FF671A
dc.l $30280002,$B02D0ACE,$66103028,$0004B02D
dc.l $0ACF6606,$B22D0AD0,$67085088,$51CFFFD4
dc.l $36074E75,$206D0A04,$3E2D0A08,$3210E049
dc.l $0C0100FF,$671A3010,$B02D0ACE,$66123028
dc.l $0002E048,$B02D0ACF,$6606B22D,$0AD06708
dc.l $588851CF,$FFD83607
dc.w $4E75
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Software Dip Switches (a.k.a. "soft dip")
softDips_All:
dc.b "EXAMPLE SET A " ; Game Name
dc.w $FFFF ; Special Option 1
dc.w $FFFF ; Special Option 2
dc.b $FF ; Special Option 3
dc.b $FF ; Special Option 4
dc.b $02 ; Option 1: 2 choices, default #0
dc.b $00,$00,$00,$00,$00,$00,$00,$00,$00 ; filler
dc.b "OPTION 1A " ; Option 1 description
dc.b "CHOICE1 A " ; Option choices
dc.b "CHOICE2 A "
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; USER
; Needs to perform actions according to the value in BIOS_USER_REQUEST.
; Must jump back to SYSTEM_RETURN at the end so the BIOS can have control.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
USER:
move.b d0,$300001 ;Kick watchdog
lea $10F300,sp ;Set stack pointer to BIOS_WORKRAM
move.w #0,$3C0006 ;LSPC_MODE - Disable auto-animation, timer interrupts
;set auto-anim speed to 0 frames
move.w #7,$3C000C ;LSPC_IRQ_ACK - acknowledge all IRQs
move.w #$2000,sr ; Enable VBlank interrupt, go Supervisor
; Handle user request
moveq #0,d0
move.b ($10FDAE).l,d0 ;BIOS_USER_REQUEST
lsl.b #2,d0 ; shift value left to get offset into table
lea cmds_USER_REQUEST,a0
movea.l (a0,d0),a0
jsr (a0)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; BIOS_USER_REQUEST commands
cmds_USER_REQUEST:
dc.l userReq_StartupInit ; Command 0 (Initialize)
dc.l userReq_StartupInit ; Command 1 (Custom eyecatch)
dc.l userReq_Game ; Command 2 (Demo Game/Game)
dc.l userReq_Game ; Command 3 (Title Display)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; userReq_StartupInit
userReq_StartupInit:
KickWatchdog
jmp $C00444 ;SYSTEM_RETURN
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Handle Interrupts and system events
PLAYER_START: ;Player pressed start on title
KickWatchdog
rts
COIN_SOUND:
DEMO_END:
rts
VBlank:
btst #7,$10FD80 ;BIOS_SYSTEM_MODE - check if the BIOS wants to run its vblank
bne gamevbl
jmp $C00438 ;SYSTEM_INT1 - run BIOS vblank
gamevbl: ;run the game's vblank
movem.l d0-d7/a0-a6,-(sp) ;save registers
move.w #4,$3C000C ;LSPC_IRQ_ACK - acknowledge the vblank interrupt
KickWatchdog
jsr $C0044A ;"Call SYSTEM_IO every 1/60 second."
jsr $C004CE ;Puzzle Bobble calls MESS_OUT just after SYSTEM_IO
move.b #0,flag_VBlank ;clear vblank flag so waitVBlank knows to stop
movem.l (sp)+,d0-d7/a0-a6 ;restore registers
rte
IRQ2:
move.w #2,$3C000C ;LSPC_IRQ_ACK - ack. interrupt #2 (HBlank)
KickWatchdog
rte
IRQ3:
move.w #1,$3C000C ;LSPC_IRQ_ACK - acknowledge interrupt 3
KickWatchdog
rte
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; UserReq_Game
userReq_Game:
; YOUR ACTUAL GAME CODE GOES HERE - EVERYTHING ABOVE IS REQUIRED BY THE SYSTEM.
; -RGB ;Color Num:
move.w #$0000,$401FFE ;0 - Background color
move.l #4,AimingSensitivity
move.w #$1000,$3C0006 ;set auto-animation speed to 8 frames.
Setup_HOWTOPLAY: ;The "HOW TO PLAY" screen from NAM 1975. Duplicated here for testing purposes only.
;Will modify to show this game's controls instead.
ifd NEOGEO_MVS ;NOT AVAILABLE ON NEOGEO AES
;this is getting annoying so i'll set my system to aes to skip it for now.
MOVE.L #$00000200,$10F300 ;All buttons released
MOVE.L #$000001FF,$10F304 ;All arrows highlighted
MOVE.L #$0010F3E2,$10F308 ;MESS_OUT
MOVE.W #$0004,$10F30C ;Wait 4 frames
MOVE.L #$0000000C,$10F30E ;Init loop counter to 12
MOVE.L #$00000100,$10F312 ;All arrows cleared
MOVE.L #$00000000,$10F316 ;Wait...
MOVE.W #$0008,$10F31A ;...8 frames
MOVE.L #$000000FF,$10F31C ;Loop back (blink all arrows 12 times.)
MOVE.L #$00000201,$10F320 ;A button is pressed.
MOVE.L #$00000100,$10F324 ;All arrows cleared.
MOVE.L #$0010F418,$10F328 ;MESS_OUT
MOVE.W #$0004,$10F32C ;Wait 4 frames
MOVE.L #$0000000C,$10F32E ;Init loop counter to 12
MOVE.L #$00000200,$10F332 ;All buttons released
MOVE.L #$00000000,$10F336 ;Wait...
MOVE.W #$0008,$10F33A ;...8 frames
MOVE.L #$00000201,$10F33C ;A button is pressed.
MOVE.L #$00000000,$10F340 ;Wait...
MOVE.W #$0008,$10F344 ;...8 frames
MOVE.L #$000000FF,$10F346 ;Loop back (blink A Button 12 times)
JSR SYS_HOWTOPLAY
endif
ClearFixLayer
;This system bios call loads its own palettes over top of yours so you
;need to reload your palettes after it's done!
Prep_VRAM:
jsr LoadPalettes ;callee preserved. No need to back up regs.
LEA TestData2,A0
MOVE.W #$0000,D1
JSR CreateSprites ;gun
LEA TestData,A0
MOVE.W #$0001,D1
JSR CreateSprites ;aiming sight
MOVE.W #$077F,TilemapShrink
JSR DefineTilemap
;BUG: Any sprite other than Sprite 0 is shown BEHIND the tilemap!
;--------------------------------------------------------------------------
inf:
KickWatchdog
jsr HandleControls
jmp inf
;---------------------------------------------------------------------
; SUBROUTINES
;---------------------------------------------------------------------
include "NEOGEO_Subroutines.asm"
;include "\SrcALL\Multiplatform_BCD.asm"
include "CreateSprites.asm"
include "tilemap2.asm"
;-------------------------------------------------------------------------
; DEBUG TOOLS CREATED BY KEITH OF CHIBIAKUMAS.COM
;-------------------------------------------------------------------------
ShowDebugScreen:
CLR.B (Cursor_X) ;RESET DEBUG SCREEN DRAWING CURSORS TO ZERO
CLR.B (Cursor_Y)
lea Message,a3
jsr PrintString ;Show String Message
jsr NewLine ;Move down a line
jsr Monitor ;Show Registers
jsr Monitor_MemDump ;Dump 6 lines from $00010000
dc.l $101000
dc.w $6
jsr NewLine
jsr NewLine
lea InsertCoinMessage,a3
jsr PrintString
RTS
PrintString:
move.b (a3)+,d0 ;Read a character in from A3
cmp.b #255,d0
beq PrintString_Done ;Return on 255
jsr PrintChar ;Print the Character
bra PrintString
PrintString_Done:
rts
NewLine:
addq.b #1,(Cursor_Y) ;Inc Ypos
clr.b (Cursor_X) ;Zero Xpos
rts
PrintChar:
moveM.l d0-d7/a0-a7,-(sp)
and #$FF,d0
sub #32,d0 ;First character in font is CHR(32)
;VRAM address = $7000 + (Ypos * 32) + Xpos
Move.L #$7000,d5 ;Tilemap base $7000
clr.L d4
Move.B (Cursor_X),D4
rol.L #5,D4 ;X*32
add.L D4,D5
clr.L d4
Move.B (Cursor_Y),D4
add #2,d4 ;NEO doesn't recommend using top 2 columns
add.L D4,D5
; PTTT - P=Palette T=TileNum
add.w #$1800,d0 ;Tile Num (Palette 1 - Tile $800+)
move.w d5,$3C0000 ;VRAM Address
move.w d0,$3C0002 ;VRAM Write (tile data)
addq.b #1,(Cursor_X) ;INC Xpos
cmp.b #39,(Cursor_X) ;At end of line?
bls nextpixel_Xok
jsr NewLine ;NewLine!
nextpixel_Xok:
moveM.l (sp)+,d0-d7/a0-a7
rts
include "\SrcALL\Multiplatform_Monitor.asm"
;--------------------------------------------------------------------------
; CONTROLLER INPUT
;--------------------------------------------------------------------------
include "controller.asm"
;--------------------------------------------------------------------------
; DATA TABLES ETC
;--------------------------------------------------------------------------
Message: dc.b 'DEBUG SCREEN',255
even
InsertCoinMessage: dc.b 'INSERT COIN...',255
EVEN
;SPRITE SHEETS
TilemapCompressed:
;not used but the label was retained to prevent the assembler from rejecting my code for now.
;PALETTES
Palette_1: ; PALETTE 1 - WE DON'T MESS WITH PALETTE ZERO.
dc.w $0FFF; ;0 -RGB transparent
dc.w $0808; ;1 -RGB dark magenta
dc.w $00FF; ;2 -RGB cyan
dc.w $0FFF; ;3 -RGB white
dc.w $0F0F; ;4 -RGB bright magenta
dc.w $0FF0; ;5 -RGB bright yellow
dc.w $033D; ;6 -RGB navy blue
dc.w $0AAA; ;7 -RGB light gray
dc.w $0E76; ;8 -RGB
dc.w $0EA5; ;9 -RGB
dc.w $0FF4; ;10 -RGB
dc.w $0A2A; ;11 -RGB
dc.w $0F0F; ;12 -RGB
dc.w $003D; ;13 -RGB
dc.w $036B; ;14 -RGB
dc.w $00DF; ;15 -RGB
Palette_2:
dc.w $0333; ;0 -RGB
dc.w $0444; ;1 -RGB
dc.w $0555; ;2 -RGB
dc.w $0FFF; ;3 -RGB
dc.w $0FFF; ;4 -RGB
dc.w $0286; ;5 -RGB
dc.w $03D3; ;6 -RGB
dc.w $0E33; ;7 -RGB
dc.w $0E76; ;8 -RGB
dc.w $0EA5; ;9 -RGB
dc.w $0FF4; ;10 -RGB
dc.w $0A2A; ;11 -RGB
dc.w $0F0F; ;12 -RGB
dc.w $003D; ;13 -RGB
dc.w $036B; ;14 -RGB
dc.w $00DF; ;15 -RGB
Palette_3
dc.w $0F00; ;0 -RGB
dc.w $00F0; ;0 -RGB
dc.w $000F; ;0 -RGB
dc.w $0F00; ;0 -RGB
dc.w $00F0; ;0 -RGB
dc.w $00F0; ;0 -RGB
dc.w $0F00; ;0 -RGB
dc.w $00F0; ;0 -RGB
dc.w $000F; ;0 -RGB
dc.w $0F00; ;0 -RGB
dc.w $00F0; ;0 -RGB
dc.w $000F; ;0 -RGB
dc.w $0F00; ;0 -RGB
dc.w $00F0; ;0 -RGB
dc.w $000F; ;0 -RGB
dc.w $0F00; ;0 -RGB
Palette_4:
dc.w $0FFF; ;0 -RGB
dc.w $0EEE; ;1 -RGB
dc.w $0DDD; ;2 -RGB
dc.w $0FF0; ;3 -RGB
dc.w $0BBB; ;4 -RGB
dc.w $0AAA; ;5 -RGB
dc.w $0999; ;6 -RGB
dc.w $0888; ;7 -RGB
dc.w $0777; ;8 -RGB
dc.w $0666; ;9 -RGB
dc.w $0555; ;10 -RGB
dc.w $0444; ;11 -RGB
dc.w $0333; ;12 -RGB
dc.w $0222; ;13 -RGB
dc.w $0111; ;14 -RGB
dc.w $0000; ;15 -RGB
;EOF
Code: Select all
;;;;;;;;;;;; DEFINE TILEMAP ;;;;;;;;;;;;;;;;;;;;;;;;
DefineTilemap:
MOVE.W #$8020,D7 ;ATTRIBS ADDR
MOVE.W #$0800,D6 ;TILE ADDR LOWER NUMBER SPRITES ARE DRAWN ON TOP OF HIGHER ONES SO WE NEED THIS TO BE A HIGH NUMBER.
MOVE.W (TilemapShrink),D5 ;SHRINK FACTOR (50%)
MOVE.L #30,D4 ;SPRITE WIDTH
MOVE.L #27,D2 ;SPRITE HEIGHT
;DEFINE ANCHOR SPRITE
MOVE.W D7,$3C0000 ;SET VRAMADDR TO $8000
MOVE.W D5,$3C0002 ;STORE SHRINK FACTOR INTO $8000
ADD.W #$200,D7 ;D7 NOW POINTS TO Y POS DESTINATION
MOVE.W D7,$3C0000 ;SET VRAMADDR TO $8200
MOVE.W #$F821,D0 ;Y POS OF $F8 AND SPRITE HEIGHT OF 33 WHICH FILLS WHOLE SCREEN
MOVE.W D0,$3C0002 ;STORE Y POS AND SPRITE HEIGHT INTO $8200
ADD.W #$200,D7 ;D7 NOW POINTS TO X POS DESTINATION
MOVE.W D7,$3C0000 ;SET VRAMADDR TO $8400
MOVE.W #$0400,$3C0002 ;STORE X POS IN $8400
SUB.W #$400,D7 ;RESET D7 BACK TO $8000
;;;;;TILES
SpriteLoop:
move.l d2,d3 ;SET UP LOOP COUNTER. THIS WAY WE CAN PRESERVE D2.
TileLoop:
MOVE.W D6,$3C0000 ;SET VRAMADDR TO SPRITE ZERO'S ADDRESS ($0000)
MOVE.W #$2010,$3C0002
ADDQ.W #1,D6 ;INCREMENT D6 TO POINT TO SPRITE ZERO'S ATTRIB DATA
MOVE.W D6,$3C0000 ;SET VRAMADDR TO SPRITE ZERO'S ATTRIB ($0001)
MOVE.W #$0100,$3C0002 ;SEND PALETTE DATA TO THE DESTINATION ADDR.
ADDQ.W #1,D6
DBRA D3,TileLoop
;At this point the anchor sprite is finished.
;CHAINED SPRITE
AND.W #%1111111111000000,D6 ;RESET D6 TO THE NEAREST MULTIPLE OF $40
ADD.W #$40,D6 ;ADD $40 TO REACH NEXT SPRITE ADDR
ADD.W #$001,D7 ;NEXT SPRITE ADDR FOR SHRINK/X/Y
MOVE.W D7,$3C0000
MOVE.W D5,$3C0002
ADD.W #$200,D7
MOVE.W D7,$3C0000
MOVE.W #$0040,$3C0002 ;THIS IS A CHAINED SPRITE.
ADD.W #$200,D7
MOVE.W D7,$3C0000
MOVE.W #$0000,$3C0002 ;X POS IS IGNORED FOR CHAINED SPRITES.
SUB.W #$400,D7
DBRA D4,SpriteLoop
JMP inf
;Set tilenumbers!
move.l #0,d2 ;y pos
lea TileMap,a6 ;get tilemap data to write to screen.
TileNextY:
move.l #0,d1
TileNextX:
clr.l d0
move.b (a6)+,d0
add.l #$200C,d0
jsr SetTile
addq.l #1,d1
cmp #40,d1
bne TileNextX
addq.l #1,d2
cmp #26,d2
bne TileNextY
RTS
SetTile:
movem.l d1-d2,-(sp) ;tileXY (d1,d2)=d0
rol.w #6,d1 ;xpos * 64
rol.w #1,d2 ;ypos * 2
add.w d2,d1 ;tile address
add.w #$800,d1 ;where bkgd sprites start
move.w d1,$3C0000
move.w d0,$3C0002
movem.l (sp)+,d1-d2
rts
TileMap: ;decimal 40 wide, decimal 26 tall
dc.b 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
dc.b 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
dc.b 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
dc.b 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
dc.b 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
dc.b 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
dc.b 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
dc.b 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
dc.b 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
dc.b 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
dc.b 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
dc.b 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
dc.b 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
dc.b 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
dc.b 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
dc.b 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
dc.b 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2
dc.b 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2
dc.b 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2
dc.b 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2
dc.b 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2
dc.b 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2
dc.b 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2
dc.b 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2
dc.b 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3
dc.b 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3
Code: Select all
; PROBLEM: WE HAVE MORE PARAMETERS FOR CREATING SPRITE DATA THAN WE HAVE
; DATA REGISTERS ON THE 68000.
; POSSIBLE SOLUTIONS: TAKING A PAGE FROM CHIBIAKUMAS BOOK, WE USE
; A SIMILAR METHOD TO HOW KEITH SETS UP THE SEGA GENESIS VDP SETTINGS.
; ORGANIZE THE DATA REGS BETTER TO MAKE IT MORE READABLE.
CreateSprites:
;INPUT: MOVE.W SPRITE ID NO.,D1 (0 THRU DECIMAL 379)
;INPUT: LEA TestData,a0
MOVE.L D1,-(SP)
ADD.W #$8000,D1 ;ADD $8000 TO D1 TO GET DESTINATION FOR SHRINK FACTOR
MOVE.W (A0)+,D2 ;LOAD SHRINK FACTOR INTO D2
MOVE.W D1,$3C0000 ;WHERE TO WRITE DATA ($8000+SPRITENUM)
MOVE.W D2,$3C0002 ;WHAT DATA TO WRITE (SHRINK FACTOR)
ADD.W #$200,D1 ;ADD $200 TO D1 TO GET DESTINATION FOR Y POS
MOVE.W (A0)+,D2 ;LOAD Y POS INTO D2
MOVE.W (A0)+,D3 ;LOAD SPRITE HEIGHT DATA INTO D3
OR.W D3,D2 ;COMBINE SPRITE HEIGHT WITH Y POS. ;DO NOT RE-USE D3, I WILL CHECK IT LATER
MOVE.W (A0)+,D0 ;LOAD CHAIN BIT INTO D0
OR.W D0,D2 ;COMBINE CHAIN BIT WITH Y POS. ;DO NOT RE-USE D0, I WILL CHECK IT LATER
MOVE.W D1,$3C0000 ;WHERE TO WRITE DATA ($8200+SPRITENUM)
MOVE.W D2,$3C0002 ;WHAT DATA TO WRITE
ADD.W #$200,D1 ;ADD $200 TO D1 TO GET DESTINATION FOR X POS
; AND #$0040,D3 ;IS THERE A CHAIN BIT?
; BNE skipXpos ;X POS IS IGNORED FOR CHAINED SPRITES
; FOR NOW WE WILL WRITE AN X POS VALUE TO $8400 EVEN IF THE SPRITE IS CHAINED BUT WE'LL TRY THIS LATER.
MOVE.W (A0)+,D2 ;LOAD X POS INTO D2
MOVE.W D1,$3C0000 ;WHERE TO WRITE DATA ($8400+SPRITENUM)
MOVE.W D2,$3C0002 ;WHAT DATA TO WRITE
skipXpos:
MOVE.L (SP)+,D1 ;POP D1
MOVE.W D1,D4 ;COPY D1 TO D4 SINCE WE WILL MESS WITH THAT VALUE.
ROL.L #6,D4 ;MULTIPLY SPRITE NUMBER BY $40 FOR TILE AND ATTRIB USE.
MOVE.W D3,D2 ;WE NO LONGER NEED D2 SO COPY THE SPRITE SIZE TO IT TO USE AS A LOOP COUNTER.
SUBQ.W #1,D2 ;SUBTRACT 1 TO FIX EXTRA TILE BUG
loop_CreateSprites: ;LOOP BEGINS HERE
MOVE.W (A0)+,D7 ;LOAD TILE ID NO. INTO D7
MOVE.W D4,$3C0000 ;WHERE TO WRITE THE TILE ID DATA (SPRITENUM*$40)
MOVE.W D7,$3C0002 ;WHAT DATA TO WRITE (THE TILE ID DATA)
ADDQ.L #1,D4 ;INCREMENT D4 BY 1 SINCE THAT'S WHERE PALETTE/ATTRIB DATA GOES.
MOVE.W (A0)+,D5 ;LOAD PALETTE DATA INTO D5
ROL.L #8,D5 ;SHIFT PALETTE DATA INTO TOP BYTE WHERE IT BELONGS
MOVE.W (A0)+,D6 ;LOAD ANIM/FLIP DATA INTO D6
OR.W D6,D5 ;MERGE ANIM/FLIP DATA WITH PALETTE DATA
MOVE.W D4,$3C0000 ;WHERE TO WRITE PALETTE DATA ((SPRITENUM*$40)+1)
MOVE.W D5,$3C0002 ;WHAT DATA TO WRITE (MERGED PALETTE/ANIM/FLIP DATA)
ADDQ.L #1,D4 ;INCREMENT D4 BY 1 TO POINT TO NEXT TILE'S TILE ID DESTINATION. (IF ANY)
;NOW REPEAT FOR EACH TILE IN THE SPRITE.
;BUG: NUMBER OF TILES EQUALS SPRITE HEIGHT +1, UNLESS SPRITE HEIGHT IS ZERO THEN NO SPRITE IS DRAWN.
;WHETHER I USE DBRA OR DBEQ SEEMS TO MAKE NO DIFFERENCE.
dbeq D2,loop_CreateSprites ;uses sprite size as a loop counter since other tiles only need
;tile ID and attrib. data.
Debug
RTS
TestData:
;TILE 0
DC.W $0FFF ;SHRINK FACTOR WRITE TO $8000 + SPRITE NUMBER
DC.W $C200 ;Y POS WRITE TO $8200 + SPRITE NUMBER
DC.W $0001 ;SPRITE HEIGHT WRITE TO $8200 + SPRITE NUMBER (OR'D WITH Y POS)
DC.W $0000 ;CHAIN BIT WRITE TO $8200 + SPRITE NUMBER (OR'D WITH Y POS)
DC.W $5000 ;X POS WRITE TO $8400 + SPRITE NUMBER
DC.W $2000 ;TILE ID NO. WRITE TO (SPRITE NUMBER*40)
DC.W $0001 ;PALETTE DATA WRITE TO (SPRITE NUMBER*$40)+1
DC.W $0004 ;ANIM/FLIP WRITE TO (SPRITE NUMBER*$40)+1 (OR'D WITH PALETTE)
TestData2:
;TILE 0
DC.W $0FFF ;SHRINK FACTOR WRITE TO $8000 + SPRITE NUMBER
DC.W $C200 ;Y POS WRITE TO $8200 + SPRITE NUMBER
DC.W $0005 ;SPRITE HEIGHT WRITE TO $8200 + SPRITE NUMBER (OR'D WITH Y POS)
DC.W $0000 ;CHAIN BIT WRITE TO $8200 + SPRITE NUMBER (OR'D WITH Y POS)
DC.W $5000 ;X POS WRITE TO $8400 + SPRITE NUMBER
DC.W $2018 ;TILE ID NO. WRITE TO (SPRITE NUMBER*40)
DC.W $0002 ;PALETTE DATA WRITE TO (SPRITE NUMBER*$40)+1
DC.W $0000 ;ANIM/FLIP WRITE TO (SPRITE NUMBER*$40)+1 (OR'D WITH PALETTE)
DC.W $2020,$0002,$0000 ;TILE 1 ID, PAL, ANIM/FLIP
DC.W $2028,$0002,$0000 ;TILE 2
DC.W $2030,$0002,$0000 ;TILE 3
DC.W $2038,$0002,$0000 ;TILE 4
DC.W $201D,$0002,$0000 ;TILE 5
DC.W $201E,$0002,$0000 ;TILE 6
DC.W $200D,$0002,$0000 ;TILE 7
DC.W $200D,$0001,$0000 ;TILE 8
DC.W $200D,$0001,$0000 ;TILE 9
DC.W $200D,$0001,$0000 ;TILE 10
DC.W $200D,$0001,$0000 ;TILE 11
DC.W $200D,$0001,$0000 ;TILE 12
DC.W $200D,$0001,$0000 ;TILE 13
DC.W $200D,$0001,$0000 ;TILE 14
DC.W $200D,$0001,$0000 ;TILE 15
DC.W $200D,$0001,$0000 ;TILE 16
DC.W $200D,$0001,$0000 ;TILE 17
DC.W $200D,$0001,$0000 ;TILE 18
DC.W $200D,$0001,$0000 ;TILE 19
DC.W $200D,$0001,$0000 ;TILE 20
DC.W $200D,$0001,$0000 ;TILE 21
DC.W $200D,$0001,$0000 ;TILE 22
DC.W $200D,$0001,$0000 ;TILE 23
DC.W $200D,$0001,$0000 ;TILE 24
DC.W $200D,$0001,$0000 ;TILE 25
DC.W $200D,$0001,$0000 ;TILE 26
DC.W $200D,$0001,$0000 ;TILE 27
DC.W $200D,$0001,$0000 ;TILE 28
EVEN