Jump to content
IGNORED

Need to reduce the CPU time this routine takes (help!)


Recommended Posts

Hi guys:

 

I know some of you are great at reducing the time things take with tricks... I kind of need that help with this routine that runs in VBLANK.

 

As it stands, it takes too long and crashes the game.

 

It is the routine that runs in VBLANK and partially rebuilds the display list with the new locations of 8 sprites. It start with a display list of a character mode (the first 5 bytes) and initializes the 'last dl entry' being set there. It then adds the 8 sprites to the end of whatever display lists it occupies. Each sprite takes up three zones. I'd really like to use this as when it works there is no slow down when all 8 objects are on the screen at the same time.

There are three loops: 1) initializes the 'last dl entry' flag to just after the character mode (i.e. first 5 bytes) - 2) Adds the sprites to the end of whatever current zone they occupy - and 3) terminates the display list with $00,$00,$00.

 

Thanks, guys

 

Bob

 

; UPDATE STAMP INFORMATION FOR NEXT RUN OF KERNAL
LOADER
  LDX #$00		 ;FIRST, INITIALIZE THE 'LAST DL ENTRY' TO BE JUST AFTER THE CHARACTER MODE DL
  LDA #$05		 ;THE FIRST 5 BYTES ARE THE CHARACTER MODE DL ENTRIES
LOADCLEARLOOP
  STA LASTDLENTRY,X
  INX
  CPX #LASTZONE
  BMI LOADCLEARLOOP

  LDX #$00		 ;NOW, ADD EACH SPRITE ONLY WHERE THEY ARE ON THE SCREEN
LOADSPRITELOOP
  LDA OTLIST,X	 ;SKIP SPRITE IF DISABLED (OFFSCREEN)
  CMP #T_DISABLED
  BNE LSLSTART
  JMP LSLNEXT

LSLSTART
  LDA VPLIST,X	 ;FIRST, GET CURRENT VERTICAL POSITION
  AND #$0F		 ;MASK OFFSET
  STA LDRTEMP6	 ;SAVE IT FOR THE OFFSET

  CLC
  LDA VZLIST,X	 ;NEXT PREPARE THE ZONES FOR EACH OF THE THREE SPRITE PARTS
  AND #$0F
  STA ZONTEMP0
  ADC #$01
  AND #$0F
  STA ZONTEMP1
  ADC #$01
  AND #$0F
  STA ZONTEMP2

  LDA SHLIST,X	 ;NOW GET THE HIGH STAMP ADDRESS OFFSET FOR EACH ZONE
  BMI LSLSHORT
  ADC LDRTEMP6 ;THIS IS DONE BECAUSE THE SPRITES ABOVE #$8000 ONLY USE TWO ZONES (NOT THREE)
LSLSHORT
  ADC #$10
  STA STMTEMP0	 ;TOP PART
  LDA SHLIST,X
  ADC LDRTEMP6
  STA STMTEMP1	 ;MIDDLE PART
  CLC
  ADC #$F0		 ;BOTTOM PART
  STA STMTEMP2

  LDA HPLIST,X	 ;NOW MODIFY THE HORIZONTAL POSITION TO INCLUDE THE SCROLLING
  CLC
  ADC WINDOWOBJADJ	 ;ADD IN THE SCROLLING ADJUSTMENT IF ANY
  STA HPLIST,X
  STA HPOSTEMP

  LDY ZONTEMP0	 ;NOW BUILD THE DL FOR THIS ZONE (PART 1/3)
  LDA DLLO,Y
  STA LDRTEMP0
  LDA DLHI,Y
  STA LDRTEMP1
  LDA LASTDLENTRY,Y
  TAY
  LDA SLLIST,X	 ;LOW STAMP ADDRESS
  STA (LDRTEMP0),Y
  INY
  LDA #$C0		 ;STAMP MODE (NOT CHAR MODE)
  STA (LDRTEMP0),Y
  INY
  LDA STMTEMP0	 ;HIGH STAMP ADDRESS WITH OFFSET
  STA (LDRTEMP0),Y
  INY
  LDA LOADPALETTEWIDTH,X	 ;GET PALETTE AND WIDTH
  STA (LDRTEMP0),Y
  INY
  LDA HPOSTEMP
  STA (LDRTEMP0),Y
  INY
  TYA
  LDY ZONTEMP0
  STA LASTDLENTRY,Y	 ;STORE THE UPDATED DL POSITION

  LDY ZONTEMP1	 ;NOW BUILD THE DL FOR THIS ZONE (PART 2/3)
  LDA DLLO,Y
  STA LDRTEMP0
  LDA DLHI,Y
  STA LDRTEMP1
  LDA LASTDLENTRY,Y
  TAY
  LDA SLLIST,X	 ;LOW STAMP ADDRESS
  STA (LDRTEMP0),Y
  INY
  LDA #$C0		 ;STAMP MODE (NOT CHAR MODE)
  STA (LDRTEMP0),Y
  INY
  LDA STMTEMP1	 ;HIGH STAMP ADDRESS WITH OFFSET
  STA (LDRTEMP0),Y
  INY
  LDA LOADPALETTEWIDTH,X	 ;GET PALETTE AND WIDTH
  STA (LDRTEMP0),Y
  INY
  LDA HPOSTEMP
  STA (LDRTEMP0),Y
  INY
  TYA
  LDY ZONTEMP1
  STA LASTDLENTRY,Y	 ;STORE THE UPDATED DL POSITION

  LDY ZONTEMP2	 ;NOW BUILD THE DL FOR THIS ZONE (PART 3/3)
  LDA DLLO,Y
  STA LDRTEMP0
  LDA DLHI,Y
  STA LDRTEMP1
  LDA LASTDLENTRY,Y
  TAY
  LDA SLLIST,X	 ;LOW STAMP ADDRESS
  STA (LDRTEMP0),Y
  INY
  LDA #$C0		 ;STAMP MODE (NOT CHAR MODE)
  STA (LDRTEMP0),Y
  INY
  LDA STMTEMP2	 ;HIGH STAMP ADDRESS WITH OFFSET
  STA (LDRTEMP0),Y
  INY
  LDA LOADPALETTEWIDTH,X	 ;GET PALETTE AND WIDTH
  STA (LDRTEMP0),Y
  INY
  LDA HPOSTEMP
  STA (LDRTEMP0),Y
  INY
  TYA
  LDY ZONTEMP2
  STA LASTDLENTRY,Y	 ;STORE THE UPDATED DL POSITION

  LDA HPOSTEMP
  SEC		 ;UPDATE THE COLUMN WITH THE SCROLLING SCREEN
  SBC #LEFTSIDE
  SBC WINDOWOFFSET
  LSR
  LSR
  LSR
  STA HCLIST,X
  LSLNEXT
  INX
  CPX #NUMOBJECT
  BPL LSLDONE
  JMP LOADSPRITELOOP

LSLDONE
  LDX #$00		 ;ADD THE TERMINATING DL ZEROS TO EACH DL
LOADTERMINATELOOP
  LDA DLLO,X		 ;GET THE DISPLAY LIST ADDRESS
  STA LDRTEMP0
  LDA DLHI,X
  STA LDRTEMP1
  LDY LASTDLENTRY,X	 ;THE LAST DL ENTRY FOR THIS ZONE
  LDA #$00
  STA (LDRTEMP0),Y	 ;FORCE THE THREE TERMINATING ZEROS AFTER THIS DL ENTRY
  INY
  STA (LDRTEMP0),Y
  INY
  STA (LDRTEMP0),Y
  INX
  CPX #LASTZONE
  BMI LOADTERMINATELOOP
  LDA #$00		 ;ALL OF THE OBJECT HAVE BEEN ADJUSTED
  STA WINDOWOBJADJ	 ;CLEAR THE SCROLLING ADJUSTMENT VALUE
  RTS

LOADPALETTEWIDTH
  .byte $1C,$1E,$1E,$1C,$1C,$1C,$1C,$1C ;THERE SHOULD BE #NUMOBJECT ENTRIES HERE

Link to comment
Share on other sites

I must confess I haven't wrapped my head around this code :), but there are two small things I noticed:

 

It seems loops are counting up. If they would count down instead, then CPX could be saved. (Usually this also has the advantage that depending on how you do this the index is either -1 or 0 at the end, which may have further use.) For example, in the first loop:

 

  LDA #$05
  LDX #LASTZONE
LOADCLEARLOOP
  STA LASTDLENTRY,X
  DEX
  BPL LOADCLEARLOOP

 

 

In the last loop, LDA #$00 can be hoisted out of the loop body:

 

  LDA #$00
  LDX #LASTZONE
LOADTERMINATELOOP
  LDY DLLO,X
  STY LDRTEMP0
  LDY DLHI,X
  STY LDRTEMP1
  LDY LASTDLENTRY,X
  STA (LDRTEMP0),Y
  INY
  STA (LDRTEMP0),Y
  INY
  STA (LDRTEMP0),Y
  DEX
  BPL LOADTERMINATELOOP

  STA WINDOWOBJADJ ; A still 0

Link to comment
Share on other sites

I will look more deeply at the code you are using tomorrow when I am home.

 

In my initial Beef Drop DL Builder initially I did...

 

Background DLs were all preinitialized and added to DLL

Loop through each zone

Skip over background stuff which was preinitialized once

Loop through each sprite

Add any (and the appropriate part) that should be on this zone

End Loop

End Loop

 

It worked but it took a lot of cycles. (this is potentially a loop of 8 inside a loop of 24)

 

 

I think eventually I rewrote it for Beef Drop (and used for b*nQ and I will describe for b*nQ since it was more complicated since sprites could go behind the background, and could be different widths and modes)

 

I kept a table of pointers for each zone. I then needed an array of indexes

 

Intitialize Index for each zone to 0

Loop through each object

If it is a behind the playfield object, calculate and update the appropriate 2 or 3 DL entries (using table and index to know where to write) and update indexes

EndLoop

 

Loop through each zone and add the playfield entries

 

Loop through each object

If it is a foreground object, update the appropriate 2 or 3 DL entries (using table and index to know where to write) and update indexes

EndLoop

Add terminators.

 

This worked much faster since the loops are not nested.

 

 

 

 

For both, each list was allocated for each line to the maximum size (which I think you also do) which wastes RAM but anything that does not change you only do once and never have to update and the DLL only needs built once and doesn't have to change.

 

For terminating the list it only important that the second byte be a zero (you don't have to waste time writing a zero in the first byte or any other bytes for that display list entry)

 

--Ken

Edited by kenfused
Link to comment
Share on other sites

Looks like it pretty much follows my second algorithm.

 

One thing I would suggest is anything accessed in these loops put into zero page (even the list of last entries) if you can if you are not already doing so.

 

There might be a CLC or two you could knock out if you know the prior add will never leave the carry set (probably not a big savings).

 

Do the display stuff as soon as you can in your VBI if you are doing other stuff. Although as long as you get the DL entries built before the line is displayed you should be ok (although if Maria is really busy it may not leave much time for code to execute once you are on the display screen). You can throw in a background color change at the start and end of the DL building code to see where you are on the screen when it is executing.

 

 

You should be able to remove these three lines that are struck through.

 

LDY LASTDLENTRY,X ;THE LAST DL ENTRY FOR THIS ZONE

LDA #$00

STA (LDRTEMP0),Y ;FORCE THE THREE TERMINATING ZEROS AFTER THIS DL ENTRY

INY

STA (LDRTEMP0),Y

INY

STA (LDRTEMP0),Y

Link to comment
Share on other sites

@roland p - I see what you're getting at, and I'll see if I can make sure LDRTEMP1 always points to the same page and only set it once.

If so, maybe you can change the code into:

LDY ZONTEMP0 ;NOW BUILD THE DL FOR THIS ZONE (PART 1/3)
LDA DLLO,Y
CLC
ADC LASTDLENTRY,Y
TAY

LDA SLLIST,X ;LOW STAMP ADDRESS
STA SOME_PAGE,Y
LDA #$C0 ;STAMP MODE (NOT CHAR MODE)
STA SOME_PAGE+1,Y
LDA STMTEMP0 ;HIGH STAMP ADDRESS WITH OFFSET
STA SOME_PAGE+2,Y
LDA LOADPALETTEWIDTH,X ;GET PALETTE AND WIDTH
STA SOME_PAGE+3,Y
LDA HPOSTEMP
STA SOME_PAGE+4,Y
INY
TYA
LDY ZONTEMP0
STA LASTDLENTRY,Y ;STORE THE UPDATED DL POSITION

Link to comment
Share on other sites

Any particular reason you're using 5 byte entries instead of 4? That would save you 9 cycles per zone (27 per sprite).

 

I'd also recommend reviewing all of the code & calculations you're doing before the "Now Build the DL" code. Are you actually saving cycles/RAM/code by pre-calculating those values, or could they be done in the zone code? For instance ZONTEMP0/ZONTEMP1/ZONTEMP2 aren't required and can be calculated from VZLIST,X as required.

 

Note: only try to eliminate CLC/SEC after you've finished optimizing everything. And always ask yourself "could C be different than I expect?" for all opcodes which change C.

 

In http://atariage.com/forums/topic/104546-sample-7800-source-code-using-zpx/ I found a slight improvement using (ZP,X) instead of (ZP),Y to build the display lists. Although the store+increment is 12 cycles instead of 7 cycles, there's a savings on the start & end.

Link to comment
Share on other sites

Thanks guys!

 

OK, some answers:

 

1) LDRTEMP1 does not always point to the same page; in fact there are 3 different pages possible. :(

2) I am using 5 bytes headers because there is a Character (Indirect) mode being used, i.e. the first 5 bytes that I am skipping (pre-defined outside of this routine).

 

So, I implemented the decrement mode (instead of increment), the 'only writing the second zero byte' to terminate the list, and the removal of the ZONTEMP variables and computed them on the fly.

 

Let me see if this helps.... I'll report back!

Thanks again,

Bob

 

EDIT - Actually the ZONTEMP variables are needed, as they are used more than once in the routine and to keep calculating them (instead of saving them) would take up more time. :(

 

BTW - Ken the call to LOADER is the only thing in my VBI after waiting for VBlank:

 

BOTDLI
	 TYA
	 PHA
	 CLD
	 LDA	 #BLACK
	 STA	 BACKGRND
	 LDA	 #$FF
	 STA	 KNLTEMP			 ;SET TOP DLI TO HAPPEN NEXT
	 INC	 RTLOCAL+1			 ;INCREMENT CLOCK
	 BNE	 DLICONT
	 INC	 RTLOCAL
DLICONT
	 JSR	 TUNER				 ;DO TUNES
	 JSR	 RAND				 ;UPDATE RANDOM NUMBER
	 JSR	 SCROLLER			 ;SCROLL SCREEN IF NECESSARY
DLLWAIT
	 BIT	 MSTAT				 ;WAIT FOR VBLANK
	 BPL	 DLLWAIT
DLLOTHER
	 JSR	 LOADER				 ;LOAD UP NEXT FRAME
	 PLA						 ;UNSTACK AND LEAVE
	 TAY
DLIOUT
	 PLA						 ;THIS IS WHERE MOST DLIs LEAVE
	 TAX
	 PLA
NULLRTI
	 RTI

Edited by PacManPlus
Link to comment
Share on other sites

Really? You can mix 5-byte and 4-byte headers? Never knew that! :)

 

Yes, the zone after the last displayed zone has the final interrupt.

 

Getting back to the header thing, you can have this?:

<(SCRSCOR+$00),$60,>(SCRSCOR+$00),$60+$06,#LEFTSIDE ;SCORE DLIST (WHITE)

<(SPRITE1),$20+$04,>(SPRITE1),HPOS

<(SPRITE2),$40+$04,>(SPRITE2),HPOS

...

$00,$00,$00

Link to comment
Share on other sites

Thanks!

 

My Sprites are 160B (12 color) - does that make a difference? The background (character mode) is the normal 3 color 160A... I have a feeling because of this it might make things more difficult... am I correct? (it's the 'Bentley Bear's Crystal Quest' game)

 

@ken - I'll double-check that most of the variables are in zero page - I do know that the ZONTEMP and the LDRTEMP variables are. But the SLLIST or actually any of the XXLIST variables are not due to their size

 

Thank you all again - I really appreciate the help.

Bob

Link to comment
Share on other sites

Just tried the 4-byte header thing (made a dummy sprite 1 byte width to change the write mode).

 

The routine got farther, but still crashed. :(

 

Back to square 1 ...

(BTW, I am also trying to figure this one out myself)

 

Thanks,

Bob

Link to comment
Share on other sites

you said you were doing a wait for vertical blank in the vbi routine...

Place the DLI that triggers it on the first blank line at the bottom and not on the last blank line (if you are not already doing so).

The wait-for-vertical-blank should not be necessary.\

 

These assume the DLL and the blank line DL entries at the bottom do not change which I don't think you change them.

 

--Ken

Edited by kenfused
Link to comment
Share on other sites

Ok, so if I have this:

 

	 .byte	 $0F,>(NULDLST),<(NULDLST)			 ;16 BLANK LINES
	 .byte	 $07,>(NULDLST),<(NULDLST)			 ;8 BLANK LINES
	 .byte	 $C6,>(SCDLIST),<(SCDLIST)			 ;SCORE ZONE - 7 LINES - FIRST INTERRUPT
	 .byte	 $07,>(INDLIST),<(INDLIST)			 ;INDICATOR ZONE - 8 LINES
	 .byte	 $01,>(NULDLST),<(NULDLST)			 ;2 BLANK LINES
	 .byte	 $CF,>(DLIST01),<(DLIST01)			 ;PF ZONE 01 - 15 LINES
	 .byte	 $CF,>(DLIST02),<(DLIST02)			 ;PF ZONE 02 - 16 LINES
	 .byte	 $CF,>(DLIST03),<(DLIST03)			 ;PF ZONE 03 - 16 LINES
	 .byte	 $CF,>(DLIST04),<(DLIST04)			 ;PF ZONE 04 - 16 LINES
	 .byte	 $CF,>(DLIST05),<(DLIST05)			 ;PF ZONE 05 - 16 LINES
	 .byte	 $CF,>(DLIST06),<(DLIST06)			 ;PF ZONE 06 - 16 LINES
	 .byte	 $CF,>(DLIST07),<(DLIST07)			 ;PF ZONE 07 - 16 LINES
	 .byte	 $CF,>(DLIST08),<(DLIST08)			 ;PF ZONE 08 - 16 LINES
	 .byte	 $CF,>(DLIST09),<(DLIST09)			 ;PF ZONE 09 - 16 LINES
	 .byte	 $CF,>(DLIST10),<(DLIST10)			 ;PF ZONE 10 - 16 LINES
	 .byte	 $CF,>(DLIST11),<(DLIST11)			 ;PF ZONE 11 - 16 LINES
	 .byte	 $8F,>(NULDLST),<(NULDLST)			 ;16 BLANK LINES - FINAL INTERRUPT
	 .byte	 $09,>(NULDLST),<(NULDLST)			 ;10 BLANK LINES

 

I don't need the

BIT MSTAT ;WAIT FOR VBLANK

BPL DLLWAIT

in the BOTDLI routine above? Wow - I've done this (and the 5-byte header for all objects) in all of my games...

 

I'll give that a try...

 

Thanks!

Bob

 

BTW, There's an interrupt on every displayed zone because I am changing colors when necessary. :)

 

EDIT - I tried this, but now the music suddenly stops, and I have Display List corruption (which is what happened when I originally put the 'Loader' routine call before the wait for VBlank instead of after.) :(

 

Damn.

Edited by PacManPlus
Link to comment
Share on other sites

I usually advised against mixing STA WSYNC and DLI as STA WSYNC pauses the CPU, which may cause it to miss the DLI interrupt (or at least delay it to the start of the next line).

He would be using STA WSYNC within the DLI. I don't think it would be necessary but didn't know if there would be some slight jitter to when the vbi routine starts each time.

 

Outside the DLI I know it could be problematic. IIRC, on the Atari 400/800s the keyclick routine used it which could cause DLI issues.

Edited by kenfused
Link to comment
Share on other sites

Hi Guys!

 

I think I found something that works, although it uses quite a bit of ROM space. I had to comment a lot of sound data out just to test this idea I had to see if it works. It seems to run without crashing. :D

Please note, that the 'INSERTSPRITE2' routine is commented out because I am using the 'INSERTSPRITE3' routine to test instead:

 

*NOTE - It sucks that the 'CODE' tags don't include tabs, which is why nothing is indented here. It is in the source code file :x

LOADER
LDX #LASTZONE - 1							;FIRST, INITIALIZE THE 'LAST DL ENTRY' TO BE JUST AFTER THE CHARACTER MODE DL
LDA #$0A									;THE FIRST 5 BYTES ARE THE CHARACTER MODE DL ENTRIES
LOADCLEARLOOP
STA LASTDLENTRY,X
DEX
BPL LOADCLEARLOOP

LDX #$00									;NOW, ADD EACH SPRITE ONLY WHERE THEY ARE ON THE SCREEN
LOADSPRITELOOP
LDA OTLIST,X								;SKIP SPRITE IF DISABLED (OFFSCREEN)
CMP #T_DISABLED
BEQ LSLNEXT

LDA HPLIST,X								;NOW MODIFY THE HORIZONTAL POSITION TO INCLUDE THE SCROLLING
CLC
ADC WINDOWOBJADJ							;ADD IN THE SCROLLING ADJUSTMENT IF ANY
STA HPLIST,X
STA HPOSTEMP

LDA VPLIST,X								;GET VERTICAL POSITION OFFSET
AND #$0F
CLC
ADC SHLIST,X								;HIGH STAMP ADDRESS WITH OFFSET
STA LDRTEMP1								;'MIDDLE' PART OF STAMP (OR TOP OF 2 ZONE HIGH STAMP)
ADC #$10
STA LDRTEMP0								;'TOP' PART OF STAMP
ADC #$E0
STA LDRTEMP2								;'BOTTOM' PART OF STAMP

LDA SHLIST,X
BMI LSLSHORT								;GRAPHICS DATA WHICH START > $8000 ARE ONLY 2 ZONES HIGH INSTEAD OF 3
LDA VZLIST,X
JSR INSERTSPRITE3							;INSERT THE SPRITE IN THE DISPLAY LIST
JMP LSLNEXT
LSLSHORT
LDA VZLIST,X
JSR INSERTSPRITE2
LSLNEXT
LDA HPOSTEMP
SEC											;UPDATE THE COLUMN WITH THE SCROLLING SCREEN
SBC #LEFTSIDE
SBC WINDOWOFFSET
LSR
LSR
LSR
STA HCLIST,X
INX
CPX #NUMOBJECT
BMI LOADSPRITELOOP

LDA #$00									;ADD THE TERMINATING DL ZEROS TO EACH DL
LDX #LASTZONE - 1
LOADTERMINATELOOP
LDA DLLO,X									;GET THE DISPLAY LIST ADDRESS
STA LDRTEMP0
LDA DLHI,X
STA LDRTEMP1
LDY LASTDLENTRY,X							;THE LAST DL ENTRY FOR THIS ZONE
LDA #$00
INY
STA (LDRTEMP0),Y								;FORCE THE THREE TERMINATING ZEROS AFTER THIS DL ENTRY (ONLY ONE ZERO IS NEEDED)
DEX
BPL LOADTERMINATELOOP

STA WINDOWOBJADJ							;CLEAR THE SCROLLING ADJUSTMENT VALUE
RTS

;	INSERTSPRITE3 - JUMPS TO A ROUTINE THAT PUTS THE 3 ZONE SPRITE IN THE CORRECT DL
INSERTSPRITE3
JSR JMPENGINE
.word IS3ZONE01
.word IS3ZONE02
.word IS3ZONE03
.word IS3ZONE04
.word IS3ZONE05
.word IS3ZONE06
.word IS3ZONE07
.word IS3ZONE08
.word IS3ZONE09
.word IS3ZONE10
.word IS3ZONE11
.word ISRTS
.word ISRTS
.word ISRTS
.word IS3ZONE15
.word IS3ZONE16

;	INSERTSPRITE2 - JUMPS TO A ROUTINE THAT PUTS THE 2 ZONE SPRITE IN THE CORRECT DL
INSERTSPRITE2
JSR JMPENGINE
.word IS2ZONE01
.word IS2ZONE02
.word IS2ZONE03
.word IS2ZONE04
.word IS2ZONE05
.word IS2ZONE06
.word IS2ZONE07
.word IS2ZONE08
.word IS2ZONE09
.word IS2ZONE10
.word ISRTS
.word ISRTS
.word ISRTS
.word ISRTS
.word IS2ZONE15
.word IS2ZONE16
ISRTS
RTS

;	3-ZONE SPRITE INSERT
IS3ZONE01
LDA LDRTEMP0
JSR INSERTSPRITEZONE1						;DO TOP OF SPRITE
LDA LDRTEMP1
JSR INSERTSPRITEZONE2						;DO MIDDLE OF SPRITE
LDA LDRTEMP2
JMP INSERTSPRITEZONE3						;DO BOTTOM OF SPRITE

IS3ZONE02
LDA LDRTEMP0
JSR INSERTSPRITEZONE2						;DO TOP OF SPRITE
LDA LDRTEMP1
JSR INSERTSPRITEZONE3						;DO MIDDLE OF SPRITE
LDA LDRTEMP2
JMP INSERTSPRITEZONE4						;DO BOTTOM OF SPRITE

IS3ZONE03
LDA LDRTEMP0
JSR INSERTSPRITEZONE3						;DO TOP OF SPRITE
LDA LDRTEMP1
JSR INSERTSPRITEZONE4						;DO MIDDLE OF SPRITE
LDA LDRTEMP2
JMP INSERTSPRITEZONE5						;DO BOTTOM OF SPRITE

IS3ZONE04
LDA LDRTEMP0
JSR INSERTSPRITEZONE4						;DO TOP OF SPRITE
LDA LDRTEMP1
JSR INSERTSPRITEZONE5						;DO MIDDLE OF SPRITE
LDA LDRTEMP2
JMP INSERTSPRITEZONE6						;DO BOTTOM OF SPRITE

IS3ZONE05
LDA LDRTEMP0
JSR INSERTSPRITEZONE5						;DO TOP OF SPRITE
LDA LDRTEMP1
JSR INSERTSPRITEZONE6						;DO MIDDLE OF SPRITE
LDA LDRTEMP2
JMP INSERTSPRITEZONE7						;DO BOTTOM OF SPRITE

IS3ZONE06
LDA LDRTEMP0
JSR INSERTSPRITEZONE6						;DO TOP OF SPRITE
LDA LDRTEMP1
JSR INSERTSPRITEZONE7						;DO MIDDLE OF SPRITE
LDA LDRTEMP2
JMP INSERTSPRITEZONE8						;DO BOTTOM OF SPRITE

IS3ZONE07
LDA LDRTEMP0
JSR INSERTSPRITEZONE7						;DO TOP OF SPRITE
LDA LDRTEMP1
JSR INSERTSPRITEZONE8						;DO MIDDLE OF SPRITE
LDA LDRTEMP2
JMP INSERTSPRITEZONE9						;DO BOTTOM OF SPRITE

IS3ZONE08
LDA LDRTEMP0
JSR INSERTSPRITEZONE8						;DO TOP OF SPRITE
LDA LDRTEMP1
JSR INSERTSPRITEZONE9						;DO MIDDLE OF SPRITE
LDA LDRTEMP2
JMP INSERTSPRITEZONE10						;DO BOTTOM OF SPRITE

IS3ZONE09
LDA LDRTEMP0
JSR INSERTSPRITEZONE9						;DO TOP OF SPRITE
LDA LDRTEMP1
JSR INSERTSPRITEZONE10						;DO MIDDLE OF SPRITE
LDA LDRTEMP2
JMP INSERTSPRITEZONE11						;DO BOTTOM OF SPRITE

IS3ZONE10
LDA LDRTEMP0
JSR INSERTSPRITEZONE10						;DO TOP OF SPRITE
LDA LDRTEMP1
JMP INSERTSPRITEZONE11						;DO MIDDLE OF SPRITE

IS3ZONE11
LDA LDRTEMP0
JMP INSERTSPRITEZONE11						;DO TOP OF SPRITE

IS3ZONE15
LDA LDRTEMP2
JMP INSERTSPRITEZONE1						;DO BOTTOM OF SPRITE

IS3ZONE16
LDA LDRTEMP1
JSR INSERTSPRITEZONE1						;DO MIDDLE OF SPRITE
LDA LDRTEMP2
JMP INSERTSPRITEZONE2						;DO BOTTOM OF SPRITE

;	TWO-ZONE SPRITE INSERT
IS2ZONE01
LDA LDRTEMP1
JSR INSERTSPRITEZONE2						;DO MIDDLE OF SPRITE
LDA LDRTEMP2
JMP INSERTSPRITEZONE3						;DO BOTTOM OF SPRITE

IS2ZONE02
LDA LDRTEMP1
JSR INSERTSPRITEZONE3						;DO MIDDLE OF SPRITE
LDA LDRTEMP2
JMP INSERTSPRITEZONE4						;DO BOTTOM OF SPRITE

IS2ZONE03
LDA LDRTEMP1
JSR INSERTSPRITEZONE4						;DO MIDDLE OF SPRITE
LDA LDRTEMP2
JMP INSERTSPRITEZONE5						;DO BOTTOM OF SPRITE

IS2ZONE04
LDA LDRTEMP1
JSR INSERTSPRITEZONE5						;DO MIDDLE OF SPRITE
LDA LDRTEMP2
JMP INSERTSPRITEZONE6						;DO BOTTOM OF SPRITE

IS2ZONE05
LDA LDRTEMP1
JSR INSERTSPRITEZONE6						;DO MIDDLE OF SPRITE
LDA LDRTEMP2
JMP INSERTSPRITEZONE7						;DO BOTTOM OF SPRITE

IS2ZONE06
LDA LDRTEMP1
JSR INSERTSPRITEZONE7						;DO MIDDLE OF SPRITE
LDA LDRTEMP2
JMP INSERTSPRITEZONE8						;DO BOTTOM OF SPRITE

IS2ZONE07
LDA LDRTEMP1
JSR INSERTSPRITEZONE8						;DO MIDDLE OF SPRITE
LDA LDRTEMP2
JMP INSERTSPRITEZONE9						;DO BOTTOM OF SPRITE

IS2ZONE08
LDA LDRTEMP1
JSR INSERTSPRITEZONE9						;DO MIDDLE OF SPRITE
LDA LDRTEMP2
JMP INSERTSPRITEZONE10						;DO BOTTOM OF SPRITE

IS2ZONE09
LDA LDRTEMP1
JSR INSERTSPRITEZONE10						;DO MIDDLE OF SPRITE
LDA LDRTEMP2
JMP INSERTSPRITEZONE11						;DO BOTTOM OF SPRITE

IS2ZONE10
LDA LDRTEMP1
JMP INSERTSPRITEZONE11						;DO MIDDLE OF SPRITE

IS2ZONE15
LDA LDRTEMP2
JMP INSERTSPRITEZONE1						;DO TOP OF SPRITE

IS2ZONE16
LDA LDRTEMP1
JSR INSERTSPRITEZONE1						;DO MIDDLE OF SPRITE
LDA LDRTEMP2
JMP INSERTSPRITEZONE2						;DO BOTTOM OF SPRITE

INSERTSPRITEZONE1
LDY LASTDLENTRY+$00
STA DLIST01+$02,Y							;SAVE HIGH STAMP ADDRESS WITH OFFSET FIRST
LDA SLLIST,X								;LOW STAMP ADDRESS
STA DLIST01,Y
INY
LDA LOADPALETTEWIDTH,X						;GET PALETTE AND WIDTH
STA DLIST01,Y
INY
INY
LDA HPOSTEMP								;HORIZONTAL POSITION WITH SCROLL OFFSET
STA DLIST01,Y
INY
STY LASTDLENTRY+$00							;TERMINATOR
RTS

INSERTSPRITEZONE2
LDY LASTDLENTRY+$01
STA DLIST02+$02,Y							;SAVE HIGH STAMP ADDRESS WITH OFFSET FIRST
LDA SLLIST,X								;LOW STAMP ADDRESS
STA DLIST02,Y
INY
LDA LOADPALETTEWIDTH,X						;GET PALETTE AND WIDTH
STA DLIST02,Y
INY
INY
LDA HPOSTEMP								;HORIZONTAL POSITION WITH SCROLL OFFSET
STA DLIST02,Y
INY
STY LASTDLENTRY+$01							;TERMINATOR
RTS

INSERTSPRITEZONE3
LDY LASTDLENTRY+$02
STA DLIST03+$02,Y							;SAVE HIGH STAMP ADDRESS WITH OFFSET FIRST
LDA SLLIST,X								;LOW STAMP ADDRESS
STA DLIST03,Y
INY
LDA LOADPALETTEWIDTH,X						;GET PALETTE AND WIDTH
STA DLIST03,Y
INY
INY
LDA HPOSTEMP								;HORIZONTAL POSITION WITH SCROLL OFFSET
STA DLIST03,Y
INY
STY LASTDLENTRY+$02							;TERMINATOR
RTS

INSERTSPRITEZONE4
LDY LASTDLENTRY+$03
STA DLIST04+$02,Y							;SAVE HIGH STAMP ADDRESS WITH OFFSET FIRST
LDA SLLIST,X								;LOW STAMP ADDRESS
STA DLIST04,Y
INY
LDA LOADPALETTEWIDTH,X						;GET PALETTE AND WIDTH
STA DLIST04,Y
INY
INY
LDA HPOSTEMP								;HORIZONTAL POSITION WITH SCROLL OFFSET
STA DLIST04,Y
INY
STY LASTDLENTRY+$03							;TERMINATOR
RTS

INSERTSPRITEZONE5
LDY LASTDLENTRY+$04
STA DLIST05+$02,Y							;SAVE HIGH STAMP ADDRESS WITH OFFSET FIRST
LDA SLLIST,X								;LOW STAMP ADDRESS
STA DLIST05,Y
INY
LDA LOADPALETTEWIDTH,X						;GET PALETTE AND WIDTH
STA DLIST05,Y
INY
INY
LDA HPOSTEMP								;HORIZONTAL POSITION WITH SCROLL OFFSET
STA DLIST05,Y
INY
STY LASTDLENTRY+$04							;TERMINATOR
RTS

INSERTSPRITEZONE6
LDY LASTDLENTRY+$05
STA DLIST06+$02,Y							;SAVE HIGH STAMP ADDRESS WITH OFFSET FIRST
LDA SLLIST,X								;LOW STAMP ADDRESS
STA DLIST06,Y
INY
LDA LOADPALETTEWIDTH,X						;GET PALETTE AND WIDTH
STA DLIST06,Y
INY
INY
LDA HPOSTEMP								;HORIZONTAL POSITION WITH SCROLL OFFSET
STA DLIST06,Y
INY
STY LASTDLENTRY+$05							;TERMINATOR
RTS

INSERTSPRITEZONE7
LDY LASTDLENTRY+$06
STA DLIST07+$02,Y							;SAVE HIGH STAMP ADDRESS WITH OFFSET FIRST
LDA SLLIST,X								;LOW STAMP ADDRESS
STA DLIST07,Y
INY
LDA LOADPALETTEWIDTH,X						;GET PALETTE AND WIDTH
STA DLIST07,Y
INY
INY
LDA HPOSTEMP								;HORIZONTAL POSITION WITH SCROLL OFFSET
STA DLIST07,Y
INY
STY LASTDLENTRY+$06							;TERMINATOR
RTS

INSERTSPRITEZONE8
LDY LASTDLENTRY+$07
STA DLIST08+$02,Y							;SAVE HIGH STAMP ADDRESS WITH OFFSET FIRST
LDA SLLIST,X								;LOW STAMP ADDRESS
STA DLIST08,Y
INY
LDA LOADPALETTEWIDTH,X						;GET PALETTE AND WIDTH
STA DLIST08,Y
INY
INY
LDA HPOSTEMP								;HORIZONTAL POSITION WITH SCROLL OFFSET
STA DLIST08,Y
INY
STY LASTDLENTRY+$07							;TERMINATOR
RTS

INSERTSPRITEZONE9
LDY LASTDLENTRY+$08
STA DLIST09+$02,Y							;SAVE HIGH STAMP ADDRESS WITH OFFSET FIRST
LDA SLLIST,X								;LOW STAMP ADDRESS
STA DLIST09,Y
INY
LDA LOADPALETTEWIDTH,X						;GET PALETTE AND WIDTH
STA DLIST09,Y
INY
INY
LDA HPOSTEMP								;HORIZONTAL POSITION WITH SCROLL OFFSET
STA DLIST09,Y
INY
STY LASTDLENTRY+$08							;TERMINATOR
RTS

INSERTSPRITEZONE10
LDY LASTDLENTRY+$09
STA DLIST10+$02,Y							;SAVE HIGH STAMP ADDRESS WITH OFFSET FIRST
LDA SLLIST,X								;LOW STAMP ADDRESS
STA DLIST10,Y
INY
LDA LOADPALETTEWIDTH,X						;GET PALETTE AND WIDTH
STA DLIST10,Y
INY
INY
LDA HPOSTEMP								;HORIZONTAL POSITION WITH SCROLL OFFSET
STA DLIST10,Y
INY
STY LASTDLENTRY+$09							;TERMINATOR
RTS

INSERTSPRITEZONE11
LDY LASTDLENTRY+$0A
STA DLIST11+$02,Y							;SAVE HIGH STAMP ADDRESS WITH OFFSET FIRST
LDA SLLIST,X								;LOW STAMP ADDRESS
STA DLIST11,Y
INY
LDA LOADPALETTEWIDTH,X						;GET PALETTE AND WIDTH
STA DLIST11,Y
INY
INY
LDA HPOSTEMP								;HORIZONTAL POSITION WITH SCROLL OFFSET
STA DLIST11,Y
INY
STY LASTDLENTRY+$0A							;TERMINATOR
RTS

LOADPALETTEWIDTH
.byte $1C,$1E,$1E,$1C,$1C,$1C,$1C,$1C		;THERE SHOULD BE #NUMOBJECT ENTRIES HERE

 

... and here is the 'JMPROUTINE' that is being referred to:

 

; JMPENGINE - DOES A CONDITIONAL JUMP DEPENDING ON THE VALUE OF 'A'
;             ($00 = ROUTINE0, $01 = ROUTINE1, $02 = ROUTINE2...)
; INPUT: JMPLO - ADDRESS LOW TO JUMP ADDRESS,
;         JMPHI - ADDRESS HIGH TO JUMP ADDRESS,
;         JMPTOLO - JUMP ADDRESS LOW
;         JMPTOHI - JUMP ADDRESS HIGH
; USES: A, Y
;
;
; USAGE:
;         JSR     JMPENGINE
;
;     .word ROUTINE0
;     .word ROUTINE1
;     .word ROUTINE2
;     .word ROUTINE3
JMPENGINE
        ASL                         ;SHIFT BIT FROM CONTANTS OF A
        TAY
        PLA                         ;PULL SAVED RETURN ADDRESS FROM STACK
        STA     JMPLO                 ;SAVE TO INDIRECT
        PLA
        STA     JMPHI
        INY
        LDA     (JMPLO),Y             ;LOAD POINTER FROM INDIRECT
        STA     JMPTOLO             ;NOTE THAT IF AN RTS IS PERFORMED IN THE NEXT ROUTINE
        INY                         ; IT WILL RETURN TO THE EXECUTION BEFORE THE SUB
        LDA     (JMPLO),Y             ; THAT CALLED THIS ROUTINE
        STA     JMPTOHI
        JMP     (JMPTOLO)             ;JUMP TO THE ADDRESS WE LOADED

 

I'm going to have to put this code in each bank somehow (I'll have to use some of the space reserved for sound data) because it won't fit in the fixed bank in the ROM.

 

Bob

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...