IncAsm "VICII.asm" ; VICII register includes 
IncAsm "macros.asm" ; macro includes

SCREEN_MEM = $4000 
SCREEN1_MEM = $4000 ; Bank 1 - Screen 0 ; $4000 
SCREEN2_MEM = $4400 ; Bank 1 - Screen 1 ; $4400 
SCORE_SCREEN = $5800 ; Bank 1 - Screen 6 ; $5800 
COLOR_MEM = $D800 ; Color mem never changes 
CHAR_MEM = $4800 ; Base of character set memory (set 1) 
SPRITE_MEM = $5C00 ; Base of sprite memory  
CHRADR1 = 19992 
CHRADR3 = 20200 ; top water tile 
CHRADR4 = 20104 
COLOR_DIFF = COLOR_MEM - SCREEN_MEM ; difference between color and screen ram  
SPRITE_POINTER_BASE = SCREEN_MEM + $3f8 ; last 8 bytes of screen mem 
SPRITE_BASE = $70 ; the pointer to the first image# 
SPRITE_0_PTR = SPRITE_POINTER_BASE + 0 ; Sprite pointers 
SPRITE_1_PTR = SPRITE_POINTER_BASE + 1 
SPRITE_2_PTR = SPRITE_POINTER_BASE + 2 
SPRITE_3_PTR = SPRITE_POINTER_BASE + 3 
SPRITE_4_PTR = SPRITE_POINTER_BASE + 4 
SPRITE_5_PTR = SPRITE_POINTER_BASE + 5 
SPRITE_6_PTR = SPRITE_POINTER_BASE + 6 
SPRITE_7_PTR = SPRITE_POINTER_BASE + 7 
SPRITE_DELTA_OFFSET_X = 8 ; Offset from SPRITE coords to Delta Char coords
SPRITE_DELTA_OFFSET_Y = 11 ; approx the center of the sprite 
SPRITE_DELTA_OFFSET_Y = 14 
ENEMY_SPRITE_DELTA_OFFSET_X = 8 
ENEMY_SPRITE_DELTA_OFFSET_Y = 14 
NUMBER_OF_SPRITES_DIV_4 = 3 ; loads sprites and characters under IO ROM 
LEVEL_1_MAP = $E000 ;Address of level 1 tiles/charsets 
LEVEL_1_CHARS = $E800  
PARAM1 = $03 ; These will be used to pass parameters to routines 
PARAM2 = $04 ; when you can't use registers or other reasons 
PARAM3 = $05 PARAM4 = $06 ; essentially, think of these as extra data registers 
PARAM5 = $07 TIMER = $08 ; Timers - fast and slow, updated every frame 
SLOW_TIMER = $09 
WPARAM1 = $0A ; Word length Params. Same as above only room for 2 
WPARAM2 = $0C ; bytes (or an address) 
WPARAM3 = $0E ;---------------------------- $11 - $16 available 
ZEROPAGE_POINTER_1 = $17 ; Similar only for pointers that hold a word long address 
ZEROPAGE_POINTER_2 = $19 
ZEROPAGE_POINTER_3 = $21 
ZEROPAGE_POINTER_4 = $23 
CURRENT_SCREEN = $25 ; Pointer to current front screen 
CURRENT_BUFFER = $27 ; Pointer to current back buffer 
SCROLL_COUNT_X = $29 ; Current hardware scroll value 
SCROLL_COUNT_Y = $2A 
SCROLL_SPEED = $2B ; Scroll speed (not implemented yet) 
SCROLL_DIRECTION = $2C ; Direction we are scrolling in 
SCROLL_MOVING = $2D ; are we moving? (Set to direction of scrolling) 

; This is for resetting back to start frames 
; All data is for the top left corner of the visible map area
 
MAP_POS_ADDRESS = $2E ; (2 bytes) pointer to current address in the level map 
MAP_X_POS = $30 ; Current map x position (in tiles) 
MAP_Y_POS = $31 ; Current map y position (in tiles) 
MAP_X_DELTA = $32 ; Map sub tile delta (in characters) 
MAP_Y_DELTA = $33 ; Map sub tile delta (in characters)
KICKSTART
; Sys call to start the program - 10 SYS (2064)
*=$0801 
BYTE $0E,$08,$0A,$00,$9E,$20,$28,$32,$30,$36,$34,$29,$00,$00,$00
PRG_START
- setup VIC bank
- define character set and screen memory (VIC_MEMORY_CONTROL)
- Load the Processor Port ($0001) and turn off LRAM (Basic), HIRAM (Kernal), and CHAREN (Character ROM).
lda #0 ; Turn off sprites
sta VIC_SPRITE_ENABLE
lda VIC_SCREEN_CONTROL ; turn screen off with bit 4
and #%11100000 ; mask out bit 4 - Screen on/off
sta VIC_SCREEN_CONTROL ; save back - setting bit 4 to off

lda VIC_BANK ; Fetch the status of CIA 2 ($DD00)
and #%11111100 ; the first 2 bits are your desired VIC bank value 
ora #%00000010 ; In this case bank 1 ($4000 - $7FFF)
sta VIC_BANK
lda #%00000010 ; bits 4-7 (000) = screen memory 0 : $0000 - $03FF 
sta VIC_MEMORY_CONTROL ; bits 1-3 (001) = character memory 2 : $0800 - $0FFF
lda PROC_PORT ; store ram setup 
sta PARAM1 
lda #%00110000 ; Switch out BASIC, KERNAL, CHAREN, IO 
sta PROC_PORT
loadPointer ZEROPAGE_POINTER_1, MAP_MEM ; source
loadPointer ZEROPAGE_POINTER_2, LEVEL_1_MAP ; destination
loadPointer ZEROPAGE_POINTER_1, CHAR_MEM 
loadPointer ZEROPAGE_POINTER_2, LEVEL_1_CHARS
 
jsr CopyChars 
lda PARAM1 ; restore ram setup 
sta PROC_PORT
Screen_Setup 
lda #COLOR_ORANGE 
sta VIC_BACKGROUND_COLOR 
lda #COLOR_ORANGE 
sta VIC_CHARSET_MULTICOLOR_1 
lda #COLOR_BROWN 
sta VIC_CHARSET_MULTICOLOR_2
 
loadPointer CURRENT_SCREEN,SCREEN1_MEM 
loadPointer CURRENT_BUFFER,SCREEN2_MEM
lda #$40 ; Use #$40 as the fill character on GameScreen 
jsr ClearScreen1 ; Clear both screens (double buffer) 
jsr ClearScreen2 
lda #32 ; Use #32 (space) as the fill character on 
jsr ClearScoreScreen ; Score Screen  
lda #COLOR_BLUE ; Fill entire visible color ram with COLOR_BLUE 
jsr ClearColorRam 

;  (Scroll Counters)
; Here we setup scroll counters for pixels scrolls and several other constants
lda #3   
sta SCROLL_COUNT_Y ; Vertical scroll 
lda #4 ; Start centered on character 
sta SCROLL_COUNT_X ; Horizontal scroll
lda #SCROLL_STOP ; direction = up 
sta SCROLL_DIRECTION ; Which way is the sprite moving in? 
lda #0 ; speed = 0 ; How fast is the screen moving? 
sta SCROLL_SPEED ; (not implemented yet)