; ***************************************************************************
; copyright   : (C) 2025 by Martin Preuss
; email       : martin@libchipcard.de
;
; ***************************************************************************
; * This file is part of the project "AqHome".                              *
; * Please see toplevel file COPYING of that project for license details.   *
; ***************************************************************************


.equ FLASH_PAGESIZE = (PAGESIZE*2*4)


; ***************************************************************************
; data

.dseg

  flashPageStart:   .byte 2
  flashPageBuffer:  .byte FLASH_PAGESIZE



; ***************************************************************************
; code

.cseg



; ---------------------------------------------------------------------------
; flash4pWritePage
;
; Interrupts must be disabled!
;
; @clobbers r0, r1, r20, r24, r25, X, Z

flash4pWritePage:
  ; copy from SDRAM into MCUs temporary page buffer
  lds zl, flashPageStart
  lds zh, flashPageStart+1
  ldi xl, LOW(flashPageBuffer)
  ldi xh, HIGH(flashPageBuffer)
  ldi r25, 4                                  ; handle 4 pages at a time
flash4pWritePage_loop1:
    ldi r24, LOW(PAGESIZE)
flash4pWritePage_loop2:
      ld r0, X+                               ; read source data from buffer (low)
      ld r1, X+                               ; read source data from buffer (high)
      ldi r20, (1<<SPMEN)                     ; enable next SPM, write R1:R0 into temp page buffer
      rcall flashDoSpm                        ; (R16)
      adiw zh:zl, 2
      dec r24
    brne flash4pWritePage_loop2

    push zl
      push zh
        subi zl, LOW(PAGESIZE*2)              ; point back to begin of page
        sbci zh, HIGH(PAGESIZE*2)
        ; transfer data from temporary page buffer into FLASH memory
        ldi r20, (1<<PGWRT) + (1<<SPMEN)      ; enable next SPM, write page (R1/R0 ignored)
        rcall flashDoSpm                      ; (R16)
      pop zh
    pop zl
    dec r25
  brne flash4pWritePage_loop1  
  ret
; @end




.equ flashWritePage = flash4pWritePage


