NV-DIR
From CPCWiki - THE Amstrad CPC encyclopedia!
This source deals with the non volatile memory of the SYMBiFACE II and the CPC Booster. Compatible with the MAXAM assembler.
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