.scope Main .zeropage HasBitmap_bitmap_b0: .res 1 .res 1 .res 1 .res 1 HasColormap_colormap_b0: .res 1 .res 1 .res 1 .res 1 HasXpos_xpos_b0: .res 1 .res 1 .res 1 .res 1 HasYpos_ypos_b0: .res 1 .res 1 .res 1 .res 1 SpriteSlot_sprite_b0: .res 1 .res 1 .res 1 .res 1 TEMP: Kernel2Sprite__2__tmp: Joystick__3__tmp: .res 1 SpriteShuffler__8__tmp: .res 1 .res 1 SpriteHider__9__tmp: .res 1 .res 1 .res 1 .res 1 .res 1 .res 1 .res 1 .res 1 .res 1 .res 1 .code KernelSection_lines_b0: .byte 192 BGColor_bgcolor_b0: .byte 162 Bitmap_bitmapdata_b0: .byte <(Bitmap_bitmapdata_e1_b0+31) .byte <(Bitmap_bitmapdata_e2_b0+31) Bitmap_bitmapdata_b8: .byte >(Bitmap_bitmapdata_e1_b0+31) .byte >(Bitmap_bitmapdata_e2_b0+31) Bitmap_bitmapdata_e1_b0: .byte 1 .byte 1 .byte 3 .byte 7 .byte 15 .byte 31 .byte 63 .byte 127 Bitmap_height_b0: .byte 8 .byte 8 Bitmap_bitmapdata_e2_b0: .byte 24 .byte 62 .byte 255 .byte 255 .byte 255 .byte 255 .byte 62 .byte 24 Colormap_colormapdata_b0: .byte <(Colormap_colormapdata_e3_b0+31) Colormap_colormapdata_b8: .byte >(Colormap_colormapdata_e3_b0+31) Colormap_colormapdata_e3_b0: .byte 6 .byte 3 .byte 6 .byte 9 .byte 12 .byte 14 .byte 31 .byte 63 Sprite_plyrflags_b0: .byte 0 .byte 3 .byte 2 .byte 0 Main__INITDATA: .byte 1 .byte 0 .byte 1 .byte 0 .byte 0 .byte 0 .byte 0 .byte 0 .byte 50 .byte 100 .byte 80 .byte 40 .byte 150 .byte 60 .byte 90 .byte 150 .byte 0 .byte 1 .byte 2 .byte 3 __Start: .code ;;; start action Init 10 main_init .include "vcs-ca65.h" .macpack longbranch .define PAL 0 __NMI: __Reset: __BRK: CLEAN_START ldy #20 : lda Main__INITDATA-1,y sta HasBitmap_bitmap_b0-1,y dey bne :- ; initialize data segment .code ;;; start action FrameLoop 1 start FrameLoop__start__2__NextFrame: FRAME_START .code ;;; start action Kernel2Sprite 2 preframe .define KLINES #192 .define KPAD 32 ; set height to zero in case no sprites lda #0 sta Kernel2Sprite__2__tmp+8 sta Kernel2Sprite__2__tmp+9 ; set temp value so we don't read bitmap from h/w registers lda #$F0 sta Kernel2Sprite__2__tmp+2 sta Kernel2Sprite__2__tmp+3 sta Kernel2Sprite__2__tmp+6 sta Kernel2Sprite__2__tmp+7 ;;; end action Kernel2Sprite 2 preframe ;;; start action Kernel2Sprite 2 preframe ldy #0 Kernel2Sprite__preframe__4____each: ldx SpriteSlot_sprite_b0,y ; flags set according to sprite slot value ; skip sprite if negative jmi Kernel2Sprite__preframe__4__nosprite ; set player object flags lda Sprite_plyrflags_b0,x sta NUSIZ0,y sta REFP0,y ; calculate screen height - ypos lda KLINES+KPAD sec sbc HasYpos_ypos_b0,x sta Kernel2Sprite__2__tmp+11 ; calculate bitmap pointer stx Kernel2Sprite__2__tmp+12 ; save X (Sprite index) lda HasBitmap_bitmap_b0,x ; deref bitmap tax lda Bitmap_bitmapdata_b0,x sec sbc Kernel2Sprite__2__tmp+11 sta Kernel2Sprite__2__tmp+0,y ; Y = sprite slot index lda Bitmap_bitmapdata_b8,x sbc #0 sta Kernel2Sprite__2__tmp+2,y ; get bitmap height lda Bitmap_height_b0,x sta Kernel2Sprite__2__tmp+8,y ; calculate colormap pointer ldx Kernel2Sprite__2__tmp+12 ; restore X lda HasColormap_colormap_b0,x ; deref colormap tax lda Colormap_colormapdata_b0,x sec sbc Kernel2Sprite__2__tmp+11 sta Kernel2Sprite__2__tmp+4,y lda Colormap_colormapdata_b8,x sbc #0 sta Kernel2Sprite__2__tmp+6,y ; save ypos ldx Kernel2Sprite__2__tmp+12 ; restore X lda HasYpos_ypos_b0,x sta Kernel2Sprite__2__tmp+10,y Kernel2Sprite__preframe__4__nosprite: iny cpy #2 jne Kernel2Sprite__preframe__4____each Kernel2Sprite__preframe__4____exit: ;;; end action Kernel2Sprite 2 preframe ;;; start action Kernel2Sprite 2 preframe ; shuffle pointers into (MSB, LSB) byte order ; L0 L1 H0 H1 -> L0 H0 L1 H1 lda Kernel2Sprite__2__tmp+1 ldy Kernel2Sprite__2__tmp+2 sty Kernel2Sprite__2__tmp+1 sta Kernel2Sprite__2__tmp+2 lda Kernel2Sprite__2__tmp+5 ldy Kernel2Sprite__2__tmp+6 sty Kernel2Sprite__2__tmp+5 sta Kernel2Sprite__2__tmp+6 ;;; end action Kernel2Sprite 2 preframe ;;; start action Kernel2Sprite 2 preframe lda #162 sta COLUBK ;;; end action Kernel2Sprite 2 preframe ;;; start action Kernel2Sprite 2 preframe ;;; end action Kernel2Sprite 2 preframe ;;; start action SetXPos 6 preframe sta HMCLR ;;; end action SetXPos 6 preframe ;;; start action SetXPos 6 preframe ldy #0 SetXPos__preframe__9____each: ldx SpriteSlot_sprite_b0,y lda HasXpos_xpos_b0,x .code ;;; start action SetHorizPos 7 SetHorizPos ; SetHorizPos routine ; A = X coordinate ; Y = player number (0 or 1) sta WSYNC ; start a new line sec ; set carry flag nop SetHorizPos__SetHorizPos__10__DivideLoop: sbc #15 ; subtract 15 bcs SetHorizPos__SetHorizPos__10__DivideLoop ; branch until negative eor #7 ; calculate fine offset asl asl asl asl sta RESP0,y ; fix coarse position sta HMP0,y ; set fine offset ;;; end action SetHorizPos 7 SetHorizPos iny cpy #2 jne SetXPos__preframe__9____each SetXPos__preframe__9____exit: ;;; end action SetXPos 6 preframe ;;; start action SetXPos 6 preframe ;;; end action SetXPos 6 preframe ;;; start action SetXPos 6 preframe sta WSYNC sta HMOVE ;;; end action SetXPos 6 preframe KERNEL_START .code ;;; start action Kernel2Sprite 2 kernel ldy #0 sty VDELP0 iny sta VDELP1 ;;; end action Kernel2Sprite 2 kernel ;;; start action Kernel2Sprite 2 kernel ldy #192 Kernel2Sprite__kernel__14__LVScan: .code ;;; start action Kernel2Sprite 2 scanline ; draw player 0 lda Kernel2Sprite__2__tmp+8 ; height dcp Kernel2Sprite__2__tmp+10 ; ypos bcs Kernel2Sprite__scanline__15__DoDraw1 lda #0 .byte $2C Kernel2Sprite__scanline__15__DoDraw1: lda (Kernel2Sprite__2__tmp+0),y .if 0 = 0 sta WSYNC .endif sta GRP0 lda (Kernel2Sprite__2__tmp+4),y sta COLUP0 ; draw player 1 lda Kernel2Sprite__2__tmp+9 ; height dcp Kernel2Sprite__2__tmp+11 ; ypos bcs Kernel2Sprite__scanline__15__DoDraw2 lda #0 .byte $2C Kernel2Sprite__scanline__15__DoDraw2: lda (Kernel2Sprite__2__tmp+2),y sta GRP1 lda (Kernel2Sprite__2__tmp+6),y sta COLUP1 ;;; end action Kernel2Sprite 2 scanline ;;; start action Kernel2Sprite 2 scanline ;;; end action Kernel2Sprite 2 scanline dey ; next scanline .code ;;; start action Kernel2Sprite 2 scanline ; draw player 0 lda Kernel2Sprite__2__tmp+8 ; height dcp Kernel2Sprite__2__tmp+10 ; ypos bcs Kernel2Sprite__scanline__17__DoDraw1 lda #0 .byte $2C Kernel2Sprite__scanline__17__DoDraw1: lda (Kernel2Sprite__2__tmp+0),y .if 1 = 0 sta WSYNC .endif sta GRP0 lda (Kernel2Sprite__2__tmp+4),y sta COLUP0 ; draw player 1 lda Kernel2Sprite__2__tmp+9 ; height dcp Kernel2Sprite__2__tmp+11 ; ypos bcs Kernel2Sprite__scanline__17__DoDraw2 lda #0 .byte $2C Kernel2Sprite__scanline__17__DoDraw2: lda (Kernel2Sprite__2__tmp+2),y sta GRP1 lda (Kernel2Sprite__2__tmp+6),y sta COLUP1 ;;; end action Kernel2Sprite 2 scanline ;;; start action Kernel2Sprite 2 scanline ;;; end action Kernel2Sprite 2 scanline dey ; next scanline bne Kernel2Sprite__kernel__14__LVScan ; repeat until out of lines ;;; end action Kernel2Sprite 2 kernel ;;; start action Kernel2Sprite 2 kernel lda #0 sta GRP0 sta GRP1 sta GRP0 sta GRP1 ;;; end action Kernel2Sprite 2 kernel KERNEL_END .code ;;; start action Joystick 3 postframe ; 2 control inputs share a single byte, 4 bits each lda SWCHA sta Joystick__3__tmp+0 ;;; end action Joystick 3 postframe ;;; start action Joystick 3 postframe ldx #0 Joystick__postframe__21____each: asl Joystick__3__tmp+0 bcs Joystick__postframe__21__SkipMoveRight .code ;;; start action MoveJoyX 4 joyright lda HasXpos_xpos_b0,x clc adc #1 cmp #152 bcs MoveJoyX__joyright__22__nomove sta HasXpos_xpos_b0,x MoveJoyX__joyright__22__nomove: ;;; end action MoveJoyX 4 joyright Joystick__postframe__21__SkipMoveRight: asl Joystick__3__tmp+0 bcs Joystick__postframe__21__SkipMoveLeft .code ;;; start action MoveJoyX 4 joyleft lda HasXpos_xpos_b0,x sec sbc #1 bcc MoveJoyX__joyleft__23__nomove sta HasXpos_xpos_b0,x MoveJoyX__joyleft__23__nomove: ;;; end action MoveJoyX 4 joyleft Joystick__postframe__21__SkipMoveLeft: asl Joystick__3__tmp+0 bcs Joystick__postframe__21__SkipMoveDown .code ;;; start action MoveJoyY 5 joydown lda HasYpos_ypos_b0,x clc adc #1 cmp #220 bcs MoveJoyY__joydown__24__nomove sta HasYpos_ypos_b0,x MoveJoyY__joydown__24__nomove: ;;; end action MoveJoyY 5 joydown Joystick__postframe__21__SkipMoveDown: asl Joystick__3__tmp+0 bcs Joystick__postframe__21__SkipMoveUp .code ;;; start action MoveJoyY 5 joyup lda HasYpos_ypos_b0,x sec sbc #1 bcc MoveJoyY__joyup__25__nomove sta HasYpos_ypos_b0,x MoveJoyY__joyup__25__nomove: ;;; end action MoveJoyY 5 joyup Joystick__postframe__21__SkipMoveUp: inx cpx #4 jne Joystick__postframe__21____each Joystick__postframe__21____exit: ;;; end action Joystick 3 postframe ;;; start action SpriteShuffler 8 postframe ; load two sprite slots at left side of array lda SpriteSlot_sprite_b0 sta SpriteShuffler__8__tmp+0 lda SpriteSlot_sprite_b0+1 sta SpriteShuffler__8__tmp+1 ; move two slots to the left ldx #0 SpriteShuffler__postframe__26__loop: lda SpriteSlot_sprite_b0+2,x sta SpriteSlot_sprite_b0,x inx cpx #4-2 bne SpriteShuffler__postframe__26__loop ; store two sprite slots at right side of array lda SpriteShuffler__8__tmp+0 sta SpriteSlot_sprite_b0+4-2 lda SpriteShuffler__8__tmp+1 sta SpriteSlot_sprite_b0+4-1 ;;; end action SpriteShuffler 8 postframe ;;; start action SpriteHider 9 postframe lda #4-1 sta SpriteHider__9__tmp+0 ;;; end action SpriteHider 9 postframe ;;; start action SpriteHider 9 postframe ldy #0 SpriteHider__postframe__28____each: ldx SpriteSlot_sprite_b0,y lda HasYpos_ypos_b0,x cmp #192 bcc SpriteHider__postframe__28__skip ; swap this sprite slot with slot at end of array lda SpriteSlot_sprite_b0,y pha ldx SpriteHider__9__tmp+0 ; clobbers X, but no longer used lda SpriteSlot_sprite_b0,x sta SpriteSlot_sprite_b0,y pla sta SpriteSlot_sprite_b0,x dec SpriteHider__9__tmp+0 SpriteHider__postframe__28__skip: iny cpy #2 jne SpriteHider__postframe__28____each SpriteHider__postframe__28____exit: ;;; end action SpriteHider 9 postframe FRAME_END .code jmp FrameLoop__start__2__NextFrame ; loop to next frame ;;; end action FrameLoop 1 start ; start main routine .segment "VECTORS" Return: .word $6060 VecNMI: VecReset: .word Main::__Reset VecBRK: .word Main::__BRK ;;; end action Init 10 main_init .endscope Main__Start = Main::__Start