#define Page_Erase PGM[2]=0x40; temp = ((unsigned char(*)(unsigned int, unsigned char))(PGM))
#define Program_Byte PGM[2]=0x20; temp = ((unsigned char(*)(unsigned int, unsigned char))(PGM))
//Array of opcode instructions of the Erase/Program function in the HCS08 family// A = data, X = Address.
volatile unsigned char PGM[35] = { 0xF7, // STA ,X Save the data byte into the address. 0xA6,0x00, // LDA cmd (Filled in before calling)0xC7,0x18,0x26, // STA _FCMD0x45,0x18,0x25, // LDHX @_FSTAT0xF6, // LDA ,X0xAA,0x80, // ORA #$800xF7, // STA ,X0x9D,0x9D,0x9D,0x9D, // NOP, NOP,NOP,NOP0xC6,0x18,0x25, // LDA _FSTAT0xA5,0x30, // BIT #$300x27,0x03, // BEQ *+5 (Label1)0xa6,0xff, // RTS
0x81,
// Label1:
0xC6,0x18,0x25, // LDA _FSTAT
0xa5,0x40, // BIT #$40
0x27,0xF9, // BEQ *-5 (Label)
0x81, // RTS
};
byte FlashErasePage(word page)
{
volatile unsigned char temp ;
byte im;
asm TPA; // get the flags
asm STA im // save them
asm SEI // clear the im bit
if (FSTAT&0x30){ //Check to see if FACCERR or FPVIOL is set
FSTAT = FSTAT | 0x30; //write a 1 to clear
}
temp = Page_Erase(page,0);
asm LDA im // get the flags back
asm TAP // restore the im bit.
return temp;
}
byte FlashProgramByte(word address, byte data)
{
volatile unsigned char temp;
byte im;
asm TPA;
asm STA im
asm SEI
if (FSTAT&0x30){ //Check to see if FACCERR or FPVIOL is set
FSTAT = FSTAT | 0x30; //write a 1 to clear
}
temp = Program_Byte(address, data);
asm LDA im
asm TAP
return temp;
}
Message Edited by JimDon on 2008-02-25 01:24 AM
Added p/n to subject.
include "mc9s08qg4.inc"cmd: EQU 0; dummyPGM_SEC: SECTION XDEF PGMPGM: STA ,X ; Save the data byte into the address. LDA #cmd ;(Filled in before calling) LDHX #FSTAT STA FCMD-FSTAT,X ; FCMD LDA ,X ORA #$80 STA ,X NOP NOP NOP NOP LDA ,X ; FSTAT BIT #$30 BEQ Label1 LDA #-1 ; needed? RTSLabel1: LDA ,X ; FSTAT BIT #$40 BEQ Label1 RTS
STA ,X NOP LDA #$30 BIT ,X ; FSTAT And, is there a reason (bug workaround, compatibility, etc.) for this: LDA ,X ORA #$80 STA ,X instead of this shorter version? (AFAIK, the remaining FSTAT bits are indifferent at this stage): LDA #$80 STA ,X I still find this version to use less RAM.
#define Page_Erase PGM[2]=0x40; ((void(*)(unsigned int, unsigned char))(PGM))
#define Program_Byte PGM[2]=0x20; ((void(*)(unsigned int, unsigned char))(PGM))
//Array of opcode instructions of the Erase/Program function in the HCS08 family
// A = data, X = Address.
volatile unsigned char PGM[18] = {
0xF7, // STA ,X Save the data byte into the address.
0xA6,0x00, // LDA cmd
0xC7,0x18,0x26, // STA _FCMD
0xA6,0x80, // LDA FCBEF bit
0xc7,0x18,0x25, // sta FSTAT
0x44, // lsra - one byte - longer delay than nop
0xc5,0x18,0x25, // Bit fstat
0x27,0xfb, // BEQ *-3
0x81 // RTS
};
byte FlashErasePage(word page)
{
byte im;
asm TPA // get that flags
asm STA im // save the flags
asm SEI // kill IM bit
if (FSTAT&0x30){ //Check to see if FACCERR is set
FSTAT = FSTAT | 0x30; //write a 1 to FACCERR to clear
}
Page_Erase(page,0);
asm LDA im // put the im bit bak
asm TAP
if (FSTAT&0x30){ //check to see if FACCERR or FVIOL are set
return 0xFF; //if so, error.
}
return 0;
}
byte FlashProgramByte(word address, byte data)
{
byte im;
asm TPA
asm STA im
asm SEI
if (FSTAT&0x30){
FSTAT = FSTAT | 0x30;
}
Program_Byte(address, data);
asm LDA im
asm TAP
if (FSTAT&0x30){ //check to see if FACCERR or FVIOL are set
return 0xFF; //if so, error.
}
return 0;
}
bigmac wrote:Why bother testing FSTAT - simply clear the flags. If they are already clear, nothing will happen.
0xF7, // STA ,X Save the data byte into the address. 0xA6,0x00, // LDA cmd 0xC7,0x18,0x26, // STA _FCMD 0xA6,0x80, // LDA FCBEF bit