From Swordfish Wiki

SwordfishUser: ROMBuffer

These modules enable you to implement a simple ROM buffer which you can read and write to. The 18F series implement a ROM block write strategy, together with block erase. This can make writing to ROM quite tricky. The ROM module handles this for you and supports devices with 8 byte block writes and 64 byte erase blocks. You can set the size of the ROM buffer by adding more elements to ROMBuffer, which is located in the ROM table module (shown later).

The following program shows how it all works. Simply call BeginWrite() to initiate the write sequence, then call WriteByte() as many times as you need, up to a maximum ROMBufferSize - 1. ROMBufferSize is a ROM module public constant. Finally, call EndWrite() to terminate the write sequence.

You data will now be stored in device ROM, which can be accessed by calling ReadByte() with an index value. The index value should range from 0 to a maximum of ROMBufferSize - 1.

// import modules...
Include "usart.bas"
Include "convert.bas"
Include "ROM.bas"

// local variables...
Dim Index, Value As Byte

// write values to ROM...
ROM.BeginWrite
For Index = 0 To ROMBufferSize - 1
   ROM.WriteByte(Index)
Next
ROM.EndWrite

// read them back...
SetBaudrate(br9600)
For Index = 0 To ROMBufferSize - 1
   Value = ROM.ReadByte(Index)
   Write("Value : ", DecToStr(Value),13,10)
Next  

ROM Module

Save this module in your UserLibrary folder and call it 'ROM.bas'...

Module ROM

// import the ROM table...
Include "ROMTable.bas"

// public constants...
Public Const 
   ROMBufferSize = SizeOf(ROMBuffer) - 64

// some local aliases...  
Dim
   EEPGD As EECON1.7,
   WR As EECON1.1,
   WREN As EECON1.2 

// local variables...
Dim
   FROMAddress As Word,
   FBlockAddress As Word
{
****************************************************************************
* Name    : Nop (PRIVATE)                                                  *
* Purpose : Inline NOP delay                                               *
****************************************************************************
} 
Inline Sub Nop()
   ASM
   Nop
   End ASM
End Sub
{
****************************************************************************
* Name    : TableRead (PRIVATE)                                            *
* Purpose : Inline TABLE read                                              *
****************************************************************************
} 
Inline Sub TableRead()
   ASM
   TBLRD*+
   End ASM
End Sub
{
****************************************************************************
* Name    : TableWrite (PRIVATE)                                           *
* Purpose : Inline TABLE write                                             *
****************************************************************************
} 
Inline Sub TableWrite()
   ASM
   TBLWT*+
   End ASM
End Sub
{
****************************************************************************
* Name    : Erase (PRIVATE)                                                *
* Purpose : Erase a 64 byte ROM block                                      *
****************************************************************************
} 
Sub Erase()
   EECON1 = $94
   EECON2 = $55
   EECON2 = $AA
   WR = 1
   Nop
   WREN = 0
End Sub
{
****************************************************************************
* Name    : WriteToROM (PRIVATE)                                           *
* Purpose : Write holding register values to ROM                           *
****************************************************************************
} 
Sub WriteToROM()
   EECON1 = $84
   EECON2 = $55
   EECON2 = $AA
   WR = 1
   Nop
   WREN = 0
End Sub
{
****************************************************************************
* Name    : ReadByte                                                       *
* Purpose : Read a single byte from ROM at pIndex                          *
****************************************************************************
} 
Public Function ReadByte(pIndex As Word) As TABLAT
   TABLEPTR = FROMAddress + pIndex
   EECON1 = 0
   EEPGD = 1
   TableRead
End Function
{
****************************************************************************
* Name    : WriteByte                                                      *
* Purpose : Write a byte value to ROM                                      *
****************************************************************************
}    
Public Sub WriteByte(pValue As TABLAT)
   TableWrite  
   If (TBLPTRL And $07) = 0 Then
      TABLEPTR = FBlockAddress
      WriteToROM
      Inc(FBlockAddress, 8)
      TABLEPTR = FBlockAddress
   EndIf        
End Sub
{
****************************************************************************
* Name    : BeginWrite                                                     *
* Purpose : Begin a write sequence to ROM                                  *
****************************************************************************
}    
Public Sub BeginWrite()
   Dim Range As Word  
   Range = FROMAddress + ROMBufferSize
   TABLEPTR = FROMAddress
   While TABLEPTR < Range
      Erase
      Inc(TABLEPTR, 64)
   Wend
   TABLEPTR = FROMAddress
   FBlockAddress = FROMAddress
End Sub
{
****************************************************************************
* Name    : EndWrite                                                       *
* Purpose : Terminate a write sequence to ROM                              *
****************************************************************************
}    
Public Inline Sub EndWrite()
   WriteToROM
End Sub
{
****************************************************************************
* Name    : Initialise                                                     *
* Purpose : Initialise ROM starting address, aligned to 64 byte boundary   *
****************************************************************************
} 
Sub Initialise()
   FROMAddress = (@ROMBuffer / 64 + 1) * 64
End Sub

// initialise the module...
Initialise

ROM Table Module

Save this module in your UserLibrary folder and call it 'ROMTable.bas'. Just add more zeros to the ROMBuffer sections marked with *** to increase the size of the buffer.

Module ROMTable

// the ROM buffer...
Public Const ROMBuffer() As Byte = 
(
   // *** 256 bytes of available ROM...
   0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
   0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,  
   0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
   0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
   0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
   0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
   0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
   0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
   // *** end ROM table

   // last 64 bytes are pack bytes to ensure erase block falls on
   // a valid 64 byte boundary...
   0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
   0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
)
Retrieved from http://www.sfcompiler.co.uk/wiki/pmwiki.php?n=SwordfishUser.ROMBuffer
Page last modified on August 26, 2007, at 05:11 PM