;******************************************************************************* ;* Subroutine: WriteEE (with compare) and WriteEE_CONFIG (no compare) ;* Programmer: Tony Papadimitriou <tonyp@acm.org> ;* Purpose : Self-writing EEPROM code using stack RAM temporarily ;* Language : Motorola/Freescale/NXP 68HC11 Assembly Language (aspisys.com/ASM11) ;* Status : FREEWARE Copyright (c) 2020 by Tony Papadimitriou <tonyp@acm.org> ;* History : 02.04.19 v1.00 Original ;* : 02.04.21 Protect X from being destroyed ;* : 02.04.22 Shortened RAM code to absolute minimum ;* : 02.04.23 Changed RAM code for 811E2 compatibility ;* : 03.05.23 v1.01 Made smarter: A single call erases and writes ;* : depending on new and current values ;* : 11.01.31 Changed some exits to :AnRTS ;******************************************************************************* #ifmain ;----------------------------------------------------------------------- #ListOff #Uses mcu.inc #ListOn #ROM Start proc lds #STACKTOP clr BPROT ;needed to allow writes to EEPROM clrb ;(for simulator only) clry ; -//- ;Example calling sequences ldx #$FF00 lda #$AA bsr WriteEE ;use WriteEE_CONFIG for CONFIG register bra * @vector Vreset,Start ;to run the demo code end :s19crc #ROM #endif ;------------------------------------------------------------------------ ;******************************************************************************* ; Action: Subroutine that does the actual write/erase to EEPROM is first ; : copied to RAM and then executed from there until the EEPROM ; : write/erase cycle finishes. ; Input : X -> EEPROM location to write ; : A = value to write (if A=$FF, an erase will be performed) ; : B = $02 to program, $16 to erase ; Output: All registers except CCR are preserved by parent procedure ; Notes : Uses 18 bytes of stack RAM ?RAM_Code proc stb PPROG sta ,x ;for erase, any value will do inc PPROG ;Turn on programming voltage ldx #DELAY@@ ;10 msec delay constant #Cycles Loop@@ dex bne Loop@@ DELAY@@ equ 10*BUS_KHZ/:cycles clr PPROG ;Turn off programming voltage rts #size ?RAM_Code ;number of RAM bytes needed ;******************************************************************************* ; Action: Write to EEPROM if value is different from current value ; : (not good for CONFIG but good for anything else) preventing ; : unnecessary wearout of EEPROM. ; Input : X -> EEPROM location to write ; : A = value to write ; Output: All registers except CCR are preserved ; Notes : Call once with actual value, erase is automatic if required ; : Interrupts must be disabled before calling, if so required. WriteEE proc cmpa ,x ;is it the same as written? beq Done@@ ;yes, no need to write again ; bra WriteEE_CONFIG ;no, so we need to write Done@@ equ :AnRTS ;******************************************************************************* ; Action: Write to EEPROM without comparing current value ; : This is good mostly for changing the CONFIG register, ; : prefer WriteEE (above) for writing anything else. ; Input : X -> EEPROM location to write ; : A = value to write ; Output: All registers except CCR are preserved ; Notes : Call once with actual value, erase is automatic if required ; : Interrupts must be disabled before calling, if so required. WriteEE_CONFIG proc push ;save all registers ldy #?RAM_Code+::?RAM_Code-1 ;routine to stack Loop@@ ldb ,y ;create a RAM copy by pshb ; pushing each byte to the dey ; stack in reverse order cmpy #?RAM_Code ; so it turns out correctly bhs Loop@@ ;do for all bytes tsy ;Y -> RAM copy of routine ldb #$16 ;to erase a byte in EEPROM cmpa #$FF ;Are we erasing instead of writing? beq DoIt@@ pshx ;protect write address jsr ,y ;first erase (v1.01) when programming pulx ;restore write address ldb #$02 ;to program a byte to EEPROM DoIt@@ jsr ,y ;call RAM routine givex #::?RAM_Code ;de-allocate stacked routine pull ;restore all registers rts