Issues trying to use the Memory Access module (SOLVED)

Coding and general discussion relating to the compiler

Moderators: David Barker, Jerry Messina

Post Reply
bradsprojects
Posts: 28
Joined: Thu Nov 29, 2012 12:29 am
Location: Australia

Issues trying to use the Memory Access module (SOLVED)

Post by bradsprojects » Sun May 27, 2018 5:15 am

Hi everyone,

I'm working on a project where I would like to be able to store some information (in 256 byte blocks) into program memory, and then be able to recall this data later on. I have been experimenting with the MemoryAccess.bas module to achieve this goal. It seems to write to program memory just fine - however I cannot get it to read from program memory and I have tried various methods to try and achieve this.

First up, here's the 'MemoryAccess.bas" module that I am using:

Code: Select all

{
*****************************************************************************
*  Name    : MemoryAccess.BAS                                               *
*  Author  : Tim Box                                                        *
*  Notice  : Copyright (c) 2007 TJB Systems Ltd                             *
*          : All Rights Reserved                                            *
*  Date    : 03/08/2007                                                     *
*  Version : 1.0                                                            *
*  Notes   :                                                                *
*          :                                                                *
*****************************************************************************
}


Module MemoryAccess

// module option - just put some values in here for testing...
    #option ROM_BLOCK_SIZE = 8
    #if Not (ROM_BLOCK_SIZE in (8, 16, 32, 64))
      #error ROM_BLOCK_SIZE, "Invalid option. ROM_BLOCK_SIZE must be 8, 16 or whatever..."
    #endif

// bring option into the program...
    Const 
        WriteBlockSize = ROM_BLOCK_SIZE - 1

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

// inline delay
    Inline Sub Delay()
      Asm
      GoTo $ + 2
      End Asm
    End Sub

// table read
    Inline Sub TableRead()
      Asm
      TBLRD*+
      End Asm
    End Sub

// table write
    Inline Sub TableWrite()
      Asm
      TBLWT*+
      End Asm
    End Sub

// Functions =======================

// read a byte from ROM  
    Public Function ReadByte (pAddress As TABLEPTR) As TABLAT
      EECON1 = 0
      EEPGD = 1
      TableRead
    End Function

// read a Word from ROM  
    Public Function ReadWord (pAddress As TABLEPTR) As Word
      EECON1 = 0
      EEPGD = 1
      TableRead
      result.Byte0 = TABLAT
      TableRead
      result.Byte1 = TABLAT
    End Function

// read a LongWord from ROM  
    Public Function ReadLongWord (pAddress As TABLEPTR) As LongWord
      EECON1 = 0
      EEPGD = 1
      TableRead
      result.Byte0 = TABLAT
      TableRead
      result.Byte1 = TABLAT
      TableRead
      result.Byte2 = TABLAT
      TableRead
      result.Byte3 = TABLAT
    End Function

// Subroutines ======================= 

// erase ROM block...
    Public Sub EraseBlock (pAddress As TABLEPTR)
      EECON1 = $94
      EECON2 = $55
      EECON2 = $AA
      WR = 1
      Delay
      WREN = 0
    End Sub

// close a write
    Public Sub CloseWrite()
      EECON1 = $84
      EECON2 = $55
      EECON2 = $AA
      WR = 1
      Delay
      WREN = 0
    End Sub

{
****************************************************************************
* Name    : WriteItem                                                      *
* Purpose : Write a byte to program memory                                 *
****************************************************************************
}
    Public Sub WriteItem (pValue As TABLAT)
      TableWrite       
      If (WriteBlockSize And Byte(TBLPTRL+1)) = 0 Then
         CloseWrite
      EndIf
      Inc(TABLEPTR)
    End Sub

{
****************************************************************************
* Name    : WriteAt (OVERLOAD)                                             *
* Purpose : Write a Byte at an address from program memory                 *
****************************************************************************
}    
    Public Inline Sub WriteAt (pAddress As TABLEPTR, pValue As TABLAT)
      WriteItem(TABLAT)
    End Sub


{
****************************************************************************
* Name    : WriteAt (OVERLOAD)                                             *
* Purpose : Write a Word at an address from Program memory                 *
****************************************************************************
}    
    Public Sub WriteAt (pAddress As TABLEPTR, pValue As Word)      
      WriteItem(pValue.byte0)
      WriteItem(pValue.byte1)
    End Sub

{
****************************************************************************
* Name    : WriteAt (OVERLOAD)                                             *
* Purpose : Write a LongWord at an address from Program memory             *
****************************************************************************
}
    Public Sub WriteAt (pAddress As TABLEPTR, pValue As LongWord)
      WriteItem(pValue.byte0)
      WriteItem(pValue.byte1)
      WriteItem(pValue.byte2)
      WriteItem(pValue.byte3)
    End Sub 
Secondly, here's my code for writing my 256 bytes from a variable array, into program memory (this code works fine), you will notice that I am erasing four, 64byte blocks of program memory before commencing the write. When it does actually write to program memory - it reads one byte at a time from the RAM() array which holds 256 bytes:

Code: Select all

Sub WriteToProgramMemory(BlockToSave As Word)
    Dim Address As Word
    Dim MyIndex As Byte
    
    Address = $1300 + BlockToSave
    EraseBlock(Address)
    eraseblock(Address + 64)
    eraseblock(Address + 128)
    eraseblock(Address + 192)
    
    For MyIndex = 0 To 255 
        WriteAt(Address + MyIndex, RAM(MyIndex)) 
    Next 
    CloseWrite
End Sub
The one thing I have not been able to get working is reading data from program memory and then storing it back into my RAM() array. Here is the code at the moment:

Code: Select all

Sub ReadFromProgramMemory(BlockToRead As Word)
    Dim Address As Word
    Dim MyIndex As Byte
    
    Address = $1300 + BlockToRead
    For MyIndex = 0 To 255
        RAM(MyIndex) = ReadByte(address + MyIndex)
    Next
End Sub
Unfortunately, the code above simply fills the RAM() array with 'FF' for every single byte. By the way - the 'BlockToRead' variable will be 0 or a multiple of 256 such as 512, 768, 1024 and so forth...

Is there anyone that can help point me in the right direction as to why I am unable to read from program memory?
Last edited by bradsprojects on Mon May 28, 2018 11:25 pm, edited 1 time in total.


bradsprojects
Posts: 28
Joined: Thu Nov 29, 2012 12:29 am
Location: Australia

Re: Issues trying to use the Memory Access module to read da

Post by bradsprojects » Sun May 27, 2018 8:22 am

Thanks for the link, i'll have a good read through although I'll just ask a quick question - is that stored in program memory?

All up I will need 2kbytes for all the data I will be storing (8 blocks of 256bytes)

Jerry Messina
Swordfish Developer
Posts: 1469
Joined: Fri Jan 30, 2009 6:27 pm
Location: US

Re: Issues trying to use the Memory Access module to read da

Post by Jerry Messina » Sun May 27, 2018 9:31 am

is that stored in program memory?
Yes it is, but both of those modules have a few issues.

One is that they both assume a certain page write/erase size that may not match the device you're using.
They also don't disable and enable interrupts during the write/erase.

Using a fixed buffer at $1300 with MemoryAccess places the buffer in a location that may get used and overwritten by your program code,
and ROMBuffer declares it in such a way that the buffer may move as you make changes to your program.

What device are you using?

bradsprojects
Posts: 28
Joined: Thu Nov 29, 2012 12:29 am
Location: Australia

Re: Issues trying to use the Memory Access module to read da

Post by bradsprojects » Sun May 27, 2018 10:29 am

Hi Jerry, I tentatively chose $1300 because my code finishes up at around $1000.

The device I am using is an 18F43K20, basically I am looking to be able to store data in 256 byte blocks and then be able to recall them even when power has been removed. The reason for not using EEPROM is that I need eight seperate blocks of 256 bytes - for a total of 2048 bytes.

Jerry Messina
Swordfish Developer
Posts: 1469
Joined: Fri Jan 30, 2009 6:27 pm
Location: US

Re: Issues trying to use the Memory Access module to read da

Post by Jerry Messina » Sun May 27, 2018 1:27 pm

I'd be inclined to just reserve space at the top of memory (more akin to what you were doing), but here's a knocked-together version
of rombuffer that at least has the correct page sizes.

main.bas:

Code: Select all

device = 18F43K20

// 43K20 has a write block size of 16 bytes and an erase block size of 64 bytes
#option WRITE_BLOCK_SIZE = 16
#option ERASE_BLOCK_SIZE = 64

// reserve 2K of program memory
#option ROMTABLE_SIZE = 2048

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

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

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

// read them back...
For Index = 0 To ROMBufferSize - 1
   Value = ROM.ReadByte(Index)
Next
rom.bas:

Code: Select all

Module ROM

// default sizes (from original module)
// override to match your device
#option ERASE_BLOCK_SIZE = 64
#option WRITE_BLOCK_SIZE = 8

const
    _ERASE_BLOCK_SIZE = ERASE_BLOCK_SIZE,
    _WRITE_BLOCK_SIZE = WRITE_BLOCK_SIZE
    
// import the ROM table...
Include "ROMTable.bas"

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

// 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 (_WRITE_BLOCK_SIZE-1)) = 0 Then
      TABLEPTR = FBlockAddress
      WriteToROM
      Inc(FBlockAddress, _WRITE_BLOCK_SIZE)
      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, _ERASE_BLOCK_SIZE)
   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 = (addressof(ROMBuffer) / _ERASE_BLOCK_SIZE + 1) * _ERASE_BLOCK_SIZE
End Sub

// initialise the module...
Initialise
romtable.bas:

Code: Select all

Module ROMTable

#option ROMTABLE_SIZE = 256

const
    _ERASE_BLOCK_SIZE = ERASE_BLOCK_SIZE,
    _ROMTABLE_SIZE = ROMTABLE_SIZE + _ERASE_BLOCK_SIZE

// the ROM buffer...
Public Const ROMBuffer(_ROMTABLE_SIZE) 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,

  #if (ROMTABLE_SIZE = 2048)
   // *** 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,

   // *** 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,

   // *** 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,

   // *** 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,

   // *** 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,

   // *** 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,

   // *** 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,
  #endif    // (ROMBUFFER_SIZE = 2048)
   // *** end ROM table

   // last 64 bytes are pack bytes to ensure erase block falls 
   // on a valid _ERASE_BLOCK_SIZE 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
)
It still won't work for all devices and it's not completely generic, but it should be a little closer.
I didn't look at the rest of the code, didn't test it, or put anything in there for interrupts (if you're using them you should disable around the lock/unlock key sequence).

SF will allocate the const array in low memory before any other consts, so as long as you include "rom.bas" first before other includes I don't think it'll move around...
Attachments
rombuffer.zip
(1.98 KiB) Downloaded 172 times

Jerry Messina
Swordfish Developer
Posts: 1469
Joined: Fri Jan 30, 2009 6:27 pm
Location: US

Re: Issues trying to use the Memory Access module to read da

Post by Jerry Messina » Sun May 27, 2018 3:04 pm

I also tried the memoryaccess.bas module, and got it to work after making a few changes
to TableWrite(), WriteItem(), and WriteBlockSize...

Code: Select all

{
*****************************************************************************
*  Name    : MemoryAccess.BAS                                               *
*  Author  : Tim Box                                                        *
*  Notice  : Copyright (c) 2007 TJB Systems Ltd                             *
*          : All Rights Reserved                                            *
*  Date    : 03/08/2007                                                     *
*  Version : 1.0                                                            *
*  Notes   :                                                                *
*          :                                                                *
*****************************************************************************
}

Module MemoryAccess

// module option - just put some values in here for testing...
    #option ROM_BLOCK_SIZE = 8
    #if Not (ROM_BLOCK_SIZE in (8, 16, 32, 64))
      #error ROM_BLOCK_SIZE, "Invalid option. ROM_BLOCK_SIZE must be 8, 16 or whatever..."
    #endif

// bring option into the program...
    Const
        WriteBlockSize = ROM_BLOCK_SIZE // - 1

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

// inline delay
    Inline Sub Delay()
      Asm
      GoTo $ + 2
      End Asm
    End Sub

// table read
    Inline Sub TableRead()
      Asm
      TBLRD*+
      End Asm
    End Sub

// table write
    Inline Sub TableWrite()
      Asm
      TBLWT*
      End Asm
    End Sub

// Functions =======================

// read a byte from ROM 
    Public Function ReadByte (pAddress As TABLEPTR) As TABLAT
      EECON1 = 0
      EEPGD = 1
      TableRead
    End Function

// read a Word from ROM 
    Public Function ReadWord (pAddress As TABLEPTR) As Word
      EECON1 = 0
      EEPGD = 1
      TableRead
      result.Byte0 = TABLAT
      TableRead
      result.Byte1 = TABLAT
    End Function

// read a LongWord from ROM 
    Public Function ReadLongWord (pAddress As TABLEPTR) As LongWord
      EECON1 = 0
      EEPGD = 1
      TableRead
      result.Byte0 = TABLAT
      TableRead
      result.Byte1 = TABLAT
      TableRead
      result.Byte2 = TABLAT
      TableRead
      result.Byte3 = TABLAT
    End Function

// Subroutines =======================

// erase ROM block...
    Public Sub EraseBlock (pAddress As TABLEPTR)
      EECON1 = $94
      EECON2 = $55
      EECON2 = $AA
      WR = 1
      Delay
      WREN = 0
    End Sub

// close a write
    Public Sub CloseWrite()
      EECON1 = $84
      EECON2 = $55
      EECON2 = $AA
      WR = 1
      Delay
      WREN = 0
    End Sub

{
****************************************************************************
* Name    : WriteItem                                                      *
* Purpose : Write a byte to program memory                                 *
****************************************************************************
}
    Public Sub WriteItem (pValue As TABLAT)
      TableWrite       
      If (TBLPTRL and (WriteBlockSize-1)) = (WriteBlockSize-1) Then
         CloseWrite
      EndIf
      Inc(TABLEPTR)
    End Sub

{
****************************************************************************
* Name    : WriteAt (OVERLOAD)                                             *
* Purpose : Write a Byte at an address from program memory                 *
****************************************************************************
}   
    Public Inline Sub WriteAt (pAddress As TABLEPTR, pValue As TABLAT)
      WriteItem(TABLAT)
    End Sub

{
****************************************************************************
* Name    : WriteAt (OVERLOAD)                                             *
* Purpose : Write a Word at an address from Program memory                 *
****************************************************************************
}   
    Public Sub WriteAt (pAddress As TABLEPTR, pValue As Word)     
      WriteItem(pValue.byte0)
      WriteItem(pValue.byte1)
    End Sub

{
****************************************************************************
* Name    : WriteAt (OVERLOAD)                                             *
* Purpose : Write a LongWord at an address from Program memory             *
****************************************************************************
}
    Public Sub WriteAt (pAddress As TABLEPTR, pValue As LongWord)
      WriteItem(pValue.byte0)
      WriteItem(pValue.byte1)
      WriteItem(pValue.byte2)
      WriteItem(pValue.byte3)
    End Sub 

end module
test code:

Code: Select all

device = 18F25k20

// write block size for the K20
#option ROM_BLOCK_SIZE = 16
include "memoryaccess.bas"

dim ix as word
dim ram(256) as byte

Sub WriteToProgramMemory(BlockToSave As Word)
    Dim Address As Word
    Dim MyIndex As Byte
   
    Address = $1300 + BlockToSave
    EraseBlock(Address)
    eraseblock(Address + 64)
    eraseblock(Address + 128)
    eraseblock(Address + 192)
   
    For MyIndex = 0 To 255
        WriteAt(Address + MyIndex, RAM(MyIndex))
    Next
    'CloseWrite << remove this
End Sub


// The one thing I have not been able to get working is reading data from program memory and then storing it back into my RAM() array. 
// Here is the code at the moment:

Sub ReadFromProgramMemory(BlockToRead As Word)
    Dim Address As Word
    Dim MyIndex As Byte
   
    Address = $1300 + BlockToRead
    For MyIndex = 0 To 255
        RAM(MyIndex) = ReadByte(address + MyIndex)
    Next
End Sub


for ix = 0 to bound(ram)
	ram(ix) = ix
next

WriteToProgramMemory(0)
clear(ram)
ReadFromProgramMemory(0)

bradsprojects
Posts: 28
Joined: Thu Nov 29, 2012 12:29 am
Location: Australia

Re: Issues trying to use the Memory Access module to read da

Post by bradsprojects » Sun May 27, 2018 7:38 pm

Sorry for the late reply - i've just woken up :)

I really appreciate the time you've put in to helping me out with this Jerry - i'll give it a try now and report back.

bradsprojects
Posts: 28
Joined: Thu Nov 29, 2012 12:29 am
Location: Australia

Re: Issues trying to use the Memory Access module to read da

Post by bradsprojects » Sun May 27, 2018 8:01 pm

Jerry - that worked an absolute treat!

I tried it with all eight blocks of 256 bytes, it was able to copy the data over and then restore it without any hassles. A huge thanks for your assistance with this. The project I am working on is called the Digirule2, which is an 8-bit programmable binary computer built into a 20cm ruler and is powered by a PIC18F43K20 microcontroller:
Image

More info can be found here:
https://bradsprojects.com/digirule2/

The eight blocks of 256 bytes that I was looking to store - is so the user can write a program into the ruler and then store it in any one of the eight storage locations to use again at a later time.

As a token of thanks for your help on this forum over the years, i'd like to send you a Digirule2 (if you would like one, that is). I'll send you a PM.

Jerry Messina
Swordfish Developer
Posts: 1469
Joined: Fri Jan 30, 2009 6:27 pm
Location: US

Re: Issues trying to use the Memory Access module to read da

Post by Jerry Messina » Mon May 28, 2018 12:15 am

That's way cool, Brad!
Geez, I must really be geeking out to think a ruler's exciting. I do have a life, really I do.

Which of the two methods did you end up using?

bradsprojects
Posts: 28
Joined: Thu Nov 29, 2012 12:29 am
Location: Australia

Re: Issues trying to use the Memory Access module to read da

Post by bradsprojects » Mon May 28, 2018 12:56 am

Glad to hear i'm not the only one getting excited about nerdy rulers - however I too have a life - although my wife just looks at it and sees a bunch of red lights on a ruler...

I should have mentioned - I used the second method that you posted. Of the two methods it made more sense to me to access the program memory location directly and not have to rely on pointing to a const array which is stored within program memory anyway.

Post Reply