; CARD_HELPER_VARS_START defines the beginning of the $100 bytes set aside for system usage
def cvCardBank equ 0
def cvCardAddress equ 1 ; location of the current card's struct

LoadCardData:
LoadCardDataAsync: 
  ; first and foremost, clear the card init, update, and draw handles, so there's 
  ; no chance of trying to jump into code from a previous card.
  ld bc, Instructions
  ld hl, CARD_INIT
  ld [hl], c
  inc hl 
  ld [hl], b
  ld hl, CARD_UPDATE
  ld [hl], c
  inc hl 
  ld [hl], b
  ld hl, CARD_DRAW
  ld [hl], c
  inc hl 
  ld [hl], b
  
  ld a, [vSelectedCardIndex]
  ld [vPreviousCardIndex], a

  ld b, 0
  ld c, a ; load bc from a, the number of the card in the cards list
  ld hl, Cards + 1 ; skip the length prefix
  add hl, bc
  add hl, bc
  add hl, bc ; triple add bc entries are bank, addr, addr
  
  ld a, [hl+]
  ld [CARD_HELPER_VARS_START + cvCardBank], a 
  ld [rROMB0], a ; select the specified bank
  ; follow the pointer we're looking at, and write it to cvCardAddress
  ld a, [hl+]
  ld [CARD_HELPER_VARS_START + cvCardAddress], a 
  ld c, a
  ld a, [hl+]
  ld [CARD_HELPER_VARS_START + cvCardAddress + 1], a 
  ld b, a

  ld h, b
  ld l, c ; hl now contains the address of the card data.
  
  

  ; card struct starts with a sequence of length-prefixed strings in memory
  ; so when we're done writing one, hl will be correctly placed to read the next
  ; length-prefixed print doesn't require passing a length
  ; so all we have to set is the destination for each
  ld de, $9800 + 32*11 + 10
  call PrintString
  ld de, $9800 + 32*12 + 10
  call PrintString
  ld de, $9800 + 32*14 + 10
  call PrintString
  ld de, $9800 + 32*15 + 10
  call PrintString
  ld de, $9800 + 32*16 + 10
  call PrintString
  
  ; hl now contains the address after all the strings.
  ; [hl+] and [hl+] read the length first, into bc
  ld a, [hl+]
  ld c, a
  ld a, [hl+]
  ld b, a ; bc has length
  ld a, [hl+]
  ld e, a
  ld a, [hl+]
  ld d, a ; de has source of tile range copy
  
  ld h, d 
  ld l, e  ; source
  ld de, $9800 + 32 + 1 ; destination
  ld b, 16 ; height
  ld c, 8 ; width
  
  call CopyTilesToMap

  ld a, [CARD_HELPER_VARS_START + cvCardAddress]
  ld l, a 
  ld a, [CARD_HELPER_VARS_START + cvCardAddress + 1]
  ld h, a ; hl now contains the address of the card data.
  
  ld b, 0
  ld c, Card_Offset_keytiles ; jump straight to keytiles length and location!
  add hl, bc
  
  ld a, [hl+]
  ld c, a
  ld a, [hl+]
  ld b, a ; bc has length of tile data
  ld a, [hl+]
  ld e, a
  ld a, [hl+]
  ld d, a ; de has source of tile range copy

  ld h, d
  ld l, e ; hl takes the source

  ld de, $9000 + VARIABLE_TILES_START*$10 ; always load tile data into the same spot in vram
  call CopyRange
  
  
  ld a, [CARD_HELPER_VARS_START + cvCardAddress]
  ld l, a 
  ld a, [CARD_HELPER_VARS_START + cvCardAddress + 1]
  ld h, a ; hl now contains the address of the card data.
  
  ld b, 0
  ld c, Card_Offset_spritetiles ; jump straight to sprite tiles length and location!
  add hl, bc
  
  ld a, [hl+]
  ld c, a
  ld a, [hl+]
  ld b, a ; bc has length of tile data
  ld a, [hl+]
  ld e, a
  ld a, [hl+]
  ld d, a ; de has source of tile range copy

  ld h, d
  ld l, e ; hl takes the source

  ld de, $8000 ; sprite tiles get loaded into the bottom of vram 
  call CopyRange
  
  ld a, [CARD_HELPER_VARS_START + cvCardAddress]
  ld l, a 
  ld a, [CARD_HELPER_VARS_START + cvCardAddress + 1]
  ld h, a ; hl now contains the address of the card data.
  
  ld b, 0
  ld c, Card_Offset_functions ; jump straight to function handles
  add hl, bc ; hl now points to the card functions
  
  ld a, [hl+]
  ld [CARD_INIT], a 
  ld a, [hl+]
  ld [CARD_INIT+1], a 
  ld a, [hl+]
  ld [CARD_UPDATE], a 
  ld a, [hl+]
  ld [CARD_UPDATE+1], a 
  ld a, [hl+]
  ld [CARD_DRAW], a 
  ld a, [hl+]
  ld [CARD_DRAW+1], a 
  
  call CardInit
  
  ret

CardInit:
  ld a, [rLCDC]
  and a, %1111_1011
  ld [rLCDC], a 
  
  ld hl, ZEROES
  ld de, MY_OAM
  ld bc, $100
  call CopyRange
  
  call CARD_INIT - 1
  ret 
  
CardUpdate:
  call CARD_UPDATE - 1
  ret

CardDraw:
  call CARD_DRAW - 1
  ret  
  

IncrementTimer:
  ; hl is the location in memory of a timer
  ; squashes a and de
  ; uses the value from rDELTAT
  ld d, h 
  ld e, l 
  inc de
  ld a, [rDELTAT]
  add a, [hl]
  ld [hl], a 
  ld h, d 
  ld l, e 
  ld a, [hl] 
  adc a, 0 
  ld [hl], a 
  dec hl 
  ret