14,348 bytes added,
21:32, 27 September 2009 This source deals with the non volatile memory of the [[SYMBiFACE II]] and the [[CPC Booster]]. Compatible with the [[MAXAM]] assembler.
<pre>
org &9000 ; File ----> NV-DIR.MAX
nolist ; Version -> 1.0 (30.12.2006) english!
; Lines ---> 477
;Part of the FutureView IV release, please look there for further informations.
;This file containt the source code to calculate a checksum over the DIRectory
;of the nvRAM of the Symbiface and/or the EEPROM of the CPC-Booster Plus.
;This source code is a part of the FutureView IV.
;-----------------;
; All code by TFM ;
; of Future-Soft ;
;-----------------;
; This code was ;
; tested. Please ;
; copy this file ;
; as it is!!! TFM ;
;-----------------;
;--- --- --- Example how to work with the EEPROM o.t. CPC Booster+ --- --- ---;
LD HL,EE_BUFFER ;Space for the &200 Bytes EEPROM of the CPC Booster+
CALL READ_EE ;Read &200 Bytes EEPROM from CB (CPC Booster+)
LD HL,EE_BUFFER ;Pointer to &200 Bytes of EEPROM buffer
CALL TST_CHCK_EE ;Test if Checksum of the EEPROM is correct
JP Z,EE_DIR_OK ;Go there if Checksum is correct!
;Checksum is NOT correct!
LD HL,EE_BUFFER ;Pointer to &200 Bytes EEPROM buffer
CALL INIT_DIR_EE ;Initialize DIRectory of the EEPROM
;There is NO need to create/install a NEW checksum,
;because the checksum and DIR are all zero bytes.
JP EE_EXIT ;Write new DIR and DATA into the CP EEPROM, then Exit!
;Delete last line of code, if you want to manage newly installed DIR/DATA.
;EEPROM Checksum was tested correct!
EE_DIR_OK
;NOW you can MANAGE your CB EEPROM in different ways...
;1. - READ an Entry (of 16 Bytes)
;(remove semicolons of the following 5 lines to use this function)
;
; LD A,&09 ;A contains the Product-ID (range between &01 and &FE).
; LD HL,EE_BUFFER ;Pointer to &200 Bytes EEPROM buffer (source)
; LD DE,ENTRY_BUF ;16 Byte buffer for ONE 16 Byte Entry of the CB EEPROM
; CALL RED_ENT_EE ;Read 16 Byte Entry from CB EEPROM with the ID stored in A
;... or ...
;2. - WRITE an Entry (of 16 Bytes)
;(remove semicolons of the following 8 lines to use this function)
;
; LD A,&12 ;A contains YOUR Product-ID (range between &01 and &FE).
; LD HL,EE_BUFFER ;Pointer to &200 Bytes EEPROM target buffer
; LD DE,ENTRY_BUF ;source buffer of ONE 16 Byte Entry for the CB EEPROM
; CALL WRT_ENT_EE ;Write 16 Byte Entry to CB EEPROM (ID prev. stored in A)
;
; LD HL,EE_BUFFER ;Pointer to &200 Bytes EEPROM buffer
; CALL MAKE_CHK_EE ;Create and install NEW checksum after WRITE
;... or ...
;3. - ERASE an Entry (of 16 Bytes)
;(remove semicolons of the following 7 lines to use this function)
;
; LD A,&02 ;A contains YOUR Product-ID (range between &01 and &FE).
; LD HL,EE_BUFFER ;Pointer to &200 Bytes EEPROM buffer
; CALL ERA_ENT_EE ;Erase ONE Entry (16 Bytes) in the DIR of the CB EEPROM
;
; LD HL,EE_BUFFER ;Pointer to &200 Bytes EEPROM buffer
; CALL MAKE_CHK_EE ;Create and install NEW checksum after ERASE
;Finally you have to write back Checksum and Data from RAM to the CB EEPROM.
EE_EXIT LD HL,EE_BUFFER ;Pointer to &200 Bytes EEPROM buffer
CALL WRITE_EE ;Write RAM to EEPROM of CB
RET
;--- --- --- Example how to work with the nvRAM of the Symbiface --- --- --- ;
LD HL,NV_BUFFER ;Space for &72 Bytes of the &80 Bytes nvRAM of the Symbiface
CALL READ_NV ;Read &72 Bytes nvRAM from SF (without clock data)
LD HL,NV_BUFFER ;Pointer to &72 Bytes of nvRAM buffer
CALL TST_CHCK_NV ;Test if Checksum of the nvRAM is correct
JP Z,NV_DIR_OK ;Go there if Checksum is correct!
;Checksum is NOT correct!
LD HL,NV_BUFFER ;Pointer to &72 Bytes nvRAM buffer
CALL INIT_DIR_NV ;Initialize DIRectory of the nvRAM
LD HL,NV_BUFFER ;Pointer to &72 Bytes nvRAM buffer
CALL MAKE_CHK_NV ;Create and install NEW checksum
JP NV_EXIT ;Write new DIR and DATA into the SF nvRAM, then Exit!
;Delete last line of code, if you want to manage newly installed DIR/DATA.
;nvRAM Checksum was tested correct!
NV_DIR_OK
;NOW you can MANAGE your SF nvRAM in different ways...
;1. - READ an Entry (of 16 Bytes)
;(remove semicolons of the following 5 lines to use this function)
;
; LD A,&09 ;A contains the Product-ID (range between &01 and &FE).
; LD HL,NV_BUFFER ;Pointer to &72 Bytes nvRAM buffer (source)
; LD DE,ENTRY_BUF ;16 Byte buffer for ONE 16 Byte Entry of the SF nvRAM
; CALL RED_ENT_NV ;Read 16 Byte Entry from SF nvRAM with the ID stored in A
;... or ...
;2. - WRITE an Entry (of 16 Bytes)
;(remove semicolons of the following 8 lines to use this function)
;
; LD A,&12 ;A contains YOUR Product-ID (range between &01 and &FE).
; LD HL,NV_BUFFER ;Pointer to &72 Bytes nvRAM target buffer
; LD DE,ENTRY_BUF ;source buffer of ONE 16 Byte Entry for the SF nvRAM
; CALL WRT_ENT_NV ;Write 16 Byte Entry to SF nvRAM (ID prev. stored in A)
;
; LD HL,NV_BUFFER ;Pointer to &72 Bytes nvRAM buffer
; CALL MAKE_CHK_NV ;Create and install NEW checksum after WRITE
;... or ...
;3. - ERASE an Entry (of 16 Bytes)
;(remove semicolons of the following 7 lines to use this function)
;
; LD A,&02 ;A contains YOUR Product-ID (range between &01 and &FE).
; LD HL,NV_BUFFER ;Pointer to &72 Bytes nvRAM buffer
; CALL ERA_ENT_NV ;Erase ONE Entry (16 Bytes) in the DIR of the SF nvRAM
;
; LD HL,NV_BUFFER ;Pointer to &72 Bytes nvRAM buffer
; CALL MAKE_CHK_NV ;Create and install NEW checksum after ERASE
;Finally you have to write back Checksum and Data from RAM to the SF nvRAM.
NV_EXIT LD HL,NV_BUFFER ;Pointer to &72 Bytes nvRAM buffer
CALL WRITE_NV ;Write RAM to nvRAM of SF (without clock)
RET
; --- --- --- Subroutines for EEPROM management / CPC Booster+ --- --- --- ;
;Read &0200 Bytes CPC Booster+ EEPROM (DIR and Data)
;
;In;
;HL = Buffer for &200 Bytes
;
;Out;
;&200 Bytes (Checksum, Data) have been read to old HL
;
;(Changed Registers AF, BC, HL)
READ_EE XOR A,A:LD BC,&FF0C:OUT (C),A:INC C:OUT (C),A
READ_E1 INC C:INI:INC B:DEC C:INC A:OUT (C),A:JR NZ,READ_E1
INC A:DEC C:OUT (C),A:INC C:DEC A
READ_E2 INC C:INI:INC B:DEC C:INC A:OUT (C),A:JR NZ,READ_E2:RET
;Test Checksum of EEPROM (CPC Booster+)
;
;In;
;HL = Buffer-Start of &200 Bytes EEPROM (previously read with READ_EE)
;
;Out;
;Zero-Flag is SET if Checksum is correct, else Zero is cleared.
;
;(Changed Registers AF, BC, DE, HL)
TST_CHCK_EE LD E,(HL):INC HL:LD D,(HL):INC HL:PUSH DE ;old checksum
LD A,&0F:LD DE,&0000
TST_CHCK_EL LD C,(HL):INC HL:LD B,(HL):INC HL:EX DE,HL:ADD HL,BC:EX DE,HL
DEC A:JR NZ,TST_CHCK_EL:POP HL:XOR A,A:SBC HL,DE:RET
;Initialize DIRectory of the EEPROM
;
;In;
;HL = Buffer for &200 Bytes EEPROM (previously read with READ_EE)
;
;(Changed Registers AF, BC, DE, HL)
INIT_DIR_EE XOR A,A:LD (HL),A:LD D,H:LD E,L:INC DE:LD BC,&001F:LDIR:RET
;Calculate and Install new Checksum for CB EEPROM buffer
;
;In;
;HL = Start of buffer of &200 Bytes EEPROM (previously read with READ_EE)
;
;(Changed Registers AF, BC, DE, HL)
MAKE_CHK_EE PUSH HL:INC HL:INC HL:LD A,&0F:LD DE,&0000
MAKE_CHK_EL LD C,(HL):INC HL:LD B,(HL):INC HL:EX DE,HL:ADD HL,BC:EX DE,HL
DEC A:JR NZ,MAKE_CHK_EL:POP HL:LD (HL),E:INC HL:LD (HL),D:RET
;Read 16 Byte Entry from CB EEPROM with given Product-ID
;
;In;
; A = contains the Product-ID (in the range between &01 and &FE).
;HL = Pointer to &200 Bytes EEPROM source buffer (must have been read before!)
;DE = Pointer to 16 Byte target buffer for ONE 16 Byte entry of the CB EEPROM
;
;Out;
;Zero-Flag set ------> Entry was found and copied to DE (16 Bytes)
;Zero-Flag cleared --> An Entry with that Product-ID was NOT found!
;
;(Changed Registers AF, BC, DE, HL)
RED_ENT_EE PUSH HL:INC HL:INC HL:LD B,&1E
GLP_ENT_EE CP A,(HL):JR Z,GEX_ENT_EE:INC HL:DJNZ GLP_ENT_EE:POP HL:RET
GEX_ENT_EE LD A,&20:SUB A,B:ADD A,A:ADD A,A:ADD A,A ;(DIR Nr. 2..31)*8
LD B,&00:LD C,A:POP HL:ADD HL,BC:ADD HL,BC:LD BC,&0010:LDIR:XOR A,A:RET
;Write 16 Byte Entry to CB EEPROM buffer (identified through given Product-ID)
;(Routine OVERWRITES old entry with the SAME Product-ID)
;
;In;
; A = YOUR Product-ID (range between &01 and &FE).
;HL = Pointer to &200 Bytes EEPROM target buffer (must have been read before!)
;DE = Pointer to source buffer of ONE 16 Byte Entry of the CB EEPROM
;
;Out;
;Zero-Flag set ------> Entry was written to CB EEPROM buffer (16 Bytes)
;Zero-Flag cleared --> NO free Entry anymore!
;
;(Changed Registers AF, BC, DE, HL)
WRT_ENT_EE PUSH HL:INC HL:INC HL:LD B,&1E
WLP_ENT_EE CP A,(HL):JR Z,WEX_ENT_EE:INC HL:DJNZ WLP_ENT_EE
LD BC,&FFE2:ADD HL,BC:LD B,&1E:LD C,A:XOR A,A
WL2_ENT_EE CP A,(HL):JR Z,WEY_ENT_EE:INC HL:DJNZ WL2_ENT_EE:POP HL:RET
WEY_ENT_EE LD (HL),C
WEX_ENT_EE LD A,&20:SUB A,B:ADD A,A:ADD A,A:ADD A,A ;(DIR Nr. 2..31)*8
LD B,&00:LD C,A:POP HL:ADD HL,BC:ADD HL,BC
EX DE,HL:LD BC,&0010:LDIR:XOR A,A:RET
;Erase ONE Entry in the DIR of the CB EEPROM (named by given Product-ID)
;
;In;
; A = contains the Product-ID (in the range between &01 and &FE).
;HL = Pointer to &200 Bytes EEPROM buffer (must have been read before!)
;
;Out;
;Zero-Flag set ------> Entry was found and ERASED in DIR
;Zero-Flag cleared --> An Entry with the given Product-ID was NOT found!
;
;(Changed Registers AF, BC, HL)
ERA_ENT_EE INC HL:INC HL:LD B,&1E
ELP_ENT_EE CP A,(HL):JR Z,EEX_ENT_EE:INC HL:DJNZ ELP_ENT_EE:RET
EEX_ENT_EE XOR A,A:LD (HL),A:RET
;Write RAM buffer back to CPC Booster+ EEPROM (DIR and Data)
;
;In;
;HL = Pointer to Buffer of &200 Bytes in RAM
;
;Out;
;&200 Bytes (Checksum, Data) have been written from RAM to EEPROM(CPC Booster+)
;
;(Changed Registers AF, BC, DE, HL)
WRITE_EE LD DE,&0001:LD BC,&FF0C:OUT (C),D:INC C:OUT (C),D
WRITE_E1 INC C:LD A,(HL):OUT (C),A:INC HL:DEC C
INC D:OUT (C),D:JR NZ,WRITE_E1
DEC C:OUT (C),E:INC C
WRITE_E2 INC C:LD A,(HL):OUT (C),A:INC HL:DEC C
INC D:OUT (C),D:JR NZ,WRITE_E2:RET
; --- --- --- Subroutines for the nvRAM management / Symbiface --- --- --- ;
;Read Symbiface nvRAM (DIR and Data)
;(read nvRAM-Bytes &000E-&007F, no clock data)
;
;In;
;HL = Buffer for &72 Bytes
;
;Out;
;&72 Bytes (Checksum, Data) have been read to old HL
;
;(Changed Registers AF, BC, HL)
READ_NV LD BC,&FD15:LD A,&0E
READ_NL OUT (C),A:DEC C:INI:INC B:INC C:INC A:OR A,A:JP P,READ_NL:RET
;Test Checksum of nvRAM (Symbiface)
;
;In;
;HL = Buffer-Start of &72 Bytes nvRAM (previously read with READ_NV)
;
;Out;
;Zero-Flag is SET if Checksum is correct, else Zero is cleared.
;
;(Changed Registers AF, BC, DE, HL)
TST_CHCK_NV LD E,(HL):INC HL:LD D,(HL):LD BC,&0061:ADD HL,BC:PUSH DE ;old checksum
LD A,&08:LD DE,&0000
TST_CHCK_NL LD C,(HL):INC HL:LD B,(HL):INC HL:EX DE,HL:ADD HL,BC:EX DE,HL
DEC A:JR NZ,TST_CHCK_NL:POP HL:XOR A,A:SBC HL,DE:RET
;Initialize DIRectory of the nvRAM
;(protect Clock Data [nvRAM-Bytes &00-&0D])
;(protect DIRectory [nvRAM-Bytes &70-&77])
;(set Millenium [nvRAM-Byte &32] to &14)
;
;In;
;HL = Buffer for &72 Bytes nvRAM (previously read with READ_NV)
;
;(Changed Registers AF, BC, DE, HL)
INIT_DIR_NV XOR A,A:LD (HL),A:LD D,H:LD E,L:INC DE:LD BC,&0071:LDIR
LD DE,&FFF8:ADD HL,DE:LD (HL),D:LD E,&F9:ADD HL,DE:LD (HL),D
LD DE,&FFC2:ADD HL,DE:LD A,&14:LD (HL),A:RET
;Calculate and Install new Checksum for SF nvRAM buffer
;
;In;
;HL = Start of buffer of &72 Bytes nvRAM (previously read with READ_NV)
;
;(Changed Registers AF, BC, DE, HL)
MAKE_CHK_NV PUSH HL:LD BC,&0062:ADD HL,BC
LD A,&08:LD DE,&0000
MAKE_CHCK_NL LD C,(HL):INC HL:LD B,(HL):INC HL:EX DE,HL:ADD HL,BC:EX DE,HL
DEC A:JR NZ,MAKE_CHCK_NL:POP HL:LD (HL),E:INC HL:LD (HL),D:RET
;Read 16 Byte Entry from SF nvRAM with given Product-ID
;
;In;
; A = contains the Product-ID (in the range between &01 and &FE).
;HL = Pointer to &72 Bytes nvRAM source buffer (must have been read before!)
;DE = Pointer to 16 Byte target buffer for ONE 16 Byte entry of the SF nvRAM
;
;Out;
;Zero-Flag set ------> Entry was found and copied to DE (16 Bytes)
;Zero-Flag cleared --> An Entry with that Product-ID was NOT found!
;
;(Changed Registers AF, BC, DE, HL)
RED_ENT_NV LD BC,&0063:PUSH HL:ADD HL,BC:LD B,&06
GLP_ENT_NV CP A,(HL):JR Z,GEX_ENT_NV:INC HL:DJNZ GLP_ENT_NV:POP HL:RET
GEX_ENT_NV LD A,&06:SUB A,B:ADD A,A:ADD A,A:ADD A,A:ADD A,A ;(DIR Nr.0-5)*16
INC A:INC A:LD B,&00:LD C,A:POP HL:ADD HL,BC:LD BC,&0010:LDIR:XOR A,A:RET
;Write 16 Byte Entry to SF nvRAM buffer (identified through given Product-ID)
;(Routine OVERWRITES old entry with the SAME Product-ID)
;
;In;
; A = YOUR Product-ID (range between &01 and &FE).
;HL = Pointer to &72 Bytes nvRAM target buffer (must have been read before!)
;DE = Pointer to source buffer of ONE 16 Byte Entry of the SF nvRAM
;
;Out;
;Zero-Flag set ------> Entry was written to SF nvRAM buffer (16 Bytes)
;Zero-Flag cleared --> NO free Entry anymore!
;
;(Changed Registers AF, BC, DE, HL)
WRT_ENT_NV LD BC,&0063:PUSH HL:ADD HL,BC:LD B,&06
WLP_ENT_NV CP A,(HL):JR Z,WEX_ENT_NV:INC HL:DJNZ WLP_ENT_NV
LD BC,&FFFA:ADD HL,BC:LD B,&06:LD C,A:XOR A,A
WL2_ENT_NV CP A,(HL):JR Z,WEY_ENT_NV:INC HL:DJNZ WL2_ENT_NV:POP HL:RET
WEY_ENT_NV LD (HL),C
WEX_ENT_NV LD A,&06:SUB A,B:ADD A,A:ADD A,A:ADD A,A:ADD A,A ;(DIR Nr.0-5)*16
INC A:INC A:LD B,&00:LD C,A:POP HL
ADD HL,BC:EX DE,HL:LD BC,&0010:LDIR:XOR A,A:RET
;Erase ONE Entry in the DIR of the SF nvRAM (named by given Product-ID)
;
;In;
; A = contains the Product-ID (in the range between &01 and &FE).
;HL = Pointer to &72 Bytes nvRAM buffer (must have been read before!)
;
;Out;
;Zero-Flag set ------> Entry was found and ERASED in DIR
;Zero-Flag cleared --> An Entry with the given Product-ID was NOT found!
;
;(Changed Registers AF, BC, HL)
ERA_ENT_NV LD BC,&0063:ADD HL,BC:LD B,&06
ELP_ENT_NV CP A,(HL):JR Z,EEX_ENT_NV:INC HL:DJNZ ELP_ENT_NV:RET
EEX_ENT_NV XOR A,A:LD (HL),A:RET
;Write RAM buffer back to Symbiface nvRAM (DIR and Data)
;
;In;
;HL = Buffer of &72 Bytes in RAM
;
;Out;
;&72 Bytes (Checksum, Data) have been written from RAM to nvRAM (Symbiface)
;
;(Changed Registers AF, BC, HL)
WRITE_NV LD BC,&FD15:LD A,&0E
WRITE_NL OUT (C),A:DEC C:INC B:OUTI:INC C:INC A:OR A,A:JP P,WRITE_NL:RET
; --- --- --- Buffers / Space for Data --- --- --- ;
EE_BUFFER DS &0200,&00 ;&200 Byte buffer for CPC Booster+ EEPROM
NV_BUFFER DS &72,&00 ;&72 Byte buffer for Symbiface nvRAM
ENTRY_BUF DS &10,&00 ;16 Byte buffer for ONE 16 Byte Entry (CB or SF)
LIST
DUMP
</pre>
[[Category:Source code]]