Okay, I'm with you guys so far. The part that I need to figure out is using word-aligned data from the SRAM's when it seems the cache expects byte-aligned. I could just use the lower 8 bits I suppose but then I waste half the memory available! I'm sure it's not that hard, just need to put it all together! Also, is there a limit to the size of the cache file?
*edit*
I see line_size controls the number of bytes to read and write. Is there a way to make sure this is an even number? That would make things a bit easier since I could just divide this by 2 to get the number of transfers from SRAM. Then, when doing the transfer: Read a word from Ram and put in 2 bytes in hub. Or read 2 bytes from hub and put a word in RAM. Does this sound like I'm heading in the right direction?
Okay, I'm with you guys so far. The part that I need to figure out is using word-aligned data from the SRAM's when it seems the cache expects byte-aligned. I could just use the lower 8 bits I suppose but then I waste half the memory available! I'm sure it's not that hard, just need to put it all together! Also, is there a limit to the size of the cache file?
The cache driver will never read or write in increments smaller than a cache line. You get to decide the size of a cache line but it will certainly be larger than 16 bits and it will be aligned on a cache-line sized boundary. In other words, if you use 64 byte cache lines they will be aligned on a 64 byte boundary which is, of course, also 16 bit aligned. I don't think alignment will be a problem.
I think doc has the design pretty much nailed down. There is a 2-screen variant I'm eagerly waiting to get my hands on too! Should function similar at the low level.
I'm not sure what you mean "available," Dr. Acula and I have boards built and running. If you're asking about "distribution" spec boards, you'd have to check with Doc. I know we are "close" to release and sure we could get boards to those interested in the future. I'm not sure how soon exactly.
These use the 40-pin touchscreen boards and I believe we will be supporting the SSD1289 controller. *These are the displays I'm using. Doc is using an ili9325 right now but it sounds like he will be converting to the SSD soon. I'm not sure if you guys have any of these displays or similar floating around.
I've been looking at the skeleton cache file and I think I understand it *sort of* I'm sure I will have questions later.
Thanks again for all the help!
By the way, I asked about hardware available to determine if it might be possible for me to help you with the cache driver. Obviously, I'd need hardware to do that.
Good, I just wanted to make sure about the line size. Like I said before I'm VERY dense with moments of idiot savant. I'm working on things and will let you guys know when I'm getting close. BTW, if anyone is interested in obtaining a board, just contact me.
*edit*
So far, it's mostly a "copy-paste-modify" job. It should be getting close though.
This is the overhead for the driver:
'get_values rdlong hubaddr, hubptr ' get hub address' rdlong ramaddr, ramptr ' get ram address' rdlong len, lenptr ' get length' mov err, #5 ' err=5'get_values_ret ret'init 'mov err, #0 ' reset err=false=good'mov dira,zero ' tristate the pins with the cog dira' and dira,maskP0P20P22 ' tristates all the common pins'done 'wrlong err, errptr ' status =0=false=good, else error x'wrlong zero, comptr ' command =0 (done)' Pass pasm_n = 0- 7 come to this with P0-P20 and P22 tristated and returns them as this too
set137 ordira,maskP22 ' pin 22 is an outputandnouta,maskP22 ' set P22low so Y0-Y7 are all highordira,maskP0P20 ' pins P0-P20 are outputsandouta,maskP0P2low ' set these 3 pins loworouta,pasm_n ' set the 137 pinsorouta,maskP22 ' pin 22 high
set137_ret ret' return
load161pasm ' uses vmaddrorouta,maskP0P20 ' set P0-P20 high ordira,maskP0P20 ' output pins 0-20mov pasm_n,#0' group 0call #set137 ' set the 137 outputandouta,maskP0P18low ' pins 0-18 set loworouta,vmaddr ' output addres to 161 chipsorouta,maskP19 ' clock highorouta,maskP20 ' load highandnouta,maskP19 ' clock lowandnouta,maskP20 ' load loworouta,maskP19 ' clock highorouta,maskP20 ' load high
load161pasm_ret ret
stop jmp #stop ' for debugging
memorytransfer ordira,maskP16P20 ' so /wr and other pins definitely highorouta,maskP16P20
mov pasm_n,#1' back to group 1 for memory transfercall #set137 ' as next routine will always be group 1ordira,maskP16P20 ' output pins 16-20orouta,maskP16P20 ' set P16-P20 high (P0-P15 set as inputs or outputs in the calling routine)
memorytransfer_ret ret
busoutput ordira,maskP0P15 ' set prop pins 0-15 as outputs
busoutput_ret ret
businput anddira,maskP16P31 ' set P0-P15 as inputs
businput_ret ret
delaynop nopnopnopnop
delaynop_ret ret
And the actual reads:
'----------------------------------------------------------------------------------------------------'' rd_cache_line - read a cache line from external memory'' vmaddr is the external memory address to read' hubaddr is the hub memory address to write' line_size is the number of bytes to read''----------------------------------------------------------------------------------------------------
rd_cache_line
' command T
pasmramtohub
call #load161pasm ' load the 161 counters with ramaddrcall #memorytransfer ' set to group 1, enable P16-P20 as outputs and set P16-P20 high call #businput ' set prop pins P0-P15 as inputsandnouta,maskP16 ' memory /rd low
ramtohub_loop mov data_16,ina' get the datawrword data_16,hubaddr ' move data to hubandnouta,maskP19 ' clock 161 loworouta,maskP19 ' clock 161 highadd hubaddr,#2' increment the hub address djnz line_size,#ramtohub_loop
orouta,maskP16 ' memory /rd high ordira,maskP0P15 ' %00000000_00000000_11111111_11111111 restore P0-P15as outputsanddira,maskP0P20P22 ' tristates all the common pins
rd_cache_line_ret
ret
The writes:
'----------------------------------------------------------------------------------------------------'' wr_cache_line - write a cache line to external memory'' vmaddr is the external memory address to write' hubaddr is the hub memory address to read' line_size is the number of bytes to write''----------------------------------------------------------------------------------------------------
wr_cache_line
' command S
pasmhubtoram
call #load161pasm ' load the 161 counters with ramaddrcall #memorytransfer ' set to group 1, enable P16-P20 as outputs and set P16-P20 highcall #busoutput ' set prop pins P0-P15 as outputs
hubtoram_loop andouta,maskP16P31 '%11111111_11111111_00000000_00000000 ' clear for output rdword data_16,hubaddr ' get the word from huband data_16,maskP0P15 ' mask to a word onlyorouta,data_16 ' send out the byte to P0-P15andnouta,maskP17 ' set mem write lowadd hubaddr,#2' increment by 2 bytes = 1 word. Put this here for small delay while writesorouta,maskP17 ' mem write highandnouta,maskP19 ' clock 161 loworouta,maskP19 ' clock 161 highdjnz line_size,#hubtoram_loop ' loop this many timesanddira,maskP0P20P22 ' tristates all the common pins
wr_cache_line_ret
ret
Last is the variable overhead:
pasm_n long 0 ' general purpose value
data_16 long 0 ' general purpose value
maskP0P2low long %11111111_11111111_11111111_11111000 ' P0-P2 low
maskP0P20 long %00000000_00011111_11111111_11111111 ' P0-P18 enabled for output plus P19,P20maskP0P18low long %11111111_11111000_00000000_00000000 ' P0-P18 low
maskP16 long %00000000_00000001_00000000_00000000 ' pin 16maskP17 long %00000000_00000010_00000000_00000000 ' pin 17maskP18 long %00000000_00000100_00000000_00000000 ' pin 18maskP19 long %00000000_00001000_00000000_00000000 ' pin 19maskP20 long %00000000_00010000_00000000_00000000 ' pin 20maskP22 long %00000000_01000000_00000000_00000000 ' pin 22maskP16P31 long %11111111_11111111_00000000_00000000 ' pin 16 to pin 31maskP0P15 long %00000000_00000000_11111111_11111111 ' for masking words
maskP16P20 long %00000000_00011111_00000000_00000000maskP0P20P22 long %11111111_10100000_00000000_00000000 ' for returning all group pins HiZ
I assume I don't need the "get_value" since that's already taken care of? Still need to work out the byte-word alignment problem but...
I know there's still the word-byte alignment problem but I built the previously described code.
Result of the BSTC are
c:\Users\Joe\Desktop\Propeller\GUI\Touch161>bstc
Brads Spin Tool Compiler v0.15.3 - Copyright 2008Compiled for i386 Win32 at 08:17:48on2009/07/20Loading Object skeleton_cache
Program size is 1092 longs
Compiled181 Lines of Code in 0.006 Seconds
Any thoughts on how to fix the byte-word alignment issue? Do 2 transfers per loop and shift "line_size" right by 1 at the start?
I know there's still the word-byte alignment problem but I built the previously described code.
Result of the BSTC are
c:\Users\Joe\Desktop\Propeller\GUI\Touch161>bstc
Brads Spin Tool Compiler v0.15.3 - Copyright 2008Compiled for i386 Win32 at 08:17:48on2009/07/20Loading Object skeleton_cache
Program size is 1092 longs
Compiled181 Lines of Code in 0.006 Seconds
Any thoughts on how to fix the byte-word alignment issue? Do 2 transfers per loop and shift "line_size" right by 1 at the start?
Okay, I will work on that. Should I be able to test the cache driver even if it's wasting half the memory? I'm @post 2...Compiled the catch, changed the board config. Stuck at running the cache_test? with the interface?
*edit* ok RTFM and I think I got it... I'll be back to you with the results:
Okay, I will work on that. Should I be able to test the cache driver even if it's wasting half the memory? I'm @post 2...Compiled the catch, changed the board config. Stuck at running the cache_test? with the interface?
Hang on. Maybe I misunderstood what you meant. Why do you need to waste half of the memory? Just fetch 16 bits at a time and store them into hub memory using wrword, increment the address by 2 and decrement the count by 2. You can assume that the cache driver will never ask for an odd number of bytes so you don't have to take care of that case.
@averagejoe, I don't believe you need to worry about caching using the sram. The clever boffins here have managed to write a generic cache driver that uses the SD card and hub ram. That works on a wide variety of boards - basically any board with an SD card. Just change the pin numbers. It is fast because most of the time it is running from hub, and it does not 'wear out' the SD card as all the SD card accesses are reads, not writes.
So if you you take the standard XMM code for the Board of Education and just change the SD pin numbers you can run huge C programs on our board.
That simplifies things because then all the SRAM accesses are done from C code. And all the PASM part does not need to change. So all you really have to do is rewrite the PUB docmd() routine to run from C, as well as change the cog start and stop methods to the C syntax.
GCC never needs to know about the SRAM and that means that GCC does not need changing.
A few weeks back I thought a lot about using the SRAM as the cache for GCC but I really don't think we need it any more. And that frees up the entire SRAM for bitmaps and fonts and large text buffers - all of which will be handled by a C program (which will probably ultimately become a .h program). There is a Spin to C translator out there, so it may even be possible to feed routines into this and porting over the spin code we have should be even easier. The pasm part stays as it is, and the spin gets converted to C.
@averagejoe, I don't believe you need to worry about caching using the sram. The clever boffins here have managed to write a generic cache driver that uses the SD card and hub ram. That works on a wide variety of boards - basically any board with an SD card. Just change the pin numbers. It is fast because most of the time it is running from hub, and it does not 'wear out' the SD card as all the SD card accesses are reads, not writes.
So if you you take the standard XMM code for the Board of Education and just change the SD pin numbers you can run huge C programs on our board.
That simplifies things because then all the SRAM accesses are done from C code. And all the PASM part does not need to change. So all you really have to do is rewrite the PUB docmd() routine to run from C, as well as change the cog start and stop methods to the C syntax.
GCC never needs to know about the SRAM and that means that GCC does not need changing.
A few weeks back I thought a lot about using the SRAM as the cache for GCC but I really don't think we need it any more. And that frees up the entire SRAM for bitmaps and fonts and large text buffers - all of which will be handled by a C program (which will probably ultimately become a .h program). There is a Spin to C translator out there, so it may even be possible to feed routines into this and porting over the spin code we have should be even easier. The pasm part stays as it is, and the spin gets converted to C.
While you are correct that you can use the SD cache driver to run large C programs from an SD card, the performance will not be nearly as good as you could get running from your parallel SRAM if you can figure out a way to share the SRAM between the display driver and the cache driver.
I see an option for split, if this is what I assume I think this would be best candidate. If you can split the catching between SRAM and SD, is there a way to decide what goes where? I will try porting the "working" touchcode to C and test with just SD catching. I think eventually it would be good to have the SRAM available, but might not be top priority right now!
While you are correct that you can use the SD cache driver to run large C programs from an SD card, the performance will not be nearly as good as you could get running from your parallel SRAM if you can figure out a way to share the SRAM between the display driver and the cache driver.
Yes it would be interesting to do the experiment. I was basing my comments on experiments we did last year with Catalina where we found in the end that caching was so efficient that the actual speed of transfers to and from the cache hardly seemed to affect the overall performance.
But, hypothetically, if one did use the sram, there are two simple routines to transfer data to and from hub. Pass to a pasm routine a single letter command to send or receive, a long for hub address, a long for ram address and number of bytes.
And I guess you need a flag somewhere in hub to say the code is using the sram or the cache is using the sram.
I don't think it will be needed though. XMMC from hub is fast, and it could be as fast as LMM when functions are small enough to fit in hub. Whenever something runs a bit slow, I find it is easier to port things over to pasm.
Is there a generic big C program we can use to test XMMC? A text based adventure program or something?
The only problem with XMMC comes when you use up all of HUB RAM - it is possible to run with a smaller cache of course, but performance does drop.
With the right device, XMMC is faster than SPIN; with the wrong device (SDcard) it is slower than SPIN. XMMC on EEPROM is faster than XMMC on SDcard.
XMM-SINGLE lets you use all of SRAM for code and data; it is usually slower than XMMC.
One of the bigger programs I've used for testing is David's EBASIC2. It works great and can quickly highlight performance differences. EBASIC2 is in the Propeller-GCC demos package.
One of the biggest challenges with XMMC on SD is the large cache line. SD accesses are done in 512-byte chunks, which allows for only 16 cache lines in an 8K cache. It would be interesting to try some experiments with a 16K cache to see how much improvement we would get. There have also been some ideas about reducing the cache line size tto 256 bytes by throwing away half the data on each access, or providing a small secondary cache that would hold the unused 256 bytes in case they are needed later.
Hey guys, I've been working on the cache driver and I think I'm close. What I'm trying to figure out now is the best way to finish the byte-word alignment issue. It seems the code was pretty close already. The only remaining issue *I THINK* is the best way to change "line_size". My initial thought was to shift line_size right by 1 somewhere at the beginning of the call. My other thought was to subtract 1 before the "djnz line_size,#ramtohub_loop" or "djnz line_size,#hubtoram_loop" but this would take an extra instruction every time the main loop runs. Any advice on where to put the "shr line_size, #1" Maybe in "Load161?"
Here's what I have so far.
'get_values rdlong hubaddr, hubptr ' get hub address' rdlong ramaddr, ramptr ' get ram address' rdlong len, lenptr ' get length' mov err, #5 ' err=5'get_values_ret ret'init 'mov err, #0 ' reset err=false=good'mov dira,zero ' tristate the pins with the cog dira' and dira,maskP0P20P22 ' tristates all the common pins'done 'wrlong err, errptr ' status =0=false=good, else error x'wrlong zero, comptr ' command =0 (done)' Pass pasm_n = 0- 7 come to this with P0-P20 and P22 tristated and returns them as this too
set137 ordira,maskP22 ' pin 22 is an outputandnouta,maskP22 ' set P22low so Y0-Y7 are all highordira,maskP0P20 ' pins P0-P20 are outputsandouta,maskP0P2low ' set these 3 pins loworouta,pasm_n ' set the 137 pinsorouta,maskP22 ' pin 22 high
set137_ret ret' return
load161pasm ' uses vmaddrorouta,maskP0P20 ' set P0-P20 high ordira,maskP0P20 ' output pins 0-20mov pasm_n,#0' group 0call #set137 ' set the 137 outputandouta,maskP0P18low ' pins 0-18 set loworouta,vmaddr ' output addres to 161 chipsorouta,maskP19 ' clock highorouta,maskP20 ' load highandnouta,maskP19 ' clock lowandnouta,maskP20 ' load loworouta,maskP19 ' clock highorouta,maskP20 ' load high
load161pasm_ret ret
stop jmp #stop ' for debugging
memorytransfer ordira,maskP16P20 ' so /wr and other pins definitely highorouta,maskP16P20
mov pasm_n,#1' back to group 1 for memory transfercall #set137 ' as next routine will always be group 1ordira,maskP16P20 ' output pins 16-20orouta,maskP16P20 ' set P16-P20 high (P0-P15 set as inputs or outputs in the calling routine)
memorytransfer_ret ret
busoutput ordira,maskP0P15 ' set prop pins 0-15 as outputs
busoutput_ret ret
businput anddira,maskP16P31 ' set P0-P15 as inputs
businput_ret ret
delaynop nopnopnopnop
delaynop_ret ret'----------------------------------------------------------------------------------------------------'' rd_cache_line - read a cache line from external memory'' vmaddr is the external memory address to read' hubaddr is the hub memory address to write' line_size is the number of bytes to read''----------------------------------------------------------------------------------------------------
rd_cache_line
' command T
pasmramtohub
call #load161pasm ' load the 161 counters with ramaddrcall #memorytransfer ' set to group 1, enable P16-P20 as outputs and set P16-P20 high call #businput ' set prop pins P0-P15 as inputsandnouta,maskP16 ' memory /rd low
ramtohub_loop mov data_16,ina' get the datawrword data_16,hubaddr ' move data to hubandnouta,maskP19 ' clock 161 loworouta,maskP19 ' clock 161 highadd hubaddr,#2' increment the hub address djnz line_size,#ramtohub_loop
orouta,maskP16 ' memory /rd high ordira,maskP0P15 ' %00000000_00000000_11111111_11111111 restore P0-P15as outputsanddira,maskP0P20P22 ' tristates all the common pins
rd_cache_line_ret
ret'----------------------------------------------------------------------------------------------------'' wr_cache_line - write a cache line to external memory'' vmaddr is the external memory address to write' hubaddr is the hub memory address to read' line_size is the number of bytes to write''----------------------------------------------------------------------------------------------------
wr_cache_line
' command S
pasmhubtoram
call #load161pasm ' load the 161 counters with ramaddrcall #memorytransfer ' set to group 1, enable P16-P20 as outputs and set P16-P20 highcall #busoutput ' set prop pins P0-P15 as outputs
hubtoram_loop andouta,maskP16P31 '%11111111_11111111_00000000_00000000 ' clear for output rdword data_16,hubaddr ' get the word from huband data_16,maskP0P15 ' mask to a word onlyorouta,data_16 ' send out the byte to P0-P15andnouta,maskP17 ' set mem write lowadd hubaddr,#2' increment by 2 bytes = 1 word. Put this here for small delay while writesorouta,maskP17 ' mem write highandnouta,maskP19 ' clock 161 loworouta,maskP19 ' clock 161 highdjnz line_size,#hubtoram_loop ' loop this many timesanddira,maskP0P20P22 ' tristates all the common pins
wr_cache_line_ret
ret
pasm_n long0' general purpose value
data_16 long0' general purpose value
maskP0P2low long%11111111_11111111_11111111_11111000' P0-P2 low
maskP0P20 long%00000000_00011111_11111111_11111111' P0-P18 enabled for output plus P19,P20
maskP0P18low long%11111111_11111000_00000000_00000000' P0-P18 low
maskP16 long%00000000_00000001_00000000_00000000' pin 16
maskP17 long%00000000_00000010_00000000_00000000' pin 17
maskP18 long%00000000_00000100_00000000_00000000' pin 18
maskP19 long%00000000_00001000_00000000_00000000' pin 19
maskP20 long%00000000_00010000_00000000_00000000' pin 20
maskP22 long%00000000_01000000_00000000_00000000' pin 22
maskP16P31 long%11111111_11111111_00000000_00000000' pin 16 to pin 31
maskP0P15 long%00000000_00000000_11111111_11111111' for masking words
maskP16P20 long%00000000_00011111_00000000_00000000
maskP0P20P22 long%11111111_10100000_00000000_00000000' for returning all group pins HiZfit496
Please advise the best place to put the "overhead" such as Load161. I'm also not sure of what tests to run in test_cache once the cache file is built. Thanks as always!
*edit*
I tried "T a" and get a bunch of nonsense from the terminal?
{
Skeleton JCACHE external RAM driver
Copyright (c) 2011 by David Betz
Based on code by Steve Denson (jazzed)
Copyright (c) 2010 by John Steven Denson
Inspired by VMCOG - virtual memory server for the Propeller
Copyright (c) February 3, 2010 by William Henning
For the EuroTouch 161 By James Moxham and Joe Heinz
TERMS OF USE: MIT License
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
}CON' default cache dimensions
DEFAULT_INDEX_WIDTH = 6
DEFAULT_OFFSET_WIDTH = 7' cache line tag flags
EMPTY_BIT = 30
DIRTY_BIT = 31PUBimagereturn @init_vm
DATorg$0' initialization structure offsets' $0: pointer to a two word mailbox' $4: pointer to where to store the cache lines in hub ram' $8: number of bits in the cache line index if non-zero (default is DEFAULT_INDEX_WIDTH)' $a: number of bits in the cache line offset if non-zero (default is DEFAULT_OFFSET_WIDTH)' note that $4 must be at least 2^(index_width+offset_width) bytes in size' the cache line mask is returned in $0
init_vm mov t1, par' get the address of the initialization structurerdlong pvmcmd, t1 ' pvmcmd is a pointer to the virtual address and read/write bitmov pvmaddr, pvmcmd ' pvmaddr is a pointer into the cache line on returnadd pvmaddr, #4add t1, #4rdlong cacheptr, t1 ' cacheptr is the base address in hub ram of the cacheadd t1, #4rdlong t2, t1 wzif_nzmov index_width, t2 ' override the index_width default valueadd t1, #4rdlong t2, t1 wzif_nzmov offset_width, t2 ' override the offset_width default valuemov index_count, #1shl index_count, index_width
mov index_mask, index_count
sub index_mask, #1mov line_size, #1shl line_size, offset_width
mov t1, line_size
sub t1, #1wrlong t1, par' put external memory initialization herejmp #vmflush
fillme long0[128-fillme] ' first 128 cog locations are used for a direct mapped cache tablefit128' initialize the cache lines
vmflush movd :flush, #0mov t1, index_count
:flush mov0-0, empty_mask
add :flush, dstinc
djnz t1, #:flush
' start the command loop
waitcmd wrlong zero, pvmcmd
:wait rdlong vmline, pvmcmd wzif_zjmp #:wait
shr vmline, offset_width wc' carry is now one for read and zero for writemov set_dirty_bit, #0' make mask to set dirty bit on writesmuxnc set_dirty_bit, dirty_mask
mov line, vmline ' get the cache line indexand line, index_mask
mov hubaddr, line
shl hubaddr, offset_width
add hubaddr, cacheptr ' get the address of the cache linewrlong hubaddr, pvmaddr ' return the address of the cache linemovs :ld, line
movd :st, line
:ld mov vmcurrent, 0-0' get the cache line tagand vmcurrent, tag_mask
cmp vmcurrent, vmline wz' z set means there was a cache hitif_nzcall #miss ' handle a cache miss
:st or0-0, set_dirty_bit ' set the dirty bit on writesjmp #waitcmd ' wait for a new command' line is the cache line index' vmcurrent is current cache line' vmline is new cache line' hubaddr is the address of the cache line
miss movd :test, line
movd :st, line
:testtest0-0, dirty_mask wzif_zjmp #:rd ' current cache line is clean, just read new onemov vmaddr, vmcurrent
shl vmaddr, offset_width
call #wr_cache_line ' write current cache line
:rd mov vmaddr, vmline
shl vmaddr, offset_width
call #rd_cache_line ' read new cache line
:st mov0-0, vmline
miss_ret ret' pointers to mailbox entries
pvmcmd long0' on call this is the virtual address and read/write bit
pvmaddr long0' on return this is the address of the cache line containing the virtual address
cacheptr long0' address in hub ram where cache lines are stored
vmline long0' cache line containing the virtual address
vmcurrent long0' current selected cache line (same as vmline on a cache hit)
line long0' current cache line index
set_dirty_bit long0' DIRTY_BIT set on writes, clear on reads
zero long0' zero constant
dstinc long1<<9' increment for the destination field of an instruction
t1 long0' temporary variable
t2 long0' temporary variable
tag_mask long !(1<<DIRTY_BIT) ' includes EMPTY_BIT
index_width long DEFAULT_INDEX_WIDTH
index_mask long0
index_count long0
offset_width long DEFAULT_OFFSET_WIDTH
line_size long0' line size in bytes
empty_mask long (1<<EMPTY_BIT)
dirty_mask long (1<<DIRTY_BIT)
' input parameters to rd_cache_line and wr_cache_line
vmaddr long0' external address
hubaddr long0' hub memory address'get_values rdlong hubaddr, hubptr ' get hub address' rdlong ramaddr, ramptr ' get ram address' rdlong len, lenptr ' get length' mov err, #5 ' err=5'get_values_ret ret'init 'mov err, #0 ' reset err=false=good'mov dira,zero ' tristate the pins with the cog dira' and dira,maskP0P20P22 ' tristates all the common pins'done 'wrlong err, errptr ' status =0=false=good, else error x'wrlong zero, comptr ' command =0 (done)' Pass pasm_n = 0- 7 come to this with P0-P20 and P22 tristated and returns them as this too
set137 ordira,maskP22 ' pin 22 is an outputandnouta,maskP22 ' set P22low so Y0-Y7 are all highordira,maskP0P20 ' pins P0-P20 are outputsandouta,maskP0P2low ' set these 3 pins loworouta,pasm_n ' set the 137 pinsorouta,maskP22 ' pin 22 high
set137_ret ret' return
load161pasm ' uses vmaddrshr line_size, #1' devide line_size by two for word-byteorouta,maskP0P20 ' set P0-P20 high ordira,maskP0P20 ' output pins 0-20mov pasm_n,#0' group 0call #set137 ' set the 137 outputandouta,maskP0P18low ' pins 0-18 set loworouta,vmaddr ' output addres to 161 chipsorouta,maskP19 ' clock highorouta,maskP20 ' load highandnouta,maskP19 ' clock lowandnouta,maskP20 ' load loworouta,maskP19 ' clock highorouta,maskP20 ' load high
load161pasm_ret ret
stop jmp #stop ' for debugging
memorytransfer ordira,maskP16P20 ' so /wr and other pins definitely highorouta,maskP16P20
mov pasm_n,#1' back to group 1 for memory transfercall #set137 ' as next routine will always be group 1ordira,maskP16P20 ' output pins 16-20orouta,maskP16P20 ' set P16-P20 high (P0-P15 set as inputs or outputs in the calling routine)
memorytransfer_ret ret
busoutput ordira,maskP0P15 ' set prop pins 0-15 as outputs
busoutput_ret ret
businput anddira,maskP16P31 ' set P0-P15 as inputs
businput_ret ret
delaynop nopnopnopnop
delaynop_ret ret'----------------------------------------------------------------------------------------------------'' rd_cache_line - read a cache line from external memory'' vmaddr is the external memory address to read' hubaddr is the hub memory address to write' line_size is the number of bytes to read''----------------------------------------------------------------------------------------------------
rd_cache_line
' command T
pasmramtohub
call #load161pasm ' load the 161 counters with ramaddrcall #memorytransfer ' set to group 1, enable P16-P20 as outputs and set P16-P20 high call #businput ' set prop pins P0-P15 as inputsandnouta,maskP16 ' memory /rd low
ramtohub_loop mov data_16,ina' get the datawrword data_16,hubaddr ' move data to hubandnouta,maskP19 ' clock 161 loworouta,maskP19 ' clock 161 highadd hubaddr,#2' increment the hub address djnz line_size,#ramtohub_loop
orouta,maskP16 ' memory /rd high ordira,maskP0P15 ' %00000000_00000000_11111111_11111111 restore P0-P15as outputsanddira,maskP0P20P22 ' tristates all the common pins
rd_cache_line_ret
ret'----------------------------------------------------------------------------------------------------'' wr_cache_line - write a cache line to external memory'' vmaddr is the external memory address to write' hubaddr is the hub memory address to read' line_size is the number of bytes to write''----------------------------------------------------------------------------------------------------
wr_cache_line
' command S
pasmhubtoram
call #load161pasm ' load the 161 counters with ramaddrcall #memorytransfer ' set to group 1, enable P16-P20 as outputs and set P16-P20 highcall #busoutput ' set prop pins P0-P15 as outputs
hubtoram_loop andouta,maskP16P31 '%11111111_11111111_00000000_00000000 ' clear for output rdword data_16,hubaddr ' get the word from huband data_16,maskP0P15 ' mask to a word onlyorouta,data_16 ' send out the byte to P0-P15andnouta,maskP17 ' set mem write lowadd hubaddr,#2' increment by 2 bytes = 1 word. Put this here for small delay while writesorouta,maskP17 ' mem write highandnouta,maskP19 ' clock 161 loworouta,maskP19 ' clock 161 highdjnz line_size,#hubtoram_loop ' loop this many timesanddira,maskP0P20P22 ' tristates all the common pins
wr_cache_line_ret
ret
pasm_n long0' general purpose value
data_16 long0' general purpose value
maskP0P2low long%11111111_11111111_11111111_11111000' P0-P2 low
maskP0P20 long%00000000_00011111_11111111_11111111' P0-P18 enabled for output plus P19,P20
maskP0P18low long%11111111_11111000_00000000_00000000' P0-P18 low
maskP16 long%00000000_00000001_00000000_00000000' pin 16
maskP17 long%00000000_00000010_00000000_00000000' pin 17
maskP18 long%00000000_00000100_00000000_00000000' pin 18
maskP19 long%00000000_00001000_00000000_00000000' pin 19
maskP20 long%00000000_00010000_00000000_00000000' pin 20
maskP22 long%00000000_01000000_00000000_00000000' pin 22
maskP16P31 long%11111111_11111111_00000000_00000000' pin 16 to pin 31
maskP0P15 long%00000000_00000000_11111111_11111111' for masking words
maskP16P20 long%00000000_00011111_00000000_00000000
maskP0P20P22 long%11111111_10100000_00000000_00000000' for returning all group pins HiZfit496
I believe I have filled this out. The "overhead" and rd and wr cache lines *Bottom of file up* were taken from this code that's been tested good..It's a bit long, so I remove some of the portions..
DAT'' +-----------------------------------------------------------------------------------------------+'' | Touchblade 161 Ram Driver (with grateful acknowlegements to Cluso and Average Joe) |'' +-----------------------------------------------------------------------------------------------+org0
tbp2_start ' setup the pointers to the hub command interface (saves execution time later' +-- These instructions are overwritten as variables after start
comptr mov comptr, par' -| hub pointer to command
hubptr mov hubptr, par' | hub pointer to hub address
ramptr add hubptr, #4' | hub pointer to ram address
lenptr mov ramptr, par' | hub pointer to length
errptr add ramptr, #8' | hub pointer to error status
cmd mov lenptr, par' | command I/R/W/G/P/Q
hubaddr add lenptr, #12' | hub address
ramaddr mov errptr, par' | ram address
len add errptr, #16' | length
err nop' -+ error status returned (=0=false=good) ' Initialise hardware tristates everything and read/write set the pins
init mov err, #0' reset err=false=good'mov dira,zero ' tristate the pins with the cog diraanddira,maskP0P20P22 ' tristates all the common pins
done wrlong err, errptr ' status =0=false=good, else error xwrlong zero, comptr ' command =0 (done)' wait for a command (pause short time to reduce power)
pause
' mov ctr, delay wz ' if =0 no pause' if_nz add ctr, cnt' if_nz waitcnt ctr, #0 ' wait for a short time (reduces power)rdlong cmd, comptr wz' command ?if_zjmp #pause ' not yet' decode commandcmp cmd, #"S"wz' hub to ramif_zjmp #pasmhubtoram
cmp cmd, #"T"wz' ram to hubif_zjmp #pasmramtohub
cmp cmd, #"U"wz' ram to displayif_zjmp #pasmramtodisplay
cmp cmd, #"V"wz' hub to displayif_zjmp #pasmhubtodisplay
cmp cmd, #"E"wz' convert 3 byte .raw format to 2 byte .ili format - hub to hubif_zjmp #rawtoiliformat
cmp cmd, #"F"wz' convert 3 byte .bmp format BGR to 2 byte ili format (same as E but order reversed)if_zjmp #bmptoiliformat
' cmp cmd, #"W" wz ' lcdwritecom in pasm, not working' if_z jmp #pasmlcdwritecomcmp cmd, #"X"wz' merge icon and background based on a maskif_zjmp #mergeicons
cmp cmd, #"Y"wz' change the 137 outputif_zjmp #changegroup
cmp cmd, #"Z"wz' set the 161 countersif_zjmp #set161
cmp cmd, #"I"wz' initif_zjmp #init
mov err, cmd ' error = cmd (unknown command)jmp #done
' ----------------- common routines -------------------------------------
get_values rdlong hubaddr, hubptr ' get hub addressrdlong ramaddr, ramptr ' get ram addressrdlong len, lenptr ' get lengthmov err, #5' err=5
get_values_ret ret' Pass pasm_n = 0- 7 come to this with P0-P20 and P22 tristated and returns them as this too
set137 ordira,maskP22 ' pin 22 is an outputandnouta,maskP22 ' set P22low so Y0-Y7 are all highordira,maskP0P20 ' pins P0-P20 are outputsandouta,maskP0P2low ' set these 3 pins loworouta,pasm_n ' set the 137 pinsorouta,maskP22 ' pin 22 high
set137_ret ret' return
load161pasm ' uses ramaddrorouta,maskP0P20 ' set P0-P20 high ordira,maskP0P20 ' output pins 0-20mov pasm_n,#0' group 0call #set137 ' set the 137 outputandouta,maskP0P18low ' pins 0-18 set loworouta,ramaddr ' output addres to 161 chipsorouta,maskP19 ' clock highorouta,maskP20 ' load highandnouta,maskP19 ' clock lowandnouta,maskP20 ' load loworouta,maskP19 ' clock highorouta,maskP20 ' load high
load161pasm_ret ret
stop jmp #stop ' for debugging
memorytransfer ordira,maskP16P20 ' so /wr and other pins definitely highorouta,maskP16P20
mov pasm_n,#1' back to group 1 for memory transfercall #set137 ' as next routine will always be group 1ordira,maskP16P20 ' output pins 16-20orouta,maskP16P20 ' set P16-P20 high (P0-P15 set as inputs or outputs in the calling routine)
memorytransfer_ret ret
busoutput ordira,maskP0P15 ' set prop pins 0-15 as outputs
busoutput_ret ret
businput anddira,maskP16P31 ' set P0-P15 as inputs
businput_ret ret
delaynop nopnopnopnop
delaynop_ret ret' ------------------ single letter commands -------------------------------------' command S
pasmhubtoram call #get_values ' get hubaddr,ramaddr,lencall #load161pasm ' load the 161 counters with ramaddrcall #memorytransfer ' set to group 1, enable P16-P20 as outputs and set P16-P20 highcall #busoutput ' set prop pins P0-P15 as outputs
hubtoram_loop andouta,maskP16P31 '%11111111_11111111_00000000_00000000 ' clear for output rdword data_16,hubaddr ' get the word from huband data_16,maskP0P15 ' mask to a word onlyorouta,data_16 ' send out the byte to P0-P15andnouta,maskP17 ' set mem write lowadd hubaddr,#2' increment by 2 bytes = 1 word. Put this here for small delay while writesorouta,maskP17 ' mem write highandnouta,maskP19 ' clock 161 loworouta,maskP19 ' clock 161 highdjnz len,#hubtoram_loop ' loop this many timesjmp #init ' tristate pins and listen for commands' command T
pasmramtohub call #get_values ' get hubaddr,ramaddr,lencall #load161pasm ' load the 161 counters with ramaddrcall #memorytransfer ' set to group 1, enable P16-P20 as outputs and set P16-P20 high call #businput ' set prop pins P0-P15 as inputsandnouta,maskP16 ' memory /rd low
ramtohub_loop mov data_16,ina' get the datawrword data_16,hubaddr ' move data to hubandnouta,maskP19 ' clock 161 loworouta,maskP19 ' clock 161 highadd hubaddr,#2' increment the hub address djnz len,#ramtohub_loop
orouta,maskP16 ' memory /rd high ordira,maskP0P15 ' %00000000_00000000_11111111_11111111 restore P0-P15as outputsjmp #init ' ' tristate pins and listen for commands' command U
pasmramtodisplay call #get_values ' get hubaddr,ramaddr,lencall #load161pasm ' load the 161 counters with ramaddrcall #memorytransfer ' set to group 1, enable P16-P20 as outputs and set P16-P20 high call #businput ' set prop pins 0-15 as inputs so doesn't interfere with the transferorouta,maskP18 ' ILI_RS highandnouta,maskP16 ' memory /rd low
ramtodisplay_loop andnouta,maskP20 ' ILI write loworouta,maskP20 ' ILI write highandnouta,maskP19 ' clock 161 loworouta,maskP19 ' clock 161 highdjnz len,#ramtodisplay_loop
orouta,maskP16 ' memory /rd high ordira,maskP0P15 ' %00000000_00000000_11111111_11111111 restore P0-P15as outputsjmp #init
' command V
pasmhubtodisplay call #get_values ' get hubaddr,ramaddr,lencall #memorytransfer ' set to group 1, enable P16-P20 as outputs and set P16-P20 high call #busoutput ' set P0-P15 as outputs
hubtodisplay_loop andouta,maskP16P31 '%11111111_11111111_00000000_00000000 ' clear for output rdword data_16,hubaddr ' get the word from huband data_16,maskP0P15 ' mask to a word onlyorouta,data_16 ' send out the byte to P0-P15andnouta,maskP20 ' ILI write loworouta,maskP20 ' ILI write highadd hubaddr,#2' one worddjnz len,#hubtodisplay_loop
jmp #init ' set pins to tristate' variables
pasm_n long0' general purpose value
data_16 long0' general purpose value
ililow long0' low data byte
ilihigh long0' high data byte
red long0' red, green blue variables
green long0
blue long0' constants
Zero long%00000000_00000000_00000000_00000000' used in several places
maskP0P2low long%11111111_11111111_11111111_11111000' P0-P2 low
maskP0P20 long%00000000_00011111_11111111_11111111' P0-P18 enabled for output plus P19,P20
maskP0P18low long%11111111_11111000_00000000_00000000' P0-P18 low
maskP16 long%00000000_00000001_00000000_00000000' pin 16
maskP17 long%00000000_00000010_00000000_00000000' pin 17
maskP18 long%00000000_00000100_00000000_00000000' pin 18
maskP19 long%00000000_00001000_00000000_00000000' pin 19
maskP20 long%00000000_00010000_00000000_00000000' pin 20
maskP22 long%00000000_01000000_00000000_00000000' pin 22
maskP16P31 long%11111111_11111111_00000000_00000000' pin 16 to pin 31
maskP0P15 long%00000000_00000000_11111111_11111111' for masking words
maskP16P20 long%00000000_00011111_00000000_00000000
maskP0P20P22 long%11111111_10100000_00000000_00000000' for returning all group pins HiZfit496
Tried turning the serial speed down. I still can't decipher the output from "t a". looks like gibberish:
OK, fixed that one! Now should I take the Load161 and Set137 and "stuff" them into the rd-wr? Do I need to re-arrange the variables? Any other thoughts. You alluded to there being more than that but did not say what. Your help is MOST appreciated!
' Pass pasm_n = 0- 7 come to this with P0-P20 and P22 tristated and returns them as this too
set137 ordira,maskP22 ' pin 22 is an outputandnouta,maskP22 ' set P22low so Y0-Y7 are all highordira,maskP0P20 ' pins P0-P20 are outputsandouta,maskP0P2low ' set these 3 pins loworouta,pasm_n ' set the 137 pinsorouta,maskP22 ' pin 22 high
set137_ret ret' return
load161pasm ' uses vmaddrmov len, line_size ' make a copy of line_size AND.shr len, #1' devide lenght by two for word-byteorouta,maskP0P20 ' set P0-P20 high ordira,maskP0P20 ' output pins 0-20mov pasm_n,#0' group 0call #set137 ' set the 137 outputandouta,maskP0P18low ' pins 0-18 set loworouta,vmaddr ' output addres to 161 chipsorouta,maskP19 ' clock highorouta,maskP20 ' load highandnouta,maskP19 ' clock lowandnouta,maskP20 ' load loworouta,maskP19 ' clock highorouta,maskP20 ' load high
load161pasm_ret ret
stop jmp #stop ' for debugging
memorytransfer ordira,maskP16P20 ' so /wr and other pins definitely highorouta,maskP16P20
mov pasm_n,#1' back to group 1 for memory transfercall #set137 ' as next routine will always be group 1ordira,maskP16P20 ' output pins 16-20orouta,maskP16P20 ' set P16-P20 high (P0-P15 set as inputs or outputs in the calling routine)
memorytransfer_ret ret
busoutput ordira,maskP0P15 ' set prop pins 0-15 as outputs
busoutput_ret ret
businput anddira,maskP16P31 ' set P0-P15 as inputs
businput_ret ret
delaynop nopnopnopnop
delaynop_ret ret'----------------------------------------------------------------------------------------------------'' rd_cache_line - read a cache line from external memory'' vmaddr is the external memory address to read' hubaddr is the hub memory address to write' line_size is the number of bytes to read''----------------------------------------------------------------------------------------------------
rd_cache_line
' command T
pasmramtohub
call #load161pasm ' load the 161 counters with ramaddrcall #memorytransfer ' set to group 1, enable P16-P20 as outputs and set P16-P20 high call #businput ' set prop pins P0-P15 as inputsandnouta,maskP16 ' memory /rd low
ramtohub_loop mov data_16,ina' get the datawrword data_16,hubaddr ' move data to hubandnouta,maskP19 ' clock 161 loworouta,maskP19 ' clock 161 highadd hubaddr,#2' increment the hub address djnz len,#ramtohub_loop
orouta,maskP16 ' memory /rd high ordira,maskP0P15 ' %00000000_00000000_11111111_11111111 restore P0-P15as outputsanddira,maskP0P20P22 ' tristates all the common pins
rd_cache_line_ret
ret'----------------------------------------------------------------------------------------------------'' wr_cache_line - write a cache line to external memory'' vmaddr is the external memory address to write' hubaddr is the hub memory address to read' line_size is the number of bytes to write''----------------------------------------------------------------------------------------------------
wr_cache_line
' command S
pasmhubtoram
call #load161pasm ' load the 161 counters with ramaddrcall #memorytransfer ' set to group 1, enable P16-P20 as outputs and set P16-P20 highcall #busoutput ' set prop pins P0-P15 as outputs
hubtoram_loop andouta,maskP16P31 '%11111111_11111111_00000000_00000000 ' clear for output rdword data_16,hubaddr ' get the word from huband data_16,maskP0P15 ' mask to a word onlyorouta,data_16 ' send out the byte to P0-P15andnouta,maskP17 ' set mem write lowadd hubaddr,#2' increment by 2 bytes = 1 word. Put this here for small delay while writesorouta,maskP17 ' mem write highandnouta,maskP19 ' clock 161 loworouta,maskP19 ' clock 161 highdjnz len,#hubtoram_loop ' loop this many timesanddira,maskP0P20P22 ' tristates all the common pins
wr_cache_line_ret
ret
pasm_n long0' general purpose value
data_16 long0' general purpose value
len long0' copy line size and devide by two for byte-word offset
maskP0P2low long%11111111_11111111_11111111_11111000' P0-P2 low
maskP0P20 long%00000000_00011111_11111111_11111111' P0-P18 enabled for output plus P19,P20
maskP0P18low long%11111111_11111000_00000000_00000000' P0-P18 low
maskP16 long%00000000_00000001_00000000_00000000' pin 16
maskP17 long%00000000_00000010_00000000_00000000' pin 17
maskP18 long%00000000_00000100_00000000_00000000' pin 18
maskP19 long%00000000_00001000_00000000_00000000' pin 19
maskP20 long%00000000_00010000_00000000_00000000' pin 20
maskP22 long%00000000_01000000_00000000_00000000' pin 22
maskP16P31 long%11111111_11111111_00000000_00000000' pin 16 to pin 31
maskP0P15 long%00000000_00000000_11111111_11111111' for masking words
maskP16P20 long%00000000_00011111_00000000_00000000
maskP0P20P22 long%11111111_10100000_00000000_00000000' for returning all group pins HiZfit496
Test3
Random Addr Pattern Test32 KB
----------------------------------------------------------------
cccccccccccccccccccccccccccccccc
w
r
Test Complete!
CACHE TEST> t 4Test4
Pseudo-Random Pattern Test -1656445 KB
----------------------------------------------------------------
w
r
ERROR at $00000000 Expected $174b43e3 Received $cd32dcc6
Address $00000000 0K Page
re #1. I've looked all over and I can't find it. I'll do some testing in the spin driver shortly, but the circuit appears correct, no open connection. No short to ANYTHING! Tested both boards with same results?
Well at least you verified that. So, for sure it's a driver problem.
re #2. It looks like this is the first candidate for fixing. Any suggestions how to approach a fix?
The length division is necessary because you are writing/reading 2 bytes at a time.
Actually, it's very curious that the data looks like it's decrementing.
Need data. Do the following:
1. Fill the cache line with incremental pattern.
CACHE TEST> i 2000
Incremental Pattern Test8 KB
----------------------------------------------------------------
wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww
rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr
Test Complete!
' check address 0 for 00000001
CACHE TEST> r 0
R 0000000000000001' flush address 0 by reading 2000
CACHE TEST> r 0' check address 0 again - what value do you see?
CACHE TEST> r 0
hmm, it seems as if the cache is not flushing on second "r"
CACHE TEST> i 2000
Incremental Pattern Test8 KB
----------------------------------------------------------------
wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww
rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr
Test Complete!
CACHE TEST> r 0
R 0000000000000001
CACHE TEST> r 0
R 0000000000000001
CACHE TEST> r 0
R 0000000000000001
*edited*
I have done my best to verify proper operation. I'm currently stepping through addresses looking for anomalies.
Hi David, sorry about that. I'll post the entire driver again.
{
Skeleton JCACHE external RAM driver
Copyright (c) 2011 by David Betz
Based on code by Steve Denson (jazzed)
Copyright (c) 2010 by John Steven Denson
Inspired by VMCOG - virtual memory server for the Propeller
Copyright (c) February 3, 2010 by William Henning
For the EuroTouch 161 By James Moxham and Joe Heinz
TERMS OF USE: MIT License
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
}CON' default cache dimensions
DEFAULT_INDEX_WIDTH = 6
DEFAULT_OFFSET_WIDTH = 4' cache line tag flags
EMPTY_BIT = 30
DIRTY_BIT = 31PUBimagereturn @init_vm
DATorg$0' initialization structure offsets' $0: pointer to a two word mailbox' $4: pointer to where to store the cache lines in hub ram' $8: number of bits in the cache line index if non-zero (default is DEFAULT_INDEX_WIDTH)' $a: number of bits in the cache line offset if non-zero (default is DEFAULT_OFFSET_WIDTH)' note that $4 must be at least 2^(index_width+offset_width) bytes in size' the cache line mask is returned in $0
init_vm mov t1, par' get the address of the initialization structurerdlong pvmcmd, t1 ' pvmcmd is a pointer to the virtual address and read/write bitmov pvmaddr, pvmcmd ' pvmaddr is a pointer into the cache line on returnadd pvmaddr, #4add t1, #4rdlong cacheptr, t1 ' cacheptr is the base address in hub ram of the cacheadd t1, #4rdlong t2, t1 wzif_nzmov index_width, t2 ' override the index_width default valueadd t1, #4rdlong t2, t1 wzif_nzmov offset_width, t2 ' override the offset_width default valuemov index_count, #1shl index_count, index_width
mov index_mask, index_count
sub index_mask, #1mov line_size, #1shl line_size, offset_width
mov t1, line_size
sub t1, #1wrlong t1, par' put external memory initialization herejmp #vmflush
fillme long0[128-fillme] ' first 128 cog locations are used for a direct mapped cache tablefit128' initialize the cache lines
vmflush movd :flush, #0mov t1, index_count
:flush mov0-0, empty_mask
add :flush, dstinc
djnz t1, #:flush
' start the command loop
waitcmd wrlong zero, pvmcmd
:wait rdlong vmline, pvmcmd wzif_zjmp #:wait
shr vmline, offset_width wc' carry is now one for read and zero for writemov set_dirty_bit, #0' make mask to set dirty bit on writesmuxnc set_dirty_bit, dirty_mask
mov line, vmline ' get the cache line indexand line, index_mask
mov hubaddr, line
shl hubaddr, offset_width
add hubaddr, cacheptr ' get the address of the cache linewrlong hubaddr, pvmaddr ' return the address of the cache linemovs :ld, line
movd :st, line
:ld mov vmcurrent, 0-0' get the cache line tagand vmcurrent, tag_mask
cmp vmcurrent, vmline wz' z set means there was a cache hitif_nzcall #miss ' handle a cache miss
:st or0-0, set_dirty_bit ' set the dirty bit on writesjmp #waitcmd ' wait for a new command' line is the cache line index' vmcurrent is current cache line' vmline is new cache line' hubaddr is the address of the cache line
miss movd :test, line
movd :st, line
:testtest0-0, dirty_mask wzif_zjmp #:rd ' current cache line is clean, just read new onemov vmaddr, vmcurrent
shl vmaddr, offset_width
call #wr_cache_line ' write current cache line
:rd mov vmaddr, vmline
shl vmaddr, offset_width
call #rd_cache_line ' read new cache line
:st mov0-0, vmline
miss_ret ret' pointers to mailbox entries
pvmcmd long0' on call this is the virtual address and read/write bit
pvmaddr long0' on return this is the address of the cache line containing the virtual address
cacheptr long0' address in hub ram where cache lines are stored
vmline long0' cache line containing the virtual address
vmcurrent long0' current selected cache line (same as vmline on a cache hit)
line long0' current cache line index
set_dirty_bit long0' DIRTY_BIT set on writes, clear on reads
zero long0' zero constant
dstinc long1<<9' increment for the destination field of an instruction
t1 long0' temporary variable
t2 long0' temporary variable
tag_mask long !(1<<DIRTY_BIT) ' includes EMPTY_BIT
index_width long DEFAULT_INDEX_WIDTH
index_mask long0
index_count long0
offset_width long DEFAULT_OFFSET_WIDTH
line_size long0' line size in bytes
empty_mask long (1<<EMPTY_BIT)
dirty_mask long (1<<DIRTY_BIT)
' input parameters to rd_cache_line and wr_cache_line
vmaddr long0' external address
hubaddr long0' hub memory address'get_values rdlong hubaddr, hubptr ' get hub address' rdlong ramaddr, ramptr ' get ram address' rdlong len, lenptr ' get length' mov err, #5 ' err=5'get_values_ret ret'init 'mov err, #0 ' reset err=false=good'mov dira,zero ' tristate the pins with the cog dira' and dira,maskP0P20P22 ' tristates all the common pins'done 'wrlong err, errptr ' status =0=false=good, else error x'wrlong zero, comptr ' command =0 (done)' Pass pasm_n = 0- 7 come to this with P0-P20 and P22 tristated and returns them as this too
set137 ordira,maskP22 ' pin 22 is an outputandnouta,maskP22 ' set P22low so Y0-Y7 are all highordira,maskP0P20 ' pins P0-P20 are outputsandouta,maskP0P2low ' set these 3 pins loworouta,pasm_n ' set the 137 pinsorouta,maskP22 ' pin 22 high
set137_ret ret' return
load161pasm ' uses vmaddrmov len, line_size ' make a copy of line_size AND.shr len, #1' devide lenght by two for word-byteorouta,maskP0P20 ' set P0-P20 high ordira,maskP0P20 ' output pins 0-20mov pasm_n,#0' group 0call #set137 ' set the 137 outputandouta,maskP0P18low ' pins 0-18 set loworouta,vmaddr ' output addres to 161 chips'or outa,maskP19 ' clock high'or outa,maskP20 ' load high'andn outa,maskP19 ' clock low'andn outa,maskP20 ' load low'or outa,maskP19 ' clock high'or outa,maskP20 ' load highandnouta,maskP20 ' load lowandnouta,maskP19 ' clock loworouta,maskP19 ' clock highorouta,maskP20 ' load high
load161pasm_ret ret
stop jmp #stop ' for debugging
memorytransfer ordira,maskP16P20 ' so /wr and other pins definitely highorouta,maskP16P20
mov pasm_n,#1' back to group 1 for memory transfercall #set137 ' as next routine will always be group 1ordira,maskP16P20 ' output pins 16-20orouta,maskP16P20 ' set P16-P20 high (P0-P15 set as inputs or outputs in the calling routine)
memorytransfer_ret ret
busoutput ordira,maskP0P15 ' set prop pins 0-15 as outputs
busoutput_ret ret
businput anddira,maskP16P31 ' set P0-P15 as inputs
businput_ret ret
delaynop nopnopnopnop
delaynop_ret ret'----------------------------------------------------------------------------------------------------'' rd_cache_line - read a cache line from external memory'' vmaddr is the external memory address to read' hubaddr is the hub memory address to write' line_size is the number of bytes to read''----------------------------------------------------------------------------------------------------
rd_cache_line
' command T
pasmramtohub
call #load161pasm ' load the 161 counters with ramaddrcall #memorytransfer ' set to group 1, enable P16-P20 as outputs and set P16-P20 high call #businput ' set prop pins P0-P15 as inputsandnouta,maskP16 ' memory /rd low
ramtohub_loop mov data_16,ina' get the datawrword data_16,hubaddr ' move data to hubandnouta,maskP19 ' clock 161 loworouta,maskP19 ' clock 161 highadd hubaddr,#2' increment the hub address djnz len,#ramtohub_loop
orouta,maskP16 ' memory /rd high ordira,maskP0P15 ' %00000000_00000000_11111111_11111111 restore P0-P15as outputsanddira,maskP0P20P22 ' tristates all the common pins
rd_cache_line_ret
ret'----------------------------------------------------------------------------------------------------'' wr_cache_line - write a cache line to external memory'' vmaddr is the external memory address to write' hubaddr is the hub memory address to read' line_size is the number of bytes to write''----------------------------------------------------------------------------------------------------
wr_cache_line
' command S
pasmhubtoram
call #load161pasm ' load the 161 counters with ramaddrcall #memorytransfer ' set to group 1, enable P16-P20 as outputs and set P16-P20 highcall #busoutput ' set prop pins P0-P15 as outputs
hubtoram_loop andouta,maskP16P31 '%11111111_11111111_00000000_00000000 ' clear for output rdword data_16,hubaddr ' get the word from huband data_16,maskP0P15 ' mask to a word onlyorouta,data_16 ' send out the byte to P0-P15andnouta,maskP17 ' set mem write lowadd hubaddr,#2' increment by 2 bytes = 1 word. Put this here for small delay while writesorouta,maskP17 ' mem write highandnouta,maskP19 ' clock 161 loworouta,maskP19 ' clock 161 highdjnz len,#hubtoram_loop ' loop this many timesanddira,maskP0P20P22 ' tristates all the common pins
wr_cache_line_ret
ret
pasm_n long0' general purpose value
data_16 long0' general purpose value
len long0' copy line size and devide by two for byte-word offset
maskP0P2low long%11111111_11111111_11111111_11111000' P0-P2 low
maskP0P20 long%00000000_00011111_11111111_11111111' P0-P18 enabled for output plus P19,P20
maskP0P18low long%11111111_11111000_00000000_00000000' P0-P18 low
maskP16 long%00000000_00000001_00000000_00000000' pin 16
maskP17 long%00000000_00000010_00000000_00000000' pin 17
maskP18 long%00000000_00000100_00000000_00000000' pin 18
maskP19 long%00000000_00001000_00000000_00000000' pin 19
maskP20 long%00000000_00010000_00000000_00000000' pin 20
maskP22 long%00000000_01000000_00000000_00000000' pin 22
maskP16P31 long%11111111_11111111_00000000_00000000' pin 16 to pin 31
maskP0P15 long%00000000_00000000_11111111_11111111' for masking words
maskP16P20 long%00000000_00011111_00000000_00000000
maskP0P20P22 long%11111111_10100000_00000000_00000000' for returning all group pins HiZfit496
I just sent a test board to Steve, it should be there on Sunday. The notes on the board for Steve's reference are as follows :
# 1. Does not match *optimized clock logic* : Wired for a 74hc00 instead of a 74hc08. I can walk Steve through the changes if necessary but the logic DOES WORK.
*edit* drawn wrong, correct now
# 2. Prop Plug pin1 is Pin14 of max chip *4 pin header installed.
# 3. IC8 *just under LEDs* is the 74HC00, sorry it's not loaded.
# 4. The 4 Pin header, bottom left is +5, +3.3 and GND.
# 5.I think I forgot to load an eeprom in the socket before shipping, sorry.
That should be it. If you have any questions please let me know.
Thanks again for all your time and help guys!
# 1. Does not match *optimized load logic* : Wired for a 74hc00 instead of a 74hc08. I can walk Steve through the changes if necessary but the logic DOES WORK. Attachment not found.
Joe, Is P19 connected directly to the counter clock inputs?
Steve, the schematic was drawn wrong. Load is supposed to be clock. P20 is supposed to be P19. I will fix and update in a second, sorry about that.
P20 is the load, or-d with Group 0.
*edit*
I will work up a description for you. Schematic is posted on 109 but I will edit this post to contain text description.
P0-15 ----> Data bus
P0-18 ----> Address bus to 161s
P 0-2 ----> 137 Address
P 22 ----> 137 Latch/Enable
Comments
*edit*
I see line_size controls the number of bytes to read and write. Is there a way to make sure this is an even number? That would make things a bit easier since I could just divide this by 2 to get the number of transfers from SRAM. Then, when doing the transfer: Read a word from Ram and put in 2 bytes in hub. Or read 2 bytes from hub and put a word in RAM. Does this sound like I'm heading in the right direction?
*edit*
So far, it's mostly a "copy-paste-modify" job. It should be getting close though.
This is the overhead for the driver:
'get_values rdlong hubaddr, hubptr ' get hub address ' rdlong ramaddr, ramptr ' get ram address ' rdlong len, lenptr ' get length ' mov err, #5 ' err=5 'get_values_ret ret 'init 'mov err, #0 ' reset err=false=good 'mov dira,zero ' tristate the pins with the cog dira ' and dira,maskP0P20P22 ' tristates all the common pins 'done 'wrlong err, errptr ' status =0=false=good, else error x 'wrlong zero, comptr ' command =0 (done) ' Pass pasm_n = 0- 7 come to this with P0-P20 and P22 tristated and returns them as this too set137 or dira,maskP22 ' pin 22 is an output andn outa,maskP22 ' set P22low so Y0-Y7 are all high or dira,maskP0P20 ' pins P0-P20 are outputs and outa,maskP0P2low ' set these 3 pins low or outa,pasm_n ' set the 137 pins or outa,maskP22 ' pin 22 high set137_ret ret ' return load161pasm ' uses vmaddr or outa,maskP0P20 ' set P0-P20 high or dira,maskP0P20 ' output pins 0-20 mov pasm_n,#0 ' group 0 call #set137 ' set the 137 output and outa,maskP0P18low ' pins 0-18 set low or outa,vmaddr ' output addres to 161 chips or outa,maskP19 ' clock high or outa,maskP20 ' load high andn outa,maskP19 ' clock low andn outa,maskP20 ' load low or outa,maskP19 ' clock high or outa,maskP20 ' load high load161pasm_ret ret stop jmp #stop ' for debugging memorytransfer or dira,maskP16P20 ' so /wr and other pins definitely high or outa,maskP16P20 mov pasm_n,#1 ' back to group 1 for memory transfer call #set137 ' as next routine will always be group 1 or dira,maskP16P20 ' output pins 16-20 or outa,maskP16P20 ' set P16-P20 high (P0-P15 set as inputs or outputs in the calling routine) memorytransfer_ret ret busoutput or dira,maskP0P15 ' set prop pins 0-15 as outputs busoutput_ret ret businput and dira,maskP16P31 ' set P0-P15 as inputs businput_ret ret delaynop nop nop nop nop delaynop_ret ret
And the actual reads:'---------------------------------------------------------------------------------------------------- ' ' rd_cache_line - read a cache line from external memory ' ' vmaddr is the external memory address to read ' hubaddr is the hub memory address to write ' line_size is the number of bytes to read ' '---------------------------------------------------------------------------------------------------- rd_cache_line ' command T pasmramtohub call #load161pasm ' load the 161 counters with ramaddr call #memorytransfer ' set to group 1, enable P16-P20 as outputs and set P16-P20 high call #businput ' set prop pins P0-P15 as inputs andn outa,maskP16 ' memory /rd low ramtohub_loop mov data_16,ina ' get the data wrword data_16,hubaddr ' move data to hub andn outa,maskP19 ' clock 161 low or outa,maskP19 ' clock 161 high add hubaddr,#2 ' increment the hub address djnz line_size,#ramtohub_loop or outa,maskP16 ' memory /rd high or dira,maskP0P15 ' %00000000_00000000_11111111_11111111 restore P0-P15as outputs and dira,maskP0P20P22 ' tristates all the common pins rd_cache_line_ret ret
The writes:'---------------------------------------------------------------------------------------------------- ' ' wr_cache_line - write a cache line to external memory ' ' vmaddr is the external memory address to write ' hubaddr is the hub memory address to read ' line_size is the number of bytes to write ' '---------------------------------------------------------------------------------------------------- wr_cache_line ' command S pasmhubtoram call #load161pasm ' load the 161 counters with ramaddr call #memorytransfer ' set to group 1, enable P16-P20 as outputs and set P16-P20 high call #busoutput ' set prop pins P0-P15 as outputs hubtoram_loop and outa,maskP16P31 '%11111111_11111111_00000000_00000000 ' clear for output rdword data_16,hubaddr ' get the word from hub and data_16,maskP0P15 ' mask to a word only or outa,data_16 ' send out the byte to P0-P15 andn outa,maskP17 ' set mem write low add hubaddr,#2 ' increment by 2 bytes = 1 word. Put this here for small delay while writes or outa,maskP17 ' mem write high andn outa,maskP19 ' clock 161 low or outa,maskP19 ' clock 161 high djnz line_size,#hubtoram_loop ' loop this many times and dira,maskP0P20P22 ' tristates all the common pins wr_cache_line_ret ret
Last is the variable overhead:pasm_n long 0 ' general purpose value data_16 long 0 ' general purpose value maskP0P2low long %11111111_11111111_11111111_11111000 ' P0-P2 low maskP0P20 long %00000000_00011111_11111111_11111111 ' P0-P18 enabled for output plus P19,P20 maskP0P18low long %11111111_11111000_00000000_00000000 ' P0-P18 low maskP16 long %00000000_00000001_00000000_00000000 ' pin 16 maskP17 long %00000000_00000010_00000000_00000000 ' pin 17 maskP18 long %00000000_00000100_00000000_00000000 ' pin 18 maskP19 long %00000000_00001000_00000000_00000000 ' pin 19 maskP20 long %00000000_00010000_00000000_00000000 ' pin 20 maskP22 long %00000000_01000000_00000000_00000000 ' pin 22 maskP16P31 long %11111111_11111111_00000000_00000000 ' pin 16 to pin 31 maskP0P15 long %00000000_00000000_11111111_11111111 ' for masking words maskP16P20 long %00000000_00011111_00000000_00000000 maskP0P20P22 long %11111111_10100000_00000000_00000000 ' for returning all group pins HiZ
I assume I don't need the "get_value" since that's already taken care of? Still need to work out the byte-word alignment problem but...Result of the BSTC are
c:\Users\Joe\Desktop\Propeller\GUI\Touch161>bstc Brads Spin Tool Compiler v0.15.3 - Copyright 2008 Compiled for i386 Win32 at 08:17:48 on 2009/07/20 Loading Object skeleton_cache Program size is 1092 longs Compiled 181 Lines of Code in 0.006 Seconds
Any thoughts on how to fix the byte-word alignment issue? Do 2 transfers per loop and shift "line_size" right by 1 at the start?*edit* ok RTFM and I think I got it... I'll be back to you with the results:
So if you you take the standard XMM code for the Board of Education and just change the SD pin numbers you can run huge C programs on our board.
That simplifies things because then all the SRAM accesses are done from C code. And all the PASM part does not need to change. So all you really have to do is rewrite the PUB docmd() routine to run from C, as well as change the cog start and stop methods to the C syntax.
GCC never needs to know about the SRAM and that means that GCC does not need changing.
A few weeks back I thought a lot about using the SRAM as the cache for GCC but I really don't think we need it any more. And that frees up the entire SRAM for bitmaps and fonts and large text buffers - all of which will be handled by a C program (which will probably ultimately become a .h program). There is a Spin to C translator out there, so it may even be possible to feed routines into this and porting over the spin code we have should be even easier. The pasm part stays as it is, and the spin gets converted to C.
Have you had a chance to test the code I posted on the GUI thread and the Files thread?
http://forums.parallax.com/showthread.php?140010-Files&p=1099650&viewfull=1#post1099650
Yes it would be interesting to do the experiment. I was basing my comments on experiments we did last year with Catalina where we found in the end that caching was so efficient that the actual speed of transfers to and from the cache hardly seemed to affect the overall performance.
But, hypothetically, if one did use the sram, there are two simple routines to transfer data to and from hub. Pass to a pasm routine a single letter command to send or receive, a long for hub address, a long for ram address and number of bytes.
And I guess you need a flag somewhere in hub to say the code is using the sram or the cache is using the sram.
I don't think it will be needed though. XMMC from hub is fast, and it could be as fast as LMM when functions are small enough to fit in hub. Whenever something runs a bit slow, I find it is easier to port things over to pasm.
Is there a generic big C program we can use to test XMMC? A text based adventure program or something?
With the right device, XMMC is faster than SPIN; with the wrong device (SDcard) it is slower than SPIN. XMMC on EEPROM is faster than XMMC on SDcard.
XMM-SINGLE lets you use all of SRAM for code and data; it is usually slower than XMMC.
One of the bigger programs I've used for testing is David's EBASIC2. It works great and can quickly highlight performance differences. EBASIC2 is in the Propeller-GCC demos package.
Here's what I have so far.
'get_values rdlong hubaddr, hubptr ' get hub address ' rdlong ramaddr, ramptr ' get ram address ' rdlong len, lenptr ' get length ' mov err, #5 ' err=5 'get_values_ret ret 'init 'mov err, #0 ' reset err=false=good 'mov dira,zero ' tristate the pins with the cog dira ' and dira,maskP0P20P22 ' tristates all the common pins 'done 'wrlong err, errptr ' status =0=false=good, else error x 'wrlong zero, comptr ' command =0 (done) ' Pass pasm_n = 0- 7 come to this with P0-P20 and P22 tristated and returns them as this too set137 or dira,maskP22 ' pin 22 is an output andn outa,maskP22 ' set P22low so Y0-Y7 are all high or dira,maskP0P20 ' pins P0-P20 are outputs and outa,maskP0P2low ' set these 3 pins low or outa,pasm_n ' set the 137 pins or outa,maskP22 ' pin 22 high set137_ret ret ' return load161pasm ' uses vmaddr or outa,maskP0P20 ' set P0-P20 high or dira,maskP0P20 ' output pins 0-20 mov pasm_n,#0 ' group 0 call #set137 ' set the 137 output and outa,maskP0P18low ' pins 0-18 set low or outa,vmaddr ' output addres to 161 chips or outa,maskP19 ' clock high or outa,maskP20 ' load high andn outa,maskP19 ' clock low andn outa,maskP20 ' load low or outa,maskP19 ' clock high or outa,maskP20 ' load high load161pasm_ret ret stop jmp #stop ' for debugging memorytransfer or dira,maskP16P20 ' so /wr and other pins definitely high or outa,maskP16P20 mov pasm_n,#1 ' back to group 1 for memory transfer call #set137 ' as next routine will always be group 1 or dira,maskP16P20 ' output pins 16-20 or outa,maskP16P20 ' set P16-P20 high (P0-P15 set as inputs or outputs in the calling routine) memorytransfer_ret ret busoutput or dira,maskP0P15 ' set prop pins 0-15 as outputs busoutput_ret ret businput and dira,maskP16P31 ' set P0-P15 as inputs businput_ret ret delaynop nop nop nop nop delaynop_ret ret '---------------------------------------------------------------------------------------------------- ' ' rd_cache_line - read a cache line from external memory ' ' vmaddr is the external memory address to read ' hubaddr is the hub memory address to write ' line_size is the number of bytes to read ' '---------------------------------------------------------------------------------------------------- rd_cache_line ' command T pasmramtohub call #load161pasm ' load the 161 counters with ramaddr call #memorytransfer ' set to group 1, enable P16-P20 as outputs and set P16-P20 high call #businput ' set prop pins P0-P15 as inputs andn outa,maskP16 ' memory /rd low ramtohub_loop mov data_16,ina ' get the data wrword data_16,hubaddr ' move data to hub andn outa,maskP19 ' clock 161 low or outa,maskP19 ' clock 161 high add hubaddr,#2 ' increment the hub address djnz line_size,#ramtohub_loop or outa,maskP16 ' memory /rd high or dira,maskP0P15 ' %00000000_00000000_11111111_11111111 restore P0-P15as outputs and dira,maskP0P20P22 ' tristates all the common pins rd_cache_line_ret ret '---------------------------------------------------------------------------------------------------- ' ' wr_cache_line - write a cache line to external memory ' ' vmaddr is the external memory address to write ' hubaddr is the hub memory address to read ' line_size is the number of bytes to write ' '---------------------------------------------------------------------------------------------------- wr_cache_line ' command S pasmhubtoram call #load161pasm ' load the 161 counters with ramaddr call #memorytransfer ' set to group 1, enable P16-P20 as outputs and set P16-P20 high call #busoutput ' set prop pins P0-P15 as outputs hubtoram_loop and outa,maskP16P31 '%11111111_11111111_00000000_00000000 ' clear for output rdword data_16,hubaddr ' get the word from hub and data_16,maskP0P15 ' mask to a word only or outa,data_16 ' send out the byte to P0-P15 andn outa,maskP17 ' set mem write low add hubaddr,#2 ' increment by 2 bytes = 1 word. Put this here for small delay while writes or outa,maskP17 ' mem write high andn outa,maskP19 ' clock 161 low or outa,maskP19 ' clock 161 high djnz line_size,#hubtoram_loop ' loop this many times and dira,maskP0P20P22 ' tristates all the common pins wr_cache_line_ret ret pasm_n long 0 ' general purpose value data_16 long 0 ' general purpose value maskP0P2low long %11111111_11111111_11111111_11111000 ' P0-P2 low maskP0P20 long %00000000_00011111_11111111_11111111 ' P0-P18 enabled for output plus P19,P20 maskP0P18low long %11111111_11111000_00000000_00000000 ' P0-P18 low maskP16 long %00000000_00000001_00000000_00000000 ' pin 16 maskP17 long %00000000_00000010_00000000_00000000 ' pin 17 maskP18 long %00000000_00000100_00000000_00000000 ' pin 18 maskP19 long %00000000_00001000_00000000_00000000 ' pin 19 maskP20 long %00000000_00010000_00000000_00000000 ' pin 20 maskP22 long %00000000_01000000_00000000_00000000 ' pin 22 maskP16P31 long %11111111_11111111_00000000_00000000 ' pin 16 to pin 31 maskP0P15 long %00000000_00000000_11111111_11111111 ' for masking words maskP16P20 long %00000000_00011111_00000000_00000000 maskP0P20P22 long %11111111_10100000_00000000_00000000 ' for returning all group pins HiZ fit 496
Please advise the best place to put the "overhead" such as Load161. I'm also not sure of what tests to run in test_cache once the cache file is built. Thanks as always!*edit*
I tried "T a" and get a bunch of nonsense from the terminal?
Can you post the full .spin file? Do you have a pointer to the schematic?
Here's the fully filled out skeleton cache *HOPEFULLY*
{ Skeleton JCACHE external RAM driver Copyright (c) 2011 by David Betz Based on code by Steve Denson (jazzed) Copyright (c) 2010 by John Steven Denson Inspired by VMCOG - virtual memory server for the Propeller Copyright (c) February 3, 2010 by William Henning For the EuroTouch 161 By James Moxham and Joe Heinz TERMS OF USE: MIT License Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. } CON ' default cache dimensions DEFAULT_INDEX_WIDTH = 6 DEFAULT_OFFSET_WIDTH = 7 ' cache line tag flags EMPTY_BIT = 30 DIRTY_BIT = 31 PUB image return @init_vm DAT org $0 ' initialization structure offsets ' $0: pointer to a two word mailbox ' $4: pointer to where to store the cache lines in hub ram ' $8: number of bits in the cache line index if non-zero (default is DEFAULT_INDEX_WIDTH) ' $a: number of bits in the cache line offset if non-zero (default is DEFAULT_OFFSET_WIDTH) ' note that $4 must be at least 2^(index_width+offset_width) bytes in size ' the cache line mask is returned in $0 init_vm mov t1, par ' get the address of the initialization structure rdlong pvmcmd, t1 ' pvmcmd is a pointer to the virtual address and read/write bit mov pvmaddr, pvmcmd ' pvmaddr is a pointer into the cache line on return add pvmaddr, #4 add t1, #4 rdlong cacheptr, t1 ' cacheptr is the base address in hub ram of the cache add t1, #4 rdlong t2, t1 wz if_nz mov index_width, t2 ' override the index_width default value add t1, #4 rdlong t2, t1 wz if_nz mov offset_width, t2 ' override the offset_width default value mov index_count, #1 shl index_count, index_width mov index_mask, index_count sub index_mask, #1 mov line_size, #1 shl line_size, offset_width mov t1, line_size sub t1, #1 wrlong t1, par ' put external memory initialization here jmp #vmflush fillme long 0[128-fillme] ' first 128 cog locations are used for a direct mapped cache table fit 128 ' initialize the cache lines vmflush movd :flush, #0 mov t1, index_count :flush mov 0-0, empty_mask add :flush, dstinc djnz t1, #:flush ' start the command loop waitcmd wrlong zero, pvmcmd :wait rdlong vmline, pvmcmd wz if_z jmp #:wait shr vmline, offset_width wc ' carry is now one for read and zero for write mov set_dirty_bit, #0 ' make mask to set dirty bit on writes muxnc set_dirty_bit, dirty_mask mov line, vmline ' get the cache line index and line, index_mask mov hubaddr, line shl hubaddr, offset_width add hubaddr, cacheptr ' get the address of the cache line wrlong hubaddr, pvmaddr ' return the address of the cache line movs :ld, line movd :st, line :ld mov vmcurrent, 0-0 ' get the cache line tag and vmcurrent, tag_mask cmp vmcurrent, vmline wz ' z set means there was a cache hit if_nz call #miss ' handle a cache miss :st or 0-0, set_dirty_bit ' set the dirty bit on writes jmp #waitcmd ' wait for a new command ' line is the cache line index ' vmcurrent is current cache line ' vmline is new cache line ' hubaddr is the address of the cache line miss movd :test, line movd :st, line :test test 0-0, dirty_mask wz if_z jmp #:rd ' current cache line is clean, just read new one mov vmaddr, vmcurrent shl vmaddr, offset_width call #wr_cache_line ' write current cache line :rd mov vmaddr, vmline shl vmaddr, offset_width call #rd_cache_line ' read new cache line :st mov 0-0, vmline miss_ret ret ' pointers to mailbox entries pvmcmd long 0 ' on call this is the virtual address and read/write bit pvmaddr long 0 ' on return this is the address of the cache line containing the virtual address cacheptr long 0 ' address in hub ram where cache lines are stored vmline long 0 ' cache line containing the virtual address vmcurrent long 0 ' current selected cache line (same as vmline on a cache hit) line long 0 ' current cache line index set_dirty_bit long 0 ' DIRTY_BIT set on writes, clear on reads zero long 0 ' zero constant dstinc long 1<<9 ' increment for the destination field of an instruction t1 long 0 ' temporary variable t2 long 0 ' temporary variable tag_mask long !(1<<DIRTY_BIT) ' includes EMPTY_BIT index_width long DEFAULT_INDEX_WIDTH index_mask long 0 index_count long 0 offset_width long DEFAULT_OFFSET_WIDTH line_size long 0 ' line size in bytes empty_mask long (1<<EMPTY_BIT) dirty_mask long (1<<DIRTY_BIT) ' input parameters to rd_cache_line and wr_cache_line vmaddr long 0 ' external address hubaddr long 0 ' hub memory address 'get_values rdlong hubaddr, hubptr ' get hub address ' rdlong ramaddr, ramptr ' get ram address ' rdlong len, lenptr ' get length ' mov err, #5 ' err=5 'get_values_ret ret 'init 'mov err, #0 ' reset err=false=good 'mov dira,zero ' tristate the pins with the cog dira ' and dira,maskP0P20P22 ' tristates all the common pins 'done 'wrlong err, errptr ' status =0=false=good, else error x 'wrlong zero, comptr ' command =0 (done) ' Pass pasm_n = 0- 7 come to this with P0-P20 and P22 tristated and returns them as this too set137 or dira,maskP22 ' pin 22 is an output andn outa,maskP22 ' set P22low so Y0-Y7 are all high or dira,maskP0P20 ' pins P0-P20 are outputs and outa,maskP0P2low ' set these 3 pins low or outa,pasm_n ' set the 137 pins or outa,maskP22 ' pin 22 high set137_ret ret ' return load161pasm ' uses vmaddr shr line_size, #1 ' devide line_size by two for word-byte or outa,maskP0P20 ' set P0-P20 high or dira,maskP0P20 ' output pins 0-20 mov pasm_n,#0 ' group 0 call #set137 ' set the 137 output and outa,maskP0P18low ' pins 0-18 set low or outa,vmaddr ' output addres to 161 chips or outa,maskP19 ' clock high or outa,maskP20 ' load high andn outa,maskP19 ' clock low andn outa,maskP20 ' load low or outa,maskP19 ' clock high or outa,maskP20 ' load high load161pasm_ret ret stop jmp #stop ' for debugging memorytransfer or dira,maskP16P20 ' so /wr and other pins definitely high or outa,maskP16P20 mov pasm_n,#1 ' back to group 1 for memory transfer call #set137 ' as next routine will always be group 1 or dira,maskP16P20 ' output pins 16-20 or outa,maskP16P20 ' set P16-P20 high (P0-P15 set as inputs or outputs in the calling routine) memorytransfer_ret ret busoutput or dira,maskP0P15 ' set prop pins 0-15 as outputs busoutput_ret ret businput and dira,maskP16P31 ' set P0-P15 as inputs businput_ret ret delaynop nop nop nop nop delaynop_ret ret '---------------------------------------------------------------------------------------------------- ' ' rd_cache_line - read a cache line from external memory ' ' vmaddr is the external memory address to read ' hubaddr is the hub memory address to write ' line_size is the number of bytes to read ' '---------------------------------------------------------------------------------------------------- rd_cache_line ' command T pasmramtohub call #load161pasm ' load the 161 counters with ramaddr call #memorytransfer ' set to group 1, enable P16-P20 as outputs and set P16-P20 high call #businput ' set prop pins P0-P15 as inputs andn outa,maskP16 ' memory /rd low ramtohub_loop mov data_16,ina ' get the data wrword data_16,hubaddr ' move data to hub andn outa,maskP19 ' clock 161 low or outa,maskP19 ' clock 161 high add hubaddr,#2 ' increment the hub address djnz line_size,#ramtohub_loop or outa,maskP16 ' memory /rd high or dira,maskP0P15 ' %00000000_00000000_11111111_11111111 restore P0-P15as outputs and dira,maskP0P20P22 ' tristates all the common pins rd_cache_line_ret ret '---------------------------------------------------------------------------------------------------- ' ' wr_cache_line - write a cache line to external memory ' ' vmaddr is the external memory address to write ' hubaddr is the hub memory address to read ' line_size is the number of bytes to write ' '---------------------------------------------------------------------------------------------------- wr_cache_line ' command S pasmhubtoram call #load161pasm ' load the 161 counters with ramaddr call #memorytransfer ' set to group 1, enable P16-P20 as outputs and set P16-P20 high call #busoutput ' set prop pins P0-P15 as outputs hubtoram_loop and outa,maskP16P31 '%11111111_11111111_00000000_00000000 ' clear for output rdword data_16,hubaddr ' get the word from hub and data_16,maskP0P15 ' mask to a word only or outa,data_16 ' send out the byte to P0-P15 andn outa,maskP17 ' set mem write low add hubaddr,#2 ' increment by 2 bytes = 1 word. Put this here for small delay while writes or outa,maskP17 ' mem write high andn outa,maskP19 ' clock 161 low or outa,maskP19 ' clock 161 high djnz line_size,#hubtoram_loop ' loop this many times and dira,maskP0P20P22 ' tristates all the common pins wr_cache_line_ret ret pasm_n long 0 ' general purpose value data_16 long 0 ' general purpose value maskP0P2low long %11111111_11111111_11111111_11111000 ' P0-P2 low maskP0P20 long %00000000_00011111_11111111_11111111 ' P0-P18 enabled for output plus P19,P20 maskP0P18low long %11111111_11111000_00000000_00000000 ' P0-P18 low maskP16 long %00000000_00000001_00000000_00000000 ' pin 16 maskP17 long %00000000_00000010_00000000_00000000 ' pin 17 maskP18 long %00000000_00000100_00000000_00000000 ' pin 18 maskP19 long %00000000_00001000_00000000_00000000 ' pin 19 maskP20 long %00000000_00010000_00000000_00000000 ' pin 20 maskP22 long %00000000_01000000_00000000_00000000 ' pin 22 maskP16P31 long %11111111_11111111_00000000_00000000 ' pin 16 to pin 31 maskP0P15 long %00000000_00000000_11111111_11111111 ' for masking words maskP16P20 long %00000000_00011111_00000000_00000000 maskP0P20P22 long %11111111_10100000_00000000_00000000 ' for returning all group pins HiZ fit 496
I believe I have filled this out. The "overhead" and rd and wr cache lines *Bottom of file up* were taken from this code that's been tested good..It's a bit long, so I remove some of the portions..
DAT '' +-----------------------------------------------------------------------------------------------+ '' | Touchblade 161 Ram Driver (with grateful acknowlegements to Cluso and Average Joe) | '' +-----------------------------------------------------------------------------------------------+ org 0 tbp2_start ' setup the pointers to the hub command interface (saves execution time later ' +-- These instructions are overwritten as variables after start comptr mov comptr, par ' -| hub pointer to command hubptr mov hubptr, par ' | hub pointer to hub address ramptr add hubptr, #4 ' | hub pointer to ram address lenptr mov ramptr, par ' | hub pointer to length errptr add ramptr, #8 ' | hub pointer to error status cmd mov lenptr, par ' | command I/R/W/G/P/Q hubaddr add lenptr, #12 ' | hub address ramaddr mov errptr, par ' | ram address len add errptr, #16 ' | length err nop ' -+ error status returned (=0=false=good) ' Initialise hardware tristates everything and read/write set the pins init mov err, #0 ' reset err=false=good 'mov dira,zero ' tristate the pins with the cog dira and dira,maskP0P20P22 ' tristates all the common pins done wrlong err, errptr ' status =0=false=good, else error x wrlong zero, comptr ' command =0 (done) ' wait for a command (pause short time to reduce power) pause ' mov ctr, delay wz ' if =0 no pause ' if_nz add ctr, cnt ' if_nz waitcnt ctr, #0 ' wait for a short time (reduces power) rdlong cmd, comptr wz ' command ? if_z jmp #pause ' not yet ' decode command cmp cmd, #"S" wz ' hub to ram if_z jmp #pasmhubtoram cmp cmd, #"T" wz ' ram to hub if_z jmp #pasmramtohub cmp cmd, #"U" wz ' ram to display if_z jmp #pasmramtodisplay cmp cmd, #"V" wz ' hub to display if_z jmp #pasmhubtodisplay cmp cmd, #"E" wz ' convert 3 byte .raw format to 2 byte .ili format - hub to hub if_z jmp #rawtoiliformat cmp cmd, #"F" wz ' convert 3 byte .bmp format BGR to 2 byte ili format (same as E but order reversed) if_z jmp #bmptoiliformat ' cmp cmd, #"W" wz ' lcdwritecom in pasm, not working ' if_z jmp #pasmlcdwritecom cmp cmd, #"X" wz ' merge icon and background based on a mask if_z jmp #mergeicons cmp cmd, #"Y" wz ' change the 137 output if_z jmp #changegroup cmp cmd, #"Z" wz ' set the 161 counters if_z jmp #set161 cmp cmd, #"I" wz ' init if_z jmp #init mov err, cmd ' error = cmd (unknown command) jmp #done ' ----------------- common routines ------------------------------------- get_values rdlong hubaddr, hubptr ' get hub address rdlong ramaddr, ramptr ' get ram address rdlong len, lenptr ' get length mov err, #5 ' err=5 get_values_ret ret ' Pass pasm_n = 0- 7 come to this with P0-P20 and P22 tristated and returns them as this too set137 or dira,maskP22 ' pin 22 is an output andn outa,maskP22 ' set P22low so Y0-Y7 are all high or dira,maskP0P20 ' pins P0-P20 are outputs and outa,maskP0P2low ' set these 3 pins low or outa,pasm_n ' set the 137 pins or outa,maskP22 ' pin 22 high set137_ret ret ' return load161pasm ' uses ramaddr or outa,maskP0P20 ' set P0-P20 high or dira,maskP0P20 ' output pins 0-20 mov pasm_n,#0 ' group 0 call #set137 ' set the 137 output and outa,maskP0P18low ' pins 0-18 set low or outa,ramaddr ' output addres to 161 chips or outa,maskP19 ' clock high or outa,maskP20 ' load high andn outa,maskP19 ' clock low andn outa,maskP20 ' load low or outa,maskP19 ' clock high or outa,maskP20 ' load high load161pasm_ret ret stop jmp #stop ' for debugging memorytransfer or dira,maskP16P20 ' so /wr and other pins definitely high or outa,maskP16P20 mov pasm_n,#1 ' back to group 1 for memory transfer call #set137 ' as next routine will always be group 1 or dira,maskP16P20 ' output pins 16-20 or outa,maskP16P20 ' set P16-P20 high (P0-P15 set as inputs or outputs in the calling routine) memorytransfer_ret ret busoutput or dira,maskP0P15 ' set prop pins 0-15 as outputs busoutput_ret ret businput and dira,maskP16P31 ' set P0-P15 as inputs businput_ret ret delaynop nop nop nop nop delaynop_ret ret ' ------------------ single letter commands ------------------------------------- ' command S pasmhubtoram call #get_values ' get hubaddr,ramaddr,len call #load161pasm ' load the 161 counters with ramaddr call #memorytransfer ' set to group 1, enable P16-P20 as outputs and set P16-P20 high call #busoutput ' set prop pins P0-P15 as outputs hubtoram_loop and outa,maskP16P31 '%11111111_11111111_00000000_00000000 ' clear for output rdword data_16,hubaddr ' get the word from hub and data_16,maskP0P15 ' mask to a word only or outa,data_16 ' send out the byte to P0-P15 andn outa,maskP17 ' set mem write low add hubaddr,#2 ' increment by 2 bytes = 1 word. Put this here for small delay while writes or outa,maskP17 ' mem write high andn outa,maskP19 ' clock 161 low or outa,maskP19 ' clock 161 high djnz len,#hubtoram_loop ' loop this many times jmp #init ' tristate pins and listen for commands ' command T pasmramtohub call #get_values ' get hubaddr,ramaddr,len call #load161pasm ' load the 161 counters with ramaddr call #memorytransfer ' set to group 1, enable P16-P20 as outputs and set P16-P20 high call #businput ' set prop pins P0-P15 as inputs andn outa,maskP16 ' memory /rd low ramtohub_loop mov data_16,ina ' get the data wrword data_16,hubaddr ' move data to hub andn outa,maskP19 ' clock 161 low or outa,maskP19 ' clock 161 high add hubaddr,#2 ' increment the hub address djnz len,#ramtohub_loop or outa,maskP16 ' memory /rd high or dira,maskP0P15 ' %00000000_00000000_11111111_11111111 restore P0-P15as outputs jmp #init ' ' tristate pins and listen for commands ' command U pasmramtodisplay call #get_values ' get hubaddr,ramaddr,len call #load161pasm ' load the 161 counters with ramaddr call #memorytransfer ' set to group 1, enable P16-P20 as outputs and set P16-P20 high call #businput ' set prop pins 0-15 as inputs so doesn't interfere with the transfer or outa,maskP18 ' ILI_RS high andn outa,maskP16 ' memory /rd low ramtodisplay_loop andn outa,maskP20 ' ILI write low or outa,maskP20 ' ILI write high andn outa,maskP19 ' clock 161 low or outa,maskP19 ' clock 161 high djnz len,#ramtodisplay_loop or outa,maskP16 ' memory /rd high or dira,maskP0P15 ' %00000000_00000000_11111111_11111111 restore P0-P15as outputs jmp #init ' command V pasmhubtodisplay call #get_values ' get hubaddr,ramaddr,len call #memorytransfer ' set to group 1, enable P16-P20 as outputs and set P16-P20 high call #busoutput ' set P0-P15 as outputs hubtodisplay_loop and outa,maskP16P31 '%11111111_11111111_00000000_00000000 ' clear for output rdword data_16,hubaddr ' get the word from hub and data_16,maskP0P15 ' mask to a word only or outa,data_16 ' send out the byte to P0-P15 andn outa,maskP20 ' ILI write low or outa,maskP20 ' ILI write high add hubaddr,#2 ' one word djnz len,#hubtodisplay_loop jmp #init ' set pins to tristate ' variables pasm_n long 0 ' general purpose value data_16 long 0 ' general purpose value ililow long 0 ' low data byte ilihigh long 0 ' high data byte red long 0 ' red, green blue variables green long 0 blue long 0 ' constants Zero long %00000000_00000000_00000000_00000000 ' used in several places maskP0P2low long %11111111_11111111_11111111_11111000 ' P0-P2 low maskP0P20 long %00000000_00011111_11111111_11111111 ' P0-P18 enabled for output plus P19,P20 maskP0P18low long %11111111_11111000_00000000_00000000 ' P0-P18 low maskP16 long %00000000_00000001_00000000_00000000 ' pin 16 maskP17 long %00000000_00000010_00000000_00000000 ' pin 17 maskP18 long %00000000_00000100_00000000_00000000 ' pin 18 maskP19 long %00000000_00001000_00000000_00000000 ' pin 19 maskP20 long %00000000_00010000_00000000_00000000 ' pin 20 maskP22 long %00000000_01000000_00000000_00000000 ' pin 22 maskP16P31 long %11111111_11111111_00000000_00000000 ' pin 16 to pin 31 maskP0P15 long %00000000_00000000_11111111_11111111 ' for masking words maskP16P20 long %00000000_00011111_00000000_00000000 maskP0P20P22 long %11111111_10100000_00000000_00000000 ' for returning all group pins HiZ fit 496
Tried turning the serial speed down. I still can't decipher the output from "t a". looks like gibberish:¸£
èˆ . R„
8H6Ûºaž£²ˆég»2üꦪ>
o¬ëù
c™§é
The biggest problem is that you're trashing the line_size variable. You need to make a copy of it to your own length variable. I.e.
rd_cache_line mov length, line_size :loop ' some code djnz length, #:loop rd_cache_line ret
' Pass pasm_n = 0- 7 come to this with P0-P20 and P22 tristated and returns them as this too set137 or dira,maskP22 ' pin 22 is an output andn outa,maskP22 ' set P22low so Y0-Y7 are all high or dira,maskP0P20 ' pins P0-P20 are outputs and outa,maskP0P2low ' set these 3 pins low or outa,pasm_n ' set the 137 pins or outa,maskP22 ' pin 22 high set137_ret ret ' return load161pasm ' uses vmaddr mov len, line_size ' make a copy of line_size AND. shr len, #1 ' devide lenght by two for word-byte or outa,maskP0P20 ' set P0-P20 high or dira,maskP0P20 ' output pins 0-20 mov pasm_n,#0 ' group 0 call #set137 ' set the 137 output and outa,maskP0P18low ' pins 0-18 set low or outa,vmaddr ' output addres to 161 chips or outa,maskP19 ' clock high or outa,maskP20 ' load high andn outa,maskP19 ' clock low andn outa,maskP20 ' load low or outa,maskP19 ' clock high or outa,maskP20 ' load high load161pasm_ret ret stop jmp #stop ' for debugging memorytransfer or dira,maskP16P20 ' so /wr and other pins definitely high or outa,maskP16P20 mov pasm_n,#1 ' back to group 1 for memory transfer call #set137 ' as next routine will always be group 1 or dira,maskP16P20 ' output pins 16-20 or outa,maskP16P20 ' set P16-P20 high (P0-P15 set as inputs or outputs in the calling routine) memorytransfer_ret ret busoutput or dira,maskP0P15 ' set prop pins 0-15 as outputs busoutput_ret ret businput and dira,maskP16P31 ' set P0-P15 as inputs businput_ret ret delaynop nop nop nop nop delaynop_ret ret '---------------------------------------------------------------------------------------------------- ' ' rd_cache_line - read a cache line from external memory ' ' vmaddr is the external memory address to read ' hubaddr is the hub memory address to write ' line_size is the number of bytes to read ' '---------------------------------------------------------------------------------------------------- rd_cache_line ' command T pasmramtohub call #load161pasm ' load the 161 counters with ramaddr call #memorytransfer ' set to group 1, enable P16-P20 as outputs and set P16-P20 high call #businput ' set prop pins P0-P15 as inputs andn outa,maskP16 ' memory /rd low ramtohub_loop mov data_16,ina ' get the data wrword data_16,hubaddr ' move data to hub andn outa,maskP19 ' clock 161 low or outa,maskP19 ' clock 161 high add hubaddr,#2 ' increment the hub address djnz len,#ramtohub_loop or outa,maskP16 ' memory /rd high or dira,maskP0P15 ' %00000000_00000000_11111111_11111111 restore P0-P15as outputs and dira,maskP0P20P22 ' tristates all the common pins rd_cache_line_ret ret '---------------------------------------------------------------------------------------------------- ' ' wr_cache_line - write a cache line to external memory ' ' vmaddr is the external memory address to write ' hubaddr is the hub memory address to read ' line_size is the number of bytes to write ' '---------------------------------------------------------------------------------------------------- wr_cache_line ' command S pasmhubtoram call #load161pasm ' load the 161 counters with ramaddr call #memorytransfer ' set to group 1, enable P16-P20 as outputs and set P16-P20 high call #busoutput ' set prop pins P0-P15 as outputs hubtoram_loop and outa,maskP16P31 '%11111111_11111111_00000000_00000000 ' clear for output rdword data_16,hubaddr ' get the word from hub and data_16,maskP0P15 ' mask to a word only or outa,data_16 ' send out the byte to P0-P15 andn outa,maskP17 ' set mem write low add hubaddr,#2 ' increment by 2 bytes = 1 word. Put this here for small delay while writes or outa,maskP17 ' mem write high andn outa,maskP19 ' clock 161 low or outa,maskP19 ' clock 161 high djnz len,#hubtoram_loop ' loop this many times and dira,maskP0P20P22 ' tristates all the common pins wr_cache_line_ret ret pasm_n long 0 ' general purpose value data_16 long 0 ' general purpose value len long 0 ' copy line size and devide by two for byte-word offset maskP0P2low long %11111111_11111111_11111111_11111000 ' P0-P2 low maskP0P20 long %00000000_00011111_11111111_11111111 ' P0-P18 enabled for output plus P19,P20 maskP0P18low long %11111111_11111000_00000000_00000000 ' P0-P18 low maskP16 long %00000000_00000001_00000000_00000000 ' pin 16 maskP17 long %00000000_00000010_00000000_00000000 ' pin 17 maskP18 long %00000000_00000100_00000000_00000000 ' pin 18 maskP19 long %00000000_00001000_00000000_00000000 ' pin 19 maskP20 long %00000000_00010000_00000000_00000000 ' pin 20 maskP22 long %00000000_01000000_00000000_00000000 ' pin 22 maskP16P31 long %11111111_11111111_00000000_00000000 ' pin 16 to pin 31 maskP0P15 long %00000000_00000000_11111111_11111111 ' for masking words maskP16P20 long %00000000_00011111_00000000_00000000 maskP0P20P22 long %11111111_10100000_00000000_00000000 ' for returning all group pins HiZ fit 496
*edited*
Now I'm getting this:
CACHE TEST> t a Test 0 Address Walking 0's 15 address bits. 00007ff8 00000000 00007ff4 00000000 00007fec 00000000 00007fdc 00000000 00007fbc 00000000 00007f7c 00000000 00007efc 00000000 00007dfc 00000000 00007bfc 00000000 000077fc 00000000 00006ffc 00000000 00005ffc 00002000 ERROR! Expected 0 @ 00007ffc after write to address 00005ffc 00002000
CACHE TEST> t 1 Test 1 Address Walking 1's 15 address bits. 00000004 00000000 00000008 00000000 00000010 00000000 00000020 00000000 00000040 00000000 00000080 00000000 00000100 00000000 00000200 00000000 00000400 00000000 00000800 00000000 00001000 00000000 00002000 00002000 ERROR! Expected 0 @ 0 after write to address 00002000 00002000
CACHE TEST> t 2 Test 2 Incremental Pattern Test 32 KB ---------------------------------------------------------------- wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww r ERROR at $00000000 Expected $00000001 Received $00001fc1 Address $00000000 0K Page Cache Dump TAG TAGVAL : Cache Line 000 00000000: 00001fc1 00001fc0 00001fbf 00001fbe 00001fbd 00001fbc 00001fbb 00001fba 000 00000008: 00001fb9 00001fb8 00001fb7 00001fb6 00001fb5 00001fb4 00001fb3 00001fb2 000 00000010: 00001fb1 00001fb0 00001faf 00001fae 00001fad 00001fac 00001fab 00001faa 000 00000018: 00001fa9 00001fa8 00001fa7 00001fa6 00001fa5 00001fa4 00001fa3 00001fa2 000 00000020: 00000001 00000002 00000003 00000004 00000005 00000006 00000007 00000008 000 00000028: 00000009 0000000a 0000000b 0000000c 0000000d 0000000e 0000000f 00000010 000 00000030: 00000011 00000012 00000013 00000014 00000015 00000016 00000017 00000018 000 00000038: 00000019 0000001a 0000001b 0000001c 0000001d 0000001e 0000001f 00000020 000 00000040: 00002000 00000004 00000008 bb40cee3 00000010 275ef0bf 28c28b6a 2f3a204c 000 00000048: 00000020 39f8646e 23a92535 a388bdc2 73716fa2 10072b02 ba8a87aa ef27c72a 000 00000050: 00000040 5e040b46 e98be8d2 f29bf2b1 0eb37d2a 5faebe89 a1affbf9 918dadc0 000 00000058: 3d07ec7a 8c8bb79e 08888a8a b81ec0b3 f6d22341 8bd147c7 2ac462ad 3ca8aa22 000 00000060: 48a608a7 06980acb bce456f1 f96b7da3 b3ebc689 a92a7b00 6ace71e7 632bb28a 000 00000068: 23cab886 82c3c0c6 8ac6a2d7 ffe6b93e 36aefcbd 50e49a0e ccc582fe 58b8ff33 000 00000070: c32127b2 84c93d71 2c08ff3a 240be8f7 98fb2dce 665c1de1 9c22c2de 0aac3bf3 000 00000078: 4b00fe13 a4010e0d eec0221f b29bf269 4b830ad3 c2a305d8 335140c9 2cc9301c 000 00000080: 43fa4c5b b7fb413c aa8cebcf de0d8d2a a8d84bc5 b6a2b12b 87d1feb2 40a879ff 000 00000088: 372c5822 a38c52a5 2bb2465e 8cd400a3 2e3af830 acbf2f7d acff2bbf fdfc8a98 000 00000090: 8ff4acee 8dbbd210 2a807506 810c21f9 060bd67c 6dcf406c 892b8739 76f536d1 000 00000098: 087293b2 3ae44bfe 2f6fd162 f6f73c33 84a3cede 3043afee a27ead90 133c719b 000 000000a0: bfbebea4 d267f1ea 9db873aa c8e7b858 2c81acfc 3cc88b83 0a999fb4 fe6ef813 000 000000a8: 8292042a 11ee1cfe 14d48233 0ee8bedf 4360eb01 337d6229 ae0c80f3 1170cee6 000 000000b0: 50993eb6 6f10b3b1 ea3ea622 acfea889 caaa2c98 146d80bc c0e4bc38 cd377b68 000 000000b8: 0734b7f9 e77482e8 a92b60c5 a8f8589d d87cf1ec 2275ac0f ebb0ea46 72f2c3fd 000 000000c0: a7f3be41 cb3ffc19 80285268 be4cfe06 4f783c73 417d4e84 0b22efdc bcd18af0 000 000000c8: 97dfaba0 3aba6e38 80ad610a ab07e7ff e29aa88c 2fe3188b e32dc077 af2d3e0e 000 000000d0: e292ac73 2231fc9d 48d78ccf 36bf1bc6 8a82be7a e96ab0b0 451862c3 bc383af0 000 000000d8: 008b1ed8 a23e465c 3e83f8f7 424f22fb b71f4907 ebb832dc a83b09e0 e19ac37a 000 000000e0: b6ae49e3 0e89677b 49e8737b ebc48f2c 3efdab0a a2d44499 3f180f97 843ab9c7 000 000000e8: e43f417a 66326321 4a964eae 2aebb20b 10d77283 ce3eaa11 fefc7ce6 88e16e7b 000 000000f0: 93032174 0314fcb5 c1902d2c 12be2e32 d9cae346 ea7e67bc 2bfaf3af af7e772c 000 000000f8: 832c48ee f1c9b60e 7e30088b 4eeaf2a4 b48e8b39 842e93f4 50366ab2 89b2ae8a 000 00000100: 4cd0fe3f f88fee82 4bdc1838 4273b4b2 0f80cfe2 cd7372e8 ee2839f8 53b7e342 000 00000108: 7c8624a6 4e6f15be d0c1c8c8 ab37d22a e93f8a2a be4f9800 42ab353a d22fe293 000 00000110: 13363215 6c9e9c3b 4978e000 da6e9fdf e2fae561 6592ac92 6a8d0790 900f29ae 000 00000118: 1db5de00 8eb832da 2f39c489 681d85d4 99ef2639 09fe806c 1231a282 2f0108a0 000 00000120: cbf72917 09a42adb b0cea523 c4882ead 66eeca8b edaf183f 2ad0f6f6 bfc3085d 000 00000128: 0431eaae 3164b2cc bddf6ff8 2280a246 d0565e6e 0ceea6fb fbddd6a8 afd6a9ba 000 00000130: c32b4beb 498c0f20 ef30387a c9aed1f6 79ce571f 57f4d304 612cbcaf 5cb08f89 000 00000138: ac8fa0ee 1d83380b 046d3e2e a539d818 7f3f02a4 a15562e9 fab8e8fa 887bf283 000 00000140: ab0487f0 55ff487c aff57c27 438fe2c9 a1f4de8e 66d522a1 de9a2906 cf201ad2 000 00000148: e6d1fa98 d7590282 85a1d8b6 acf8bd13 38874a87 58e8c603 08fce010 aebf25d9 000 00000150: 890431d2 e1fcf643 f0313b9b fe17cafb 9ae43fc6 21c4f06c 2407acad 896ee280 000 00000158: 39ac65ba 161f52bf 0b91ff18 b83c726b 90ba2e82 fa0a3bbe 8b2b3f78 64f9872d 000 00000160: 264fbd7d 60be5293 0c9d82ab 69cd28b1 a1a766af b8e1c892 a0efcecb b24e8a21 000 00000168: 4a213755 c36ce16b e4a9037c 044dc726 0bf27f2c 69a618af 49efc883 e0fefae8 000 00000170: 6bee9d20 0db71e77 ceffa0e9 6d8cb68c 34c87a13 87eca47a 9cd4effb b6e7e5f0 000 00000178: be8e71cd 8ef6e4a4 9abe3b74 9eab43e2 bde0e936 47f7e981 3f6c3624 3e2e384f 000 00000180: 508ed82f 0bb1c88a cb2e62e8 f681f232 a8aea2e4 cf9d90a9 a3dfd76c 2cefd299 000 00000188: 862e8097 43813795 e9836333 2492b023 33184cce bbec40f0 e9ebae20 624aae86 000 00000190: d46513a8 b2d80f1d 000aab8a f8c3e0ae c28f2688 a16c892c 05d8f5de 8b094a6a 000 00000198: 038b3af7 b2babbb2 f97d0f31 e9ff0b3c e92cf8b6 1ca48a83 bd39494a a7066cab 000 000001a0: 6f965ee0 a92f2b75 4bbe94f6 9ffceb30 ce2bc0b8 e88a3053 eff1acbc a3000fee 000 000001a8: fd4fba09 65be7c2d 47944a95 a763f408 38214c52 b7aecab5 4bdc460d 1230aeef 000 000001b0: a8411bba 5ace72a9 b9af8a26 b23ca0a0 1ff2a3c2 97f9c00e 6a2659ce 8daf3ac7 000 000001b8: fbacaf42 528c8810 274cdeb6 2839df58 2aff9f32 1d2713b3 e7a739ec e6eee026 000 000001c0: f7e43b1f 270a63fe 46c3073e 3bab02f7 08838c6d f8c3b205 2fc7ede1 b496c884 000 000001c8: b1a16994 8037a82f c88b9bc7 a3d1e04f 5b6fe767 c7adf81a 1b364b88 c4cca416 000 000001d0: 67136cdb 7ad8f8db 0ac7212d af17c748 12306fe4 448de607 1b8f360b 6a0b82b7 000 000001d8: de1c8323 8aec8b78 8ed61e3b db6e74c9 e535bdbd fdacadbb a0b28add 4b573cae 000 000001e0: 1b3342a1 be46220a a716876f b1c7fbb2 73a2a20f 47eda88f 0f687ed7 c0e88cab 000 000001e8: 9af3c23e 03ecbb89 a56993fc e756c5fa 856b6ea5 9824c568 26fd2ba6 991aa09e 000 000001f0: d52af5a5 916ce73f c3ca2760 83648c71 23424610 c2f5a65c 34622870 013feebd 000 000001f8: a3548808 fe20f6ae 2aba768f ccc22a37 5ef145a5 04ac2e11 6ffd830e eeaf1b2f 000 00000200: e595e1c5 938a9484 b4fbd8fc 9ac94ce8 192c6ce2 f3ec2100 09519acf 66e8a3ca 000 00000208: e82a9bb5 0902f1ae b72ea53a 80bf99ac 18d5e0d8 a803f85c a5c07094 ecbbe526 000 00000210: d3cfe836 2d4b23a3 8e4002fe 88db6e4f fed1c2bc 033c43e0 8947b9da d0a10b1b 000 00000218: 4de812ec 4fa2add4 8c94ce76 93fac344 5cd3dacc 442b4436 3c5d4159 30d4f973 000 00000220: 89c0bbed d2fa6904 60a4c5a0 9788386e 28e79883 eff8eb6b e6809aee 93938468 000 00000228: 514f87a6 6d88bfc7 22070caf 372aa8af 2c6a902f 8e6b4061 5abeb814 af0d0380 000 00000230: 25fff882 0a262f2e d236c2a2 2ab3c887 586e054e 56a2e8be 22be1b20 61e4bfe3 000 00000238: 363efbc1 a54bd3b6 34a9d887 588916d1 b3b34eb1 cef29b04 fe32668b e344cc36 000 00000240: 0e924fcb fbe31c20 b2edfa1e aa0cdeb7 4b7b4c31 b9f43482 972dfa4b c26af25a 000 00000248: 89f127ca b1332d40 0cb1f0c5 68832d33 b7e8fe33 bdbbbb0d 091b8dc4 32dd842c 000 00000250: 4f5596f4 83b9792a ca3b690e 8acfb70b 7efcf164 0f2befc4 787ef983 5848c640 000 00000258: 144bb282 415dd7d6 f87b1e00 9387cef8 8f395ca3 24a32f90 abeea687 7202c287 000 00000260: 0fdb2e06 af3f95de f314e0da cfae3f97 0161b7e3 31ccbde2 98ff5ffe 2abdf017 000 00000268: d555562c 2f21ce9b 4af3483b 68bbfcdd 90071c3a 5bf0ab47 ff8cf88b 9fff7a22 000 00000270: ab020b59 3c961686 18a22ba6 032c7d3b dec825ba 8d8ca6f4 37f98a8b 8dec8ed0 000 00000278: 4950d69b b520df09 03e042fb a5df9eb6 6e4105a6 11f8222e 67c2d9ca 33d09eb1 000 00000280: b574bc08 1332131f 99fd1437 24b5022f 4406e7c3 f91c340b b8e23c50 9a2d354b 000 00000288: ba2abf3a 7c300fdb 4be12279 e01aa33a 1d4fcd35 0d589a09 7f833702 4faa5920 000 00000290: 27c6fe2e fea0dae6 25abf86e 79ac1832 c4a73bd0 fed43dca 669aa69f d3f27b71 000 00000298: c220c3fc 2ef163c2 fcdf2c62 83ba5e67 0c8a06f3 a8df9532 3deafea4 977c0bb3 000 000002a0: 5f82f4f8 2b2b8042 c8bcb3dd e0000c0d 4ff97ccb e493b593 6be11b38 552ccee2 000 000002a8: ab321337 ca6fc3e5 ca8ae5e6 2f2318c2 fc3599b5 23e8abc5 47e249b1 756a5fae 000 000002b0: 20e80adb 46938c2b 3a03d333 52eb7aa3 679f029f 8a8e91b2 87c03091 421b04b8 000 000002b8: 7f5fc5ee b2921eed 309e34ec 1dfa8ecd 2cb0aab5 9d9e01cb d3bf7438 cb633093 000 000002c0: 854ab3ac 05d30d2c b2f7e82e 4d06f9bb 2ab86a90 4f8652a5 a608170a 691cac38 000 000002c8: ef0980cb 5aa36503 c8e279cb 36802a66 ae0c63c9 9a3a2f2d 1024bc00 41b239a6 000 000002d0: d6f087b9 646c87e6 c2d35e3a 93fd3dbc fc29d8af bf034262 698e2aa3 0a3c8f61 000 000002d8: c20d84c6 68083aee 9aeb66fe 920c1920 d3e57f0f 0928ab6c 13fca8c1 d83a1b1b 000 000002e0: eb8fab2e a33e3728 45001720 c1df2b12 fdde11af ba0ff28e 40ef8ab1 e1baebda 000 000002e8: f6b71bd7 a0abdf98 5a53eaaa ae8e8cf7 ef1713cb 97378c84 7c80e421 b89ca1bc 000 000002f0: 232b09e4 5a406a52 e0f82e3d 0ace888a 6f7e7f74 99f2c7d8 05ec4928 477bb22f 000 000002f8: c34f7b0f f05f9cb8 c41b2c2e c181311e 7e01780a cd3e48cf a88aab81 ce4f6ca6 000 00000300: cc7c8a67 f0219929 ee812aad 3593af08 924af1ee 20cf20cc 3a16fcd4 b012fdab 000 00000308: 3b6f1c33 49e80a09 9aa52772 4c2b040b 082e07d4 b38b8a7b c03cf22e 202e22ca 000 00000310: 90580e6f 2b811963 64cf2049 0626c872 d1a2d2c1 b7e7c7ba d89f9d00 aa04b82a 000 00000318: bda07593 6bf0cca8 2df840a8 f417c0d0 b95d528d a4438d8f 77daad8b 7744f2c0 000 00000320: d7fe3efb 84358f28 4c0f3c1a 57bff70f 6083eba5 07fd1a21 e72227eb 90588567 000 00000328: e64f8f33 530f2bcf 8a63b0f2 a93222ea 6a38267b 821cf3ce 43e7552c 72beef68 000 00000330: 43c8f6d8 4493322c 61a76730 fed4224c 358e1ad3 a39ef1ec 725aabc6 504ef163 000 00000338: 2ee4e8ca 9d762fd2 abc0febb e554882e 46b0211b 315effbc a827b65c cc8d0a9a 000 00000340: 00e9887c e7f90331 fdae28f4 aed37acf 6bbbc3e1 b06c6833 aa020f5a 6b444534 000 00000348: 2e0856a6 aea9dcc2 095889ca 38be2d2d b59e3b7d bdf5d7c9 819821e3 1363be3f 000 00000350: aa56bfa2 1ed252a3 821a6072 f8c641ef e46acd53 8a43e29b ebc1ad25 d014aac3 000 00000358: 1fdeb63d 5b6101c3 c41ed00c c3c6ae77 3f734e24 3c85ea5f ae3effe8 b19bea28 000 00000360: 02a32b12 1884ab05 083431fb 41e6ae2f f1cb2784 0ca013cb e056a2eb 97afb438 000 00000368: bfbebc01 c7b62ace fe3d6f8a 81ca8806 0756801c fecea9e3 2aaffdea ba6a27a4 000 00000370: a77f4480 a09f8c47 f2ca5ca3 8aba4395 2cb8149a 5a526541 ec088bf7 b76a1e1a 000 00000378: 30ef4848 0e0827d5 e816fabc 710eafae 716b0398 b0e8838d ba7b1f3a a03aff80 000 00000380: c30a903a 0c4b4f39 ce9ef0eb 20db8102 031fb0cd 04b26d1d bb1f02b4 094fda64 000 00000388: 323c106c 8af83bd3 8eef27a8 040e7f0d a63f38fe c225fac2 3bf11f84 819d8f3a 000 00000390: a1ae97a1 c2479a5e ffb6af00 74949080 e0ddd0ee f2189efa f9eaec56 b60e5cd1 000 00000398: 7aa87027 affe7d51 54e2cec1 2e40ba03 ce696fa0 b4193ec2 7e051867 cad1da8f 000 000003a0: cbb34700 e7de2813 0bdff502 6adab429 a7e9bb02 fbe4a09b 2ad780a3 b1e2748a 000 000003a8: d8ec50f7 a2c6af9e a7f01f00 2383faeb 38aa23ad c212d66e ab198ab8 eb20cf8c 000 000003b0: ff392c92 0c07be5e 8fcaed03 88bf30e5 fbefb1f5 dec30c94 3796eb0f da0938a8 000 000003b8: 61ea487b 207fd0bc a83e8ece 880e961e f8511d33 451ba428 bdd0d64b ec23a80c 000 000003c0: b0fa6722 e94a4cf3 833a0c01 401be9a2 21621ff2 e03e7be6 0c97a433 a0cdaa6a 000 000003c8: e3b27bf4 94a51cc7 4cacbb90 2fc59bb8 5e507daa 350d0898 0f486ec3 82d28641 000 000003d0: 91a2d3a2 d0b71ebd 9ceea086 330e222a f1daec02 9bfac83c 31e9ab35 eb63f873 000 000003d8: 4bba3110 f74e013e 18968aca ea3277ae d92b6440 17ece774 e80805ea 9b30ce0b 000 000003e0: c433d0ca 7ab8899d ac5dca9f cd8bac24 bbcd7ac9 ee9bfab7 f1a20467 c8840860 000 000003e8: 0045382b 0e882f50 acb21a12 e28b8323 82c14e94 a07824ca 2aaab0bf 66bcddd1 000 000003f0: add9ef0f 27322ae2 6c958a73 328b2eca 596d2e3a 24ffba47 b2181e85 e4affaee 000 000003f8: 475ad964 d8b2ffab 98f9dad4 923afbbf 03443ab8 6681fd73 c2410eaa 807beb87 000 00000400: b75fc127 88d44af4 70a9aa40 6cc356ed 0bc1c643 32eaf4af a0918027 9b4cfe7e 000 00000408: 9be6f23a 9124a7ff 8d9fb580 72ba2bbb 630ccbdf d8a84571 899a9ce2 f37d42ba 000 00000410: 473bf5f8 c32d1800 efa3b046 e6dc188c ec36108e ea80ac1c 6a8e7600 001092a0 000 00000418: 8baddf0c 328894d0 0f0b5abf 3121e312 c0c4af29 85a4c2f7 8ac60bc8 a009aba3 000 00000420: c44cb93f e83c8310 a19363bc c2fb0cc8 0d925945 bf92f971 ce5ac3d2 d3708bff 000 00000428: e1988c3d ceecac78 b0a4bc6d cde5f2d8 fa89f1e4 73634230 a20b74a8 8fcbd3ce 000 00000430: 9eefb867 223b0bae 2608cea1 996fe86b 64c973ab ba09f464 87eaaa10 d751878c 000 00000438: 05fd5372 c6fb8061 bfa96ac3 e689fba6 9f422ce7 4e3f8fec f080a267 ea362f11 000 00000440: 3d66dc68 031de9b0 8c53589a 828f419f 34d1b0ba 80233c9d f9a723b4 f4cae51d 000 00000448: 48c87d23 802eaa66 ae7fcee0 d3d2c0c5 c4a0e3de 9f986380 2a04ab8f fb3baa12 000 00000450: 4d094cb4 db8fa984 19b29e9d e822cab8 a24dc13c 0ba8bb21 670380c7 3a8a89a1 000 00000458: b33a0e9c dfce630b 30eb7c91 8d2f3433 6fb58388 ee2fc70a 3a107fa2 feee7e70 000 00000460: 502596f1 2c369aa3 70ed5abe b29d885c 87e66840 6aa9b903 eba130ba 0e4df4aa 000 00000468: 0eb94f00 820f6b42 b8f900d6 acc06006 c52dfbe0 04e520a7 2c55dd2e 3b6b8c8b 000 00000470: f3d2901b f7c0faab 7123ab7a 9a300182 bc3309d3 0ca379c4 f990e3bf c8db57b3 000 00000478: 957a1538 304bde29 e8e0f931 acb54fff e71deb6a b302a3a7 180834ee 83ed50e6 000 00000480: c1c11e38 ea041c32 7c5a99e8 390d38b3 550bd9cc 65802e3c 6af78bb8 3a877b03 000 00000488: 0a3ab49f 10800b1e 2da2bf21 8be8b832 ce842b63 cfdf6b46 69ae2a26 cc509bf0 000 00000490: 8faaae02 0bff8d6c 242debd5 893430bc e2fb314e 9ad49561 94c87aab 99886889 000 00000498: 303b0f12 676f9836 c210e038 9c8b7abf cd3a939e 0879c2a8 e93f1e73 b6dd4303 000 000004a0: b2f2dfba 0e31b4eb ef463485 aefacfcb 54c9515e 873dab21 a836a134 9e273a00 000 000004a8: 681d557a c12885ce e04e2128 0e30c968 b2f0fb53 ba336ca8 e3b0b68f 436cebcc 000 000004b0: 6f8eaa8b f0516b50 7a860693 83a8092e fdf810f7 291f330c 6e98cc8d 7cdc4ba4 000 000004b8: 3ec44c8e 3e29be65 c92ce80c 9e30622b aa907ee4 f5173fff 89928689 eb93ed78 000 000004c0: 48f5b639 c0fb1bff 5de4d424 eb8131bf 3ac20f57 be42d7ff 5cb684cc e6388eeb 000 000004c8: 90fbf193 c3d8738e 6593ba83 fc6407a6 a0b2eecc cb76bff7 723acf36 8cb5494c 000 000004d0: c7bea573 d370ecce 2ea8e29b ce880a2f e6d00979 9aeecc43 b836d4d9 b705788f 000 000004d8: 0101a331 45c6f20a e0eacad3 893f102a 2b14cdee aa7026ff 2df45ce8 e737b61c 000 000004e0: 0adb2dd0 60bd85bd c86b901b ba9c028a 2aaa93e3 c64f7718 ac76211d 691b952a 000 000004e8: 8ea4e548 65c4c711 165a929a 12195733 0c09e278 10f151ef 44345800 ff20af4b 000 000004f0: 26ff2f28 48e4054a 8b043102 cf5b3822 9a099a57 ccf8e9fb 00a686a2 f9f0c097 000 000004f8: a7ccb680 fa1cdf1a 4c8397c3 62156a90 c7c0fe83 a1edfb26 0b2007ea a8434bba 000 00000500: f7e10d5b 21030189 ed0102ed bc27d312 7bad5364 0f0cd8b8 a4bff2d7 321ac618 000 00000508: b88b0d76 8fe46f3e 3e03900a 37cd8d68 d0ec9605 46978c0a 101faacb 3ebe7ffc 000 00000510: b6ca2c7e 9074a2fb f9eef77e c40c07ea 76410bb2 8616ba6f 5a9364f2 eac862ee 000 00000518: 48d38110 9bf81317 317e2fdf 00aaa406 fbfce8e3 27ec61cf 6a60421f 2f230980 000 00000520: 1c1aefe5 6bb39be1 efd3b08e ed2a97b2 ef1e0e32 fb7a94f4 3602f2e8 d2cccf13 000 00000528: b4eadb2b 52b6fdbf 68fae101 6a8ef1f0 053a0720 ce6179f7 cafcc79c fea4fbeb 000 00000530: 07830ba1 c675e87f da3d69df 2c48f80c 131899ca 56718a0d cc67e298 e0bd643c 000 00000538: 16598d9b 2d906098 5a322b6b a6230e0c c11ff4fa 8eecf2b9 f130f4f1 de336886 000 00000540: 894b921c 93ea6069 2deda8be d0df47bb e8ff4cb8 c6b13868 84e0628b 809fd699 000 00000548: 052082cc d035af67 3c9fd88f a8f8f1bc ce5fecca a5db20b9 ffadd60e 0ba4f008 000 00000550: b903a907 56e3bb87 7704d9c1 a80e09d2 e4bec0a7 2faf13da 8a248962 5a94e2bc 000 00000558: 24ce48f3 ed43da5f 7791e0ce 81b85cd6 d80f33a8 60090f82 a81730e9 eed40ec3 000 00000560: 2aa3a8bf b028cce2 604ce16c cfce5aa1 f1d85e52 6bcd8290 ed20258a 2e4fee82 000 00000568: 82fbb13e d5aa322a 000a4b19 10a02432 72dc7dbc b356c066 52de9f6f dea588fd 000 00000570: fc2d3fe6 06798510 f759ba12 e3ef0bd0 6e892d18 c2cca03c 0664d18b f39ff21f 000 00000578: 7d9c0944 29b4cc11 dfb1031c 82ecf23f b0b41de2 6be03541 ca8497d0 e7382270 000 00000580: b03bf204 cbe4bece 64b38a01 a87d0f23 d45bba37 cde0cb71 06625c84 854eb208 000 00000588: 182b3ca2 d0e9baf2 a907d736 2d088e3d bfeccc6b 89cc76d6 0efa12f5 4b430bfb 000 00000590: 1a11fece 732c2830 ee3ca47e 2a8ef8a0 ac968b21 f12944b2 d7c18e91 0288c2ba 000 00000598: bdc22bf9 cae0093f 83670e86 86660cab e39b28aa 43873e46 826730ee aaf7f37c 000 000005a0: 78be524f cc662aba 8e1f03de 4b0a6a9e f67b00c2 aebc6399 2f5235c2 173aac61 000 000005a8: ee8a3e24 380f3a40 a1e21fd2 e67c0be8 1123a858 a541d644 2efcf898 f80b1f10 000 000005b0: f1f8cc8b 408dd113 3af89d80 47da034c f67436a0 afe6c2c3 573ebea0 ea9741da 000 000005b8: 37fd3fff de02e161 ac8294a1 98409917 08838496 b64098ce 387078bd 40e2c2a7 000 000005c0: 842f82ec 044e01d0 b62cd299 79744ff2 8de00cc4 23ca3e6e af2929ea 1b8235b3 000 000005c8: bbfa384c d5fa1932 2ad18e7a ee76221e 6f1eb011 0837e8cb eec7bddf add9243c 000 000005d0: 6b36ef31 08008fc6 e8e0e066 50a0aad6 f248c4af 0ea82025 92a91eb3 b0f8cbbe 000 000005d8: a4771621 4fa0f0a6 9e2272d2 32686012 6246335c e2105882 083acbd0 0585e6a7 000 000005e0: 3009adbe f28ce76f bb84ec6c df4de3f8 390427ee 504bab2c 49a1e18b 8d041630 000 000005e8: f024d23f bb1bcf28 9981faeb eba6c966 5efe8a4b 680ea86b 207abb28 b011e02e 000 000005f0: 1ecd96d9 151c733c c35ef8e3 e196ac2e f454c60f 0e633eef 3e812aeb eca2d4e0 000 000005f8: cf4ad620 820bb23e f3309222 286aa429 fc58bb28 27a212a2 d7303776 269de73d 000 00000600: 9c502590 7c20e447 ad8fc11a 4c90fcb0 bd0119f4 daed5ae8 b8a30ec7 c35ca682 000 00000608: 7f10c32e 43e7210f e3ca2cb0 803bffe9 6e8ebf0a a3b78fa0 ffb2b612 22cef9ff 000 00000610: f4ba2284 29f7ad34 0eb130cb 29beff7f f1c36086 01c78dff b21cdd1f e603fa93 000 00000618: 62e8ac6f 5e9a32c5 66bdcf9e eaa6d1ee c283e49e 1dd84b62 38ab4bbb 509e9f20 000 00000620: 6e4efe35 3eee28a3 c200ea3e 8ef3b013 3fe5ccaa 835c09c8 aee6f825 f747a81d 000 00000628: 9923b7ef 0d7c0e8b 23ab5ce0 cdb04012 98165eda 96480370 7071f462 68a099be 000 00000630: 6279f07e ec0eed5f cffb67c3 3089807d 1816722c 36b7faf0 3c30f13d 0cdcb3a4 000 00000638: 65bad80c fb8f6ce3 6cb2a801 d42fc647 13a32082 30ba03e1 63ffbabd b0e842f6 000 00000640: 9cf0efba 03dd8df9 42076e32 a8362841 c0d008c9 8b8df612 95418a62 88e7cd7f 000 00000648: 89c9201a 20c5176c fef57a00 a031d827 b8877889 2ef3e606 a21f2470 db09076b 000 00000650: 3772600a 99fb789b 541f82c8 604a27bc 8f10e9ee 4c9ea1aa 0b030a89 350bdc7c 000 00000658: 3807e6f6 db88893a 7bada167 eae898f2 0e83eb3a 4511fe54 8d3aac88 8c92a488 000 00000660: 751f69cf 82c3a9bb b4ce2abc 4322d1c1 aa108ee4 856e6a84 8ec4e82e 8cc3aac4 000 00000668: 92a8bc0d 8aed2356 5c467ce6 011696c8 6facef93 b4be52a9 706a9ef2 ac8976ac 000 00000670: 51f3aa0d 074f4e5d bb1a85c0 ded2e4f1 bd060e19 fc5365f0 197a293c eaec4b4a 000 00000678: eb348aa7 c0102c2f b811059a feebbb9b ef20773e 3ff34038 4d6d82f1 cef0afad 000 00000680: 137949e0 d78389ce 9ae03c22 97ce4c51 9e2d1124 fab08fa8 5922aae8 dfd0a890 000 00000688: 79af7d81 06b8a9fc 13885330 72cf50fc f438c31b 0c05d9b8 f77c1aa3 c5362f2b 000 00000690: 10c43bcc 6998e03d f82bb6cb 273c3bf3 6f501377 fb30e278 229fc865 ac289124 000 00000698: 82fab434 1f9a66b3 15dff83c de39338c 4631049c 79b7caf8 40231a5b 64f82224 000 000006a0: a04ca31c b851a60b 604b2cb5 7281b918 82ee3cc6 616ebfc2 0ca4bdad f900ddaa 000 000006a8: 4a8fafa3 643201e4 37a8b9b9 4fb808fe 2a566d25 cf4d9c86 aba2c78c 8aba02e2 000 000006b0: 17469a0b b3de1253 e52bb08a 2aef62c4 5b4be99e 8a7e702a aa9aeb19 b4f9ee98 000 000006b8: 15d18663 cf983d2a 9001ae67 962e771a ad0bf4be 4000aef8 7adbb07a 2c8cb2bb 000 000006c0: f2fc9207 a12f3eae 6817fe08 3fe87ef1 cea09f19 f98e3e2d 583ba3fa ecb7bc8e 000 000006c8: aac18bb8 a93bc19c 926fd183 4ab0bce1 a207b7db 74879dbf 09bd4991 daea2bf6 000 000006d0: e44b0874 8098e8d3 ed6efba3 69b09b5b 9fcb75e0 9f04ed6e deb33a3b fa43940c 000 000006d8: 340cc89b 87b04ba3 fa4653a7 aeb90683 99aea49f 3d7fb28a ea80c2a4 93b353d8 000 000006e0: d32168c6 2b74f52c 9f94a8b2 cb941ec6 b7eebfaf f8cc5bf8 12e04290 b490a904 000 000006e8: 8957700c 19f72a5a a9317f94 23089bc8 fce0890e ad912cba b8eaf312 a73b7ffa 000 000006f0: d61f2ea4 df7b81ac 8ffb40b1 b8ec8c2a da19271d c874cc4e 3a638729 5aa8bb0d 000 000006f8: ed86f9b2 7f81913e ba43e27f 3bab18b6 7f7c17bc 7c67f374 87e3add1 a120a38f 000 00000700: 1b2db04a bb9b9bac 454a08de 22132ff2 b4ec3a1b ba1afec0 6efb93a9 3b22e24f 000 00000708: 28f4f319 26cafa28 66480c6a 2beefaee 1e328902 09c6ac82 b23530c8 bad2ea4e 000 00000710: 387a0722 399817a0 6bb68304 861a9346 a71000bf b93b39bf 6ea40a08 3283381f 000 00000718: 068d1761 0de0a736 3b3427e6 daf0fb2f dfb34998 88571fe1 28cfe39d 6a89d279 000 00000720: 1c222b49 ceb8f5ba dc68c5b7 358a3e27 ffacd4f2 b715fa80 2dedffde 1b3e2f31 000 00000728: fe8a2070 a3f6e09b 486fd8c0 e4f5e028 38306895 5a837eb3 fbb0abd4 fbdbe477 000 00000730: e3e2fcc0 4e36cc28 ced0db82 559904cb 6444aac2 692e05ec e7d75ef6 48f12927 000 00000738: 6b3a6467 eb2fe619 0eab8c13 ba964adf 07278658 70f0092b feaf3fca 932496f0 000 00000740: 7a86e25c 5a81702a 14ef98d3 bd612dd0 f4037dfb d1bcba3f 4470f28a c66cfa6b 000 00000748: 62add2f6 eeb2bf1a 8cff4bb6 bce20e7e ac84ffbd fddb8ea0 1d7cabad 24683007 000 00000750: 26999283 f36e57b3 157d6562 b12ba822 7b6e98aa 2711bf84 a5a3fc36 9a82a6e2 000 00000758: 78f306ee e282ce8e 87e6fbfb 7a8e927c 5f369b81 10aaf132 e70ff876 07257bce 000 00000760: b62aaa80 bb927a53 c03cb0a1 eb889af3 b706cbea e0dd0183 b82b18ec c15c254a 000 00000768: 28f896bf a7a8803f 34683cac 48da3277 385e0612 1f3e49dc 44ef08bb aaf335ac 000 00000770: 2be0ede2 c6307603 2895c62e cc497bcc f89db76a 23b84fb8 8828246f e2cd98de 000 00000778: 6dec9220 eb443ee8 41b8802e 32b07ab8 2202ca23 a7890f0d ececa5fb 2ed94f3f 000 00000780: febac8e8 dc0cd791 a9f4a5c7 0e6efeca 1dc3fe53 a00ce0ec 933dd4bc cdd3379e 000 00000788: 6b57bf14 6f5e4a30 feae6c37 ee4ecb65 9bb2b034 f68b9dfc 8a2807ea 85a7a3d8 000 00000790: 2b1807c9 e6bee028 b26c38be 6cbb83b9 175ea53b 6221fef0 bc3f30f9 8e387b4b 000 00000798: 2e23716c 700de70a a11df27b fb4aa61b bd29a3f6 e0c8ae2b 2f48c36b a84ffa2c 000 000007a0: 181e3420 b370ab2b 8ef3ce6a 223fc7a8 32f1a8e6 ef828bbc 83675fe8 25a43839 000 000007a8: db4434b9 7cb58165 fe9e7259 ebb6f5a6 920fc3a1 f0c5f976 a6ec7cd2 f68da8f6 000 000007b0: 81d49885 fad850ed 1c3dbd5e 9e22c280 1374cf6b c001f6a1 a94dc92b a1cfab21 000 000007b8: 6bab6ec6 1a762e25 c881ea45 69fcc0a3 8cf8200a fb244a42 30ea2637 eed7d4ad 000 000007c0: fd102269 b6efe03c 018f78d9 8f2c102c 63c7ea8e 11978800 3c45aa66 1fbfbfa7 000 000007c8: c6cd431f fe1c98ac 098eceed 2c89ab82 3a94c92a fff2fa19 bff6a58e d461bc6e 000 000007d0: 020c33a3 40cf8c34 c6531d71 ade08e28 f916c2ec 800b4d1f 228aeafb 1847647a 000 000007d8: af1da9ec de7e27f9 ffab9826 a132aa0c 0d89fb54 e376470a 6ea41dab a26efeab 000 000007e0: 2b7fdea9 8a0712ee c95cba38 2bcfb408 8b73f30d 91a970f1 44b20ece aa038b66 000 000007e8: d3deb7a3 1aa7e5d8 778dc03c d5046e76 e79366e2 bfecf886 5cb60abd 1df0e837 000 000007f0: 0082bc48 e8caf8d1 b2404675 62a32ea8 9345025b fde3ced0 cc018eb5 c19851bb 000 000007f8: d4eeccbc a70b246b 29e6d13f b639d0da e20fd9a7 c75e0e82 c2897b5e 00001fc2
Test 3 will always succeed??Test 3 Random Addr Pattern Test 32 KB ---------------------------------------------------------------- cccccccccccccccccccccccccccccccc w r Test Complete!
CACHE TEST> t 4 Test 4 Pseudo-Random Pattern Test -1656445 KB ---------------------------------------------------------------- w r ERROR at $00000000 Expected $174b43e3 Received $cd32dcc6 Address $00000000 0K Page
There are many optimizations possible in your code. Let's get it working right first.
Other points:
- Looks like you have an aliasing problem with address bit A13. There may be an open connection from the 74161 to SRAM.
- The incremental test should have data always increasing from 0. Your data is swapped on even/odd addresses.
- The one test that is passing all the time does that because the test range is not big enough.
- Not sure what's happening with the last test. I've never seen a negative test range before with test_cache.spin.
Other notes:Well at least you verified that. So, for sure it's a driver problem.
The length division is necessary because you are writing/reading 2 bytes at a time.
Actually, it's very curious that the data looks like it's decrementing.
Need data. Do the following:
1. Fill the cache line with incremental pattern. CACHE TEST> i 2000 Incremental Pattern Test 8 KB ---------------------------------------------------------------- wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr Test Complete! ' check address 0 for 00000001 CACHE TEST> r 0 R 00000000 00000001 ' flush address 0 by reading 2000 CACHE TEST> r 0 ' check address 0 again - what value do you see? CACHE TEST> r 0
I have to run some errands. Be back in a while.
--Steve
I'm sorry, I meant
CACHE TEST> r 2000
then
CACHE TEST> r 0
Could you post your entire driver .spin file? It's kind of hard to see what's happening with the fragments embedded in your messages.
Thanks,
David
{ Skeleton JCACHE external RAM driver Copyright (c) 2011 by David Betz Based on code by Steve Denson (jazzed) Copyright (c) 2010 by John Steven Denson Inspired by VMCOG - virtual memory server for the Propeller Copyright (c) February 3, 2010 by William Henning For the EuroTouch 161 By James Moxham and Joe Heinz TERMS OF USE: MIT License Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. } CON ' default cache dimensions DEFAULT_INDEX_WIDTH = 6 DEFAULT_OFFSET_WIDTH = 4 ' cache line tag flags EMPTY_BIT = 30 DIRTY_BIT = 31 PUB image return @init_vm DAT org $0 ' initialization structure offsets ' $0: pointer to a two word mailbox ' $4: pointer to where to store the cache lines in hub ram ' $8: number of bits in the cache line index if non-zero (default is DEFAULT_INDEX_WIDTH) ' $a: number of bits in the cache line offset if non-zero (default is DEFAULT_OFFSET_WIDTH) ' note that $4 must be at least 2^(index_width+offset_width) bytes in size ' the cache line mask is returned in $0 init_vm mov t1, par ' get the address of the initialization structure rdlong pvmcmd, t1 ' pvmcmd is a pointer to the virtual address and read/write bit mov pvmaddr, pvmcmd ' pvmaddr is a pointer into the cache line on return add pvmaddr, #4 add t1, #4 rdlong cacheptr, t1 ' cacheptr is the base address in hub ram of the cache add t1, #4 rdlong t2, t1 wz if_nz mov index_width, t2 ' override the index_width default value add t1, #4 rdlong t2, t1 wz if_nz mov offset_width, t2 ' override the offset_width default value mov index_count, #1 shl index_count, index_width mov index_mask, index_count sub index_mask, #1 mov line_size, #1 shl line_size, offset_width mov t1, line_size sub t1, #1 wrlong t1, par ' put external memory initialization here jmp #vmflush fillme long 0[128-fillme] ' first 128 cog locations are used for a direct mapped cache table fit 128 ' initialize the cache lines vmflush movd :flush, #0 mov t1, index_count :flush mov 0-0, empty_mask add :flush, dstinc djnz t1, #:flush ' start the command loop waitcmd wrlong zero, pvmcmd :wait rdlong vmline, pvmcmd wz if_z jmp #:wait shr vmline, offset_width wc ' carry is now one for read and zero for write mov set_dirty_bit, #0 ' make mask to set dirty bit on writes muxnc set_dirty_bit, dirty_mask mov line, vmline ' get the cache line index and line, index_mask mov hubaddr, line shl hubaddr, offset_width add hubaddr, cacheptr ' get the address of the cache line wrlong hubaddr, pvmaddr ' return the address of the cache line movs :ld, line movd :st, line :ld mov vmcurrent, 0-0 ' get the cache line tag and vmcurrent, tag_mask cmp vmcurrent, vmline wz ' z set means there was a cache hit if_nz call #miss ' handle a cache miss :st or 0-0, set_dirty_bit ' set the dirty bit on writes jmp #waitcmd ' wait for a new command ' line is the cache line index ' vmcurrent is current cache line ' vmline is new cache line ' hubaddr is the address of the cache line miss movd :test, line movd :st, line :test test 0-0, dirty_mask wz if_z jmp #:rd ' current cache line is clean, just read new one mov vmaddr, vmcurrent shl vmaddr, offset_width call #wr_cache_line ' write current cache line :rd mov vmaddr, vmline shl vmaddr, offset_width call #rd_cache_line ' read new cache line :st mov 0-0, vmline miss_ret ret ' pointers to mailbox entries pvmcmd long 0 ' on call this is the virtual address and read/write bit pvmaddr long 0 ' on return this is the address of the cache line containing the virtual address cacheptr long 0 ' address in hub ram where cache lines are stored vmline long 0 ' cache line containing the virtual address vmcurrent long 0 ' current selected cache line (same as vmline on a cache hit) line long 0 ' current cache line index set_dirty_bit long 0 ' DIRTY_BIT set on writes, clear on reads zero long 0 ' zero constant dstinc long 1<<9 ' increment for the destination field of an instruction t1 long 0 ' temporary variable t2 long 0 ' temporary variable tag_mask long !(1<<DIRTY_BIT) ' includes EMPTY_BIT index_width long DEFAULT_INDEX_WIDTH index_mask long 0 index_count long 0 offset_width long DEFAULT_OFFSET_WIDTH line_size long 0 ' line size in bytes empty_mask long (1<<EMPTY_BIT) dirty_mask long (1<<DIRTY_BIT) ' input parameters to rd_cache_line and wr_cache_line vmaddr long 0 ' external address hubaddr long 0 ' hub memory address 'get_values rdlong hubaddr, hubptr ' get hub address ' rdlong ramaddr, ramptr ' get ram address ' rdlong len, lenptr ' get length ' mov err, #5 ' err=5 'get_values_ret ret 'init 'mov err, #0 ' reset err=false=good 'mov dira,zero ' tristate the pins with the cog dira ' and dira,maskP0P20P22 ' tristates all the common pins 'done 'wrlong err, errptr ' status =0=false=good, else error x 'wrlong zero, comptr ' command =0 (done) ' Pass pasm_n = 0- 7 come to this with P0-P20 and P22 tristated and returns them as this too set137 or dira,maskP22 ' pin 22 is an output andn outa,maskP22 ' set P22low so Y0-Y7 are all high or dira,maskP0P20 ' pins P0-P20 are outputs and outa,maskP0P2low ' set these 3 pins low or outa,pasm_n ' set the 137 pins or outa,maskP22 ' pin 22 high set137_ret ret ' return load161pasm ' uses vmaddr mov len, line_size ' make a copy of line_size AND. shr len, #1 ' devide lenght by two for word-byte or outa,maskP0P20 ' set P0-P20 high or dira,maskP0P20 ' output pins 0-20 mov pasm_n,#0 ' group 0 call #set137 ' set the 137 output and outa,maskP0P18low ' pins 0-18 set low or outa,vmaddr ' output addres to 161 chips 'or outa,maskP19 ' clock high 'or outa,maskP20 ' load high 'andn outa,maskP19 ' clock low 'andn outa,maskP20 ' load low 'or outa,maskP19 ' clock high 'or outa,maskP20 ' load high andn outa,maskP20 ' load low andn outa,maskP19 ' clock low or outa,maskP19 ' clock high or outa,maskP20 ' load high load161pasm_ret ret stop jmp #stop ' for debugging memorytransfer or dira,maskP16P20 ' so /wr and other pins definitely high or outa,maskP16P20 mov pasm_n,#1 ' back to group 1 for memory transfer call #set137 ' as next routine will always be group 1 or dira,maskP16P20 ' output pins 16-20 or outa,maskP16P20 ' set P16-P20 high (P0-P15 set as inputs or outputs in the calling routine) memorytransfer_ret ret busoutput or dira,maskP0P15 ' set prop pins 0-15 as outputs busoutput_ret ret businput and dira,maskP16P31 ' set P0-P15 as inputs businput_ret ret delaynop nop nop nop nop delaynop_ret ret '---------------------------------------------------------------------------------------------------- ' ' rd_cache_line - read a cache line from external memory ' ' vmaddr is the external memory address to read ' hubaddr is the hub memory address to write ' line_size is the number of bytes to read ' '---------------------------------------------------------------------------------------------------- rd_cache_line ' command T pasmramtohub call #load161pasm ' load the 161 counters with ramaddr call #memorytransfer ' set to group 1, enable P16-P20 as outputs and set P16-P20 high call #businput ' set prop pins P0-P15 as inputs andn outa,maskP16 ' memory /rd low ramtohub_loop mov data_16,ina ' get the data wrword data_16,hubaddr ' move data to hub andn outa,maskP19 ' clock 161 low or outa,maskP19 ' clock 161 high add hubaddr,#2 ' increment the hub address djnz len,#ramtohub_loop or outa,maskP16 ' memory /rd high or dira,maskP0P15 ' %00000000_00000000_11111111_11111111 restore P0-P15as outputs and dira,maskP0P20P22 ' tristates all the common pins rd_cache_line_ret ret '---------------------------------------------------------------------------------------------------- ' ' wr_cache_line - write a cache line to external memory ' ' vmaddr is the external memory address to write ' hubaddr is the hub memory address to read ' line_size is the number of bytes to write ' '---------------------------------------------------------------------------------------------------- wr_cache_line ' command S pasmhubtoram call #load161pasm ' load the 161 counters with ramaddr call #memorytransfer ' set to group 1, enable P16-P20 as outputs and set P16-P20 high call #busoutput ' set prop pins P0-P15 as outputs hubtoram_loop and outa,maskP16P31 '%11111111_11111111_00000000_00000000 ' clear for output rdword data_16,hubaddr ' get the word from hub and data_16,maskP0P15 ' mask to a word only or outa,data_16 ' send out the byte to P0-P15 andn outa,maskP17 ' set mem write low add hubaddr,#2 ' increment by 2 bytes = 1 word. Put this here for small delay while writes or outa,maskP17 ' mem write high andn outa,maskP19 ' clock 161 low or outa,maskP19 ' clock 161 high djnz len,#hubtoram_loop ' loop this many times and dira,maskP0P20P22 ' tristates all the common pins wr_cache_line_ret ret pasm_n long 0 ' general purpose value data_16 long 0 ' general purpose value len long 0 ' copy line size and devide by two for byte-word offset maskP0P2low long %11111111_11111111_11111111_11111000 ' P0-P2 low maskP0P20 long %00000000_00011111_11111111_11111111 ' P0-P18 enabled for output plus P19,P20 maskP0P18low long %11111111_11111000_00000000_00000000 ' P0-P18 low maskP16 long %00000000_00000001_00000000_00000000 ' pin 16 maskP17 long %00000000_00000010_00000000_00000000 ' pin 17 maskP18 long %00000000_00000100_00000000_00000000 ' pin 18 maskP19 long %00000000_00001000_00000000_00000000 ' pin 19 maskP20 long %00000000_00010000_00000000_00000000 ' pin 20 maskP22 long %00000000_01000000_00000000_00000000 ' pin 22 maskP16P31 long %11111111_11111111_00000000_00000000 ' pin 16 to pin 31 maskP0P15 long %00000000_00000000_11111111_11111111 ' for masking words maskP16P20 long %00000000_00011111_00000000_00000000 maskP0P20P22 long %11111111_10100000_00000000_00000000 ' for returning all group pins HiZ fit 496
I just sent a test board to Steve, it should be there on Sunday. The notes on the board for Steve's reference are as follows :
# 1. Does not match *optimized clock logic* : Wired for a 74hc00 instead of a 74hc08. I can walk Steve through the changes if necessary but the logic DOES WORK.
*edit* drawn wrong, correct now
# 2. Prop Plug pin1 is Pin14 of max chip *4 pin header installed.
# 3. IC8 *just under LEDs* is the 74HC00, sorry it's not loaded.
# 4. The 4 Pin header, bottom left is +5, +3.3 and GND.
# 5.I think I forgot to load an eeprom in the socket before shipping, sorry.
That should be it. If you have any questions please let me know.
Thanks again for all your time and help guys!
Joe, Is P19 connected directly to the counter clock inputs?
Thanks,
--Steve
P20 is the load, or-d with Group 0.
*edit*
I will work up a description for you. Schematic is posted on 109 but I will edit this post to contain text description.
P0-15 ----> Data bus
P0-18 ----> Address bus to 161s
P 0-2 ----> 137 Address
P 22 ----> 137 Latch/Enable
P16 ----> SRAM RD
P17 ----> SRAM WR
Group1 ----> SRAM CS
P20 ORd Group0 ----> Load 161s
Group 0 AND Group 1 ---> ORd Pin 19 ----> Clock 161
That should cover the basics.
Thanks a million guys!