It's not for me to worry about a hijack of Cluso's thread[noparse]:)[/noparse]
I just thought that the combination of Z80 and Prop might like to have it's own home. Purely selfish so that its easier for me to find in the future[noparse]:)[/noparse]
You see a project with that combination is what I was about to embark on before getting derailed by the emulation idea.
Also you may want to share some effort/ideas with Yoda who is working on a a similar setup.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
For me, the past is not over yet.
Ok, I'll bring it back on track with a specific question for Cluso:
I'm trying to trace through the program execution where it sends a byte to the ram chip. I found some commented out code in the LoadSRAM section that printed out the values in the buffer array. But this is data that has been read from the SD card, not from the ram chip. So I was pondering a tiny bit of code that would test the ram chip by picking one location, writing a byte and reading it back. I put in this little bit of code just under the LoadSRAM
uart.str(string("Test write and read a byte from ram"))
crlf
buff :=88
tbp2.DoCmd("W",@buff,3,1) ' write 1 byte to ram
uart.dec(buff)
crlf
I tried tracing through with some jumps to an endless loop but I can't quite see how the data gets through. So to simplify things, inside the wrloop code I tried adding a couple of lines that I think should increment the value in the hub buffer (and which should not affect the writing to ram as this is a write, not a read)
wrloop rdbyte outx, hubaddr ' copy byte from hub
add outx,#1 ' test adding 1 and sending it back
wrbyte outx,hubaddr ' send it back for debugging
What I was expecting to happen is that this would take the value of 88 stored in
buff
, add 1 and put it back in the correct hub address. However, it prints out the value in
buff
unchanged.
I must be missing something obvious here. Help would be most appreciated!
Addit: problems with the forum putting in square braces, even inside the code statement. So for the word 'buff' above, substitute buff, left square brace,3,right square brace
Been coding all day. I probably don't need the answer to that question anymore. Going back to a previous question, I never worked out the equivalent of "PRINT" in spin (or Debug in Picaxe), ie a single line test statement that you can drop in anywhere in the code. Specifically, in a seperate spin program like the Blade2 driver. Debugging was becoming impossible, so I first started off with a brand new program and did lots of F10s (one very nice feature of the Prop) to quickly build up a new driver in Spin. Ok, it is slower but with the new setup, all it really has to do is put 3 bytes at the bottom of ram, and 256 bytes at the top, and then jump into the zicog. As it was taking 20 secs to boot, I commented out the code that filled the 64k with zero, as this isn't needed either. Now it gets to the zicog stage the same speed as the triblade.
Then I dropped the working code in at the bottom of the zicog_cpm program. This way, it is possible to debug with the UART.hex and UART.str objects. Much faster than trying to debug with a led that lights.
I also added a little code that reads back the first 3 bytes from ram to give some indication the ram is working correctly.
Next step, translating the working spin driver code into something that fits inside the zicog. I hope it fits!!
ZiCog 1.0_rc_5.5b on the TriBladeProp v0.125
SD started
SD mounted
A:ZIPM2_6b.DSK 852817 748644720
B:ZICOG_A2.DSK 639825 748644720
C:DRAC2_64.DSK 279185 748644720
D:ZICOG_SC.DSK 803665 748644720
E:ZICOG_E2.DSK 721745 748644720
F:ZICOG_F0.DSK 738129 748644720
G:ZICOG_G0.DSK 770897 748644720
H:ZICOG_H0.DSK 787281 748644720
R:BOOTHDSK.32M <-bootcode 115281 748644720
Loading SRAM...
Skip filling memory with zero
Ram test, should print out C3 00 FF = first 3 ram bytes: C3,00,FF,
Read boot code from SD card and store at $FF00:
Boot code loaded
Starting Z80 emulation...
Passed, please wait...
But I do have another technical question for Cluso, if I may. All through the zicog code (with I/O commands) is this statement:
#ifdef TriBladeProp
mov dira, ram_dir_read 'RR20090321 (take I/O from another cog)
#endif
Some are ram_dir_input. What is this code doing, and why is it needed in the zicog? (I was thinking that all I/O was serviced in spin in the main program)
eg for the Z80 OUT instruction there is this:
wrbyte data_8, io_port
rdbyte data_8, a_reg 'Get the output data from A reg
wrbyte data_8, io_data 'Set the output data
mov data_8, #io_cmd_out 'Set I/O command to OUT
#ifdef TriBladeProp
mov dira, ram_dir_input 'RR20090321 (pass I/O to another cog)
#endif
wrbyte data_8, io_command
:wait rdbyte data_8, io_command wz 'Wait for the output done
if_nz jmp #:wait
#ifdef TriBladeProp
mov dira, ram_dir_read 'RR20090321 (take I/O from another cog)
#endif
ram_dir_read long %00110_11111111111_11111111_00000000 ' outputs WE, OE, A0-18, inputs D0-7
ram_dir_input long %00000_00000000000_00000000_00000000 ' all inputs (for Ram Disk access)
Which appears to put all the pins to a tristate state while waiting for the io_command to complete in spin. Is this in case the io_command happened to want to access the sd card and then zicog couldn't work out what to put the pins back to?
The Z80 emulation PASM code ZiCog.spin has to be able to read and write from Z80's RAM space in the external RAM.
It does this directly. That is it waggles all the pins connected to the RAM itself rather than relying on some external module/driver. This is so that it works at a reasonable speed. Look for PASM routines read_memory_byte and write_memory_byte.
BUT of course those RAM access pins are shared with the SD card driver and any other user of the RAM. So we have the complicated situation of two different pieces of code wanting to use the same pins. This is normally a no-no but in ZiCog CP/M we are OK because only one of those pieces of code needs to be running at any given time. So either ZiCog is emulating at full speed and "owns" the I/O pins or it hangs in a loop during an I/O operation during which time the I/O emulation Spin code can "own" the pins.
So as you see each side has to release control of the pins when it does not need them and you have seen ZiCog.spin does this by the "mov dira, ram_dir_read" which insures they not driven when ZiCog hangs waiting on the I/O driver code. This has to be done at every place ZiCog hangs waiting for an I/O to complete as it does not know what pins any I/O driver may use.
There is no issue of zicog not knowing what to "put the pins back to". More simply it's just that we can't allow two COGs to drive outputs simultaneously.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
For me, the past is not over yet.
I've just completed rewriting the read_memory_byte and write_memory_byte subroutines. Translated them from spin.
Nooo - 11 longs too many!!
As I've not got any conflicts with sd card pins I went and commented out all those #ifdefs in the zicog that were related to the triblade. There were more than 11, so theoretically I should have saved those 11 longs.
Now I'm getting a slightly different error - still 11 longs but at a different place.
C:\Propeller\zicog92\Drac 25 10 09>bstc -p2 -d COM1 -e -Ox zicog_cpm_rc5.5b_rr12
7.spin
Brads Spin Tool Compiler v0.15.3 - Copyright 2008,2009 All rights reserved
Compiled for i386 Win32 at 08:17:48 on 2009/07/20
Loading Object zicog_cpm_rc5.5b_rr127
Loading Object zicog
zicog - Error at (1298,36) PC exceeds cog memory by 11 longs
fit $1F0
___________________________________^
zicog - Error at (1318,35) Expected Spin Method, Unique Name, Assembly Condition
al, BYTE, WORD, LONG or Assembly Instruction
long $0[noparse][[/noparse]($ - OVERLAY_START) // 2] 'fill to even nu
mber of longs (REQUIRED)
__________________________________^
Compiled 2710 Lines of Code in 0.219 Seconds
C:\Propeller\zicog92\Drac 25 10 09>TERATERM.EXE
C:\Propeller\zicog92\Drac 25 10 09>pause
Press any key to continue . . .
Line 1298 is the fit $1F at the end of the DAA. @heater I think there might be some tweaking to do with the way you squeezed everything in with overlays. Could you explain these a bit more? Why do they all start at Overlay_start? Where does the code come from and how does it save memory?
I'm happy to lose one or two instructions eg some of the block 'out' instructions if it will save space, but first, why did it not create any new space when I deleted all those triblade #ifdefs in the zicog?
James: You cannot necessarily delete the #ifdef TriBlade because any hardware will require code here, so you are not saving any pasm instructions because you DO HAVE other cogs requiring access to these pins. The RAM is shared by ZiCog and the driver, which includes the spin I/O driver and the TriBlade driver (or equivalent) because it will be required to copy the SD block of data read to the RAM.
So, because your RAM access is much more complicated than mine, you use more cog instructions in the ZiCog pasm code, and as a consequence you have run out of space. I am not sure how you are going to overcome this.
As for the overlay routines, I suggest you look at my original overlay loader (you can find the thread under my tools link below). Basically, it loads a pasm routine into the cog at overlay_start and executes it, either by a jmp or call.
The FIT $1F0 is to ensure all cog code fits into the cog.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ Links to other interesting threads:
Last time I checked I think we were down to 6 LONGs free in ZiCog, perhaps even less. So I guess things are going to be tight.
Not sure why you are deleting the #ifdefs why not just not define triblade prop? But as Cluso says most of those instructions to tristate the pins will be needed as you are accessing RAM from outside ZiCog, in the driver codes.
Re: overlays. There is a non-obvious thing going on here - that when you remove LONGS from overlays it appears not to save any space or the FIT "exceeds cog memory" error moves around from one overlay to another.
So consider this:
1) There is the bulk of zicog PASM that is always in the COG. That is everything up to OVERLAY_START. This is normally referred to as "resident" code. Same as in CP/M with bank switched memory or other such systems.
2) There is a bunch of small bits of PASM (overlays) that are sitting in HUB. Each of these small bits of code can be read into COG by the overlay loader when it is required to run them.
3) There is necessarily a free space in the COG that these overlays are read into in order to execute them. Rather like the Transient Program Area (TPA) in CP/M. This is at address OVERLAY_START and is at the end of the "resident" area in the COG.
So how much COG space is used? Well it's the size of the "resident" PASM code plus the size of the area reserved for overlay loading. The overlay area must be the size of the largest existing overlay.
So COG space used = "size of resident code + size of largest overlay"
What does this mean? Well what I found myself doing is shaving LONGS of of overlays and finding it did not save space. Crazy. But now we see that unless you are shaving the biggest overlay, and hence the required overlay area size, the change does not make any difference.
So in fact you could delete most of the overlays, which is what happens when CPU_8080 is defined instead of CPU_Z80, and find that no change in the size of code, still only 6 free LONGS. This is because the biggest overlay is DAA which is used by 8080. There has to be space for that in the "non resident" area.
(Thinks..If I remember correctly DAA is still the biggest overlay).
To your questions:
"Why do they all start at Overlay_start?" - The expression "$ - OVERLAY_START" is giving the length of the overlay.
OVERLAY_START is a fixed address in COG where the overlay will be loaded. "$" is the current address where PASM is assembling code (which may not still be within the COG). BUT because the address used by PASM is reset at the beginning of each overlay with " org OVERLAY_START" the "$" ends up giving us the address where the end of the overlay will be when it is loaded into the COG. Devious ha?
"Where does the code come from and how does it save memory" - Not sure I understand the question. The code comes form the fact that it is just sitting there at the end of the PASM in HUB memory. When the COG is run the first 496 LONGS are loaded into COG and run. The rest of it, the overlays, are just sitting there in HUB memory. When an overlay is to be run the overlay loader reads it from HUB and writes it to OVERLAY_START and runs it. So that how it saves memory, not all routines are in COG at the same time.
Note. The is no "free space" explicitly defined in COG for overlays to be read into. Rather the first overlay, DAA in our case is actually the overlay loader space. It is loaded anyway when the COG is first started for free.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
For me, the past is not over yet.
For experimental purposes you could comment out the DAA code. Apart from SURVEY I have not found any other CP/M program that uses it. It is big and will save you LONGS for the RAM access code.
Do use CPU_8080 instead of CPU_Z80. That gets rid of most overlays.
How we get this space in the long term I'm not sure yet. It will be tricky.
Looks like you second compile error is because OVERLAY_START has been commented out or has been lost behind ifdefs.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
For me, the past is not over yet.
Thanks heaps for the explanation. Now it makes a lot more sense. More and more I can say that this is a superb piece of work by heater and cluso.
Ok, short answer is that I changed to 8080 code for the moment and now there is enough room and it compiles and runs.
I'm working with one sd card at the moment and it is a card that won't boot on the triblade any more (lots of reboots in the middle of reads = ? corrupted files). But it takes about 2 hours to copy the files over to the sd card so I don't want to do a reformat right now. Awaiting some new cards.
I put back in the ifdefs for the triblade in the zicog - not saving anything as you say. But possibly part of the problem too, especially the OUT command.
So - I have a board working to the point it hands over to the zicog routine. This is now getting into familiar territory for me as I can recognise certain Z80 instructions by their hex opcodes (very sad I know). This ought to be easier than programming eproms one instruction at a time! So - given there is no A>, and given there might possibly be corrupted boot files on the sd card, I'd first like to start with some very simple programs. Eg an OUT and see if iocommand can trap it. So, I could write a little program on the N8VEM, compile it, put the binary on the sd card , rename the boot program to this new program, and it should run.
How would I go about putting the single step back in so I can trace program execution?
Don't forget if you assemble a test program to put in place of ziboot.com you will need to have it orged to FF00 instead of the normal 0100 of CP/M programs. Perhaps start with the ziboot.mac as an example.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
For me, the past is not over yet.
Does the zicog start at FF00 or at 0000? There is a JMP FF00 at 0000 so I'm wondering if that is where it starts. If so, it ought to be easy to poke a few bytes into 0000 and up using spin and then run them. Eg LD A,5 then LD (nnnn),A and then a halt (is halt implemented?) and then see if the number is at nnnn in the memory. Basic stuff I know, but it is the simplest way I can think of to test the PASM code that does ram read and write.
zicog, like a real Z80, starts at 0000. However if you wanted to experiment you could set the initial value of the PC in zicog_cpm to something else before starting emulation. Not really recommended.
Poking a few bytes into 0000 is how I originally tested zicog op code handling.
HALT is implemented, should cause a break and dumpt the regs like a single step. But you may as well be single stepping anyway when testing some initial op codes at 0000.
What you are suggesting to do is about the best way to proceed during these initial stages of getting the emulator running. Much like bringing up a real Z80 on new hardware and following it along with a logic analyser on the busses.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
For me, the past is not over yet.
Drac: I placed a jmp $FF00 and load $FF00 with the boot code.
I think you best buy an USB SD card reader/writer from Officeworks. It will save you hours for reformatting and copying new files to your SD card. Did you take a copy of the files we loaded onto your card??
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ Links to other interesting threads:
I've spent some time inside the code. Boy is it clever. Great fun working through step by step. I've come up against a small snag and the answer is eluding me. I just can't seem to make a couple of pins go low within PASM
I've narrowed it down to a very small bit of code.
Ok, in the main zicog program, right near the end of the PUB start there is this bit of code:
James: The way the prop works is that all cog output pins are OR'd together, so if another cog is driving those pins high they will be high.
So I presume cpu.start or service_IO is driving the lines at some point in time causing your problem.
BTW I presume that the DAT normally follows and you are starting it correctly. i.e. You understand how cogs and pasm work.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ Links to other interesting threads:
Thanks cluso. I bypassed the sd routines and that fixes the problem. Need to narrow it down further, as I thought that if the sd routines only used 4 pins then only those 4 would be set. Am back in the original fsrw_femto but I see your version had some tristating going on. I'll narrow it down...
I think you have to use my version of the SD driver because the standard version requires the SD pins to be successive 4 pins and IIRC you do not use contiguous pins
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ Links to other interesting threads:
I think that is the issue right there. The standard fsrw needs contiguous pins. Your "i" command tristated all 32 pins, and when I removed that I assumed that fsrw would only ever use 4 pins. I put back the "i" command all through the code and now I have control of the pins again. I think this also goes back to an earlier discussion where I could not work out why you would ever need pullups on SD pins if those pins were never used for anything else and the cog kept running. Dare I say it, but I think the brute force tristate to all pins may be masking specific pins in the sd driver code not doing exactly what is expected. So - simple solution that 'works' is to put in pullups and to tristate all 32 pins to be sure.
In revision 2 of the board design I changed the pinouts so the SD pins are contiguous. I also dropped in a 9 resistor 10k SIL for pullups on everything that is needed if any/all prop pins are tristated. In particular, the SD pins and also the gate going into the 138, so that even if the 3 inputs to the 138 are floating, the outputs will all be high because the gate is pulled high.
Getting close to testing efficiency. And this is where a real Z80 board is very handy for doing some test code and assembling it and getting the hex values:
' poke a tiny test program into ram
buff[noparse][[/noparse]0] := $3E ' ld a,6
buff := $06
buff := $32 ' ld (500),a save to a random memory location
buff := $01
buff := $F4
buff := $3E ' ld a,0 clear a
buff[noparse][[/noparse]6] := $00
buff[noparse][[/noparse]7] := $3A ' ld a,(500)
buff[noparse][[/noparse]8] := $01
buff[noparse][[/noparse]9] := $F4
buff[noparse][[/noparse]10]:= $3C ' inc a
buff[noparse][[/noparse]11]:= $3C ' inc a
buff[noparse][[/noparse]12]:= $3C ' inc a
(allowing for the forum not quite reproducing all the buff arrays which are contiguous)
and watch register A as this is single stepped:
Starting 8080 emulation...
Passed, please wait...
PC=0000 AF=0000 BC=0000 DE=0000 HL=0000 IX=0000 IY=0000 SP=0000
Spacebar for next instruction
PC=0002 AF=0600 BC=0000 DE=0000 HL=0000 IX=0000 IY=0000 SP=0000
Spacebar for next instruction
PC=0005 AF=0600 BC=0000 DE=0000 HL=0000 IX=0000 IY=0000 SP=0000
Spacebar for next instruction
PC=0007 AF=0000 BC=0000 DE=0000 HL=0000 IX=0000 IY=0000 SP=0000
Spacebar for next instruction
PC=000A AF=0600 BC=0000 DE=0000 HL=0000 IX=0000 IY=0000 SP=0000
Spacebar for next instruction
PC=000B AF=0700 BC=0000 DE=0000 HL=0000 IX=0000 IY=0000 SP=0000
Spacebar for next instruction
PC=000C AF=0800 BC=0000 DE=0000 HL=0000 IX=0000 IY=0000 SP=0000
Spacebar for next instruction
Thanks ++ for that clue re non contiguous pins. That has really got things moving along quickly now.
Just a quick addition to your code in the single step could be the spacebar instruction
PRI on_break
'Handle CPU break condition
'No, this never existed in an Altair (or SIMH simulator)
print_regs
'waitcnt (cnt + 80_000)
UART.str(string("Spacebar for next instruction"))
crlf
as it took me a little while to work out what to do to single step.
Ok, next step is to single step through the boot code. This is about 100 bytes of hex code. Not that reverse compiling isn't fun, but is there the source code for this tiny program somewhere?
Thanks heater. Ziboot.mac sounds familiar. Though I had a quick scan back through to early October and can't see it anywhere on the forum. Maybe it was one of the files Cluso gave me at the Great Southern Hemisphere Prop Conference. I'm at work now so can't check the sd card. Possibly it needs to be on this forum. But it would naturally go with a package of disk images that are all 8mb and even when compressed they come to quite a large zip. I'm not sure of the solution to that - ?? a link to a website.
I must say it is a great way to learn about the zicog by building it up one step at a time.
Thanks heater. (I'm still at work. Another 16 hour workday. Will get a chance to do to prop stuff in about 5 hours - Yay!)
I'll be single stepping this, but just a quick note - it has a .org of 100H, but the zicog puts this code at $FF00. Anyway, it should be possible to trace as it sends back lots of messages to the spin code.
Not quite. There is an "org 100h" but the code immediately following that is not actually assembled as it is preceded by "if includeTestCode" which is a conditional assembly directive. As "includeTestCode" is not defined the actual code assembled starts after the line ".phase bootstart". This causes the code to be assembled as if it were sitting at FF00.
If you look in ZIBOOT.PRN you can see the actual assembled opcodes. Notice all the jumps have the correct destination addresses for when running at FF00.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
For me, the past is not over yet.
Ok, working through the code. I did need the source ziboot files after all - so thanks ++ for this. Putting back lots of commented out test lines in the spin code at the moment and tracing through the simh io port calls. All good fun!
Comments
I just thought that the combination of Z80 and Prop might like to have it's own home. Purely selfish so that its easier for me to find in the future[noparse]:)[/noparse]
You see a project with that combination is what I was about to embark on before getting derailed by the emulation idea.
Also you may want to share some effort/ideas with Yoda who is working on a a similar setup.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
For me, the past is not over yet.
I'm trying to trace through the program execution where it sends a byte to the ram chip. I found some commented out code in the LoadSRAM section that printed out the values in the buffer array. But this is data that has been read from the SD card, not from the ram chip. So I was pondering a tiny bit of code that would test the ram chip by picking one location, writing a byte and reading it back. I put in this little bit of code just under the LoadSRAM
I tried tracing through with some jumps to an endless loop but I can't quite see how the data gets through. So to simplify things, inside the wrloop code I tried adding a couple of lines that I think should increment the value in the hub buffer (and which should not affect the writing to ram as this is a write, not a read)
What I was expecting to happen is that this would take the value of 88 stored in
, add 1 and put it back in the correct hub address. However, it prints out the value in
unchanged.
I must be missing something obvious here. Help would be most appreciated!
Addit: problems with the forum putting in square braces, even inside the code statement. So for the word 'buff' above, substitute buff, left square brace,3,right square brace
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
www.smarthome.viviti.com/build
Post Edited (Dr_Acula) : 11/9/2009 12:40:13 PM GMT
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Links to other interesting threads:
· Home of the MultiBladeProps: TriBlade,·RamBlade,·SixBlade, website
· Single Board Computer:·3 Propeller ICs·and a·TriBladeProp board (ZiCog Z80 Emulator)
· Prop Tools under Development or Completed (Index)
· Emulators: CPUs Z80 etc; Micros Altair etc;· Terminals·VT100 etc; (Index) ZiCog (Z80) , MoCog (6809)
· Search the Propeller forums·(uses advanced Google search)
My cruising website is: ·www.bluemagic.biz·· MultiBladeProp is: www.bluemagic.biz/cluso.htm
Then I dropped the working code in at the bottom of the zicog_cpm program. This way, it is possible to debug with the UART.hex and UART.str objects. Much faster than trying to debug with a led that lights.
I also added a little code that reads back the first 3 bytes from ram to give some indication the ram is working correctly.
Next step, translating the working spin driver code into something that fits inside the zicog. I hope it fits!!
But I do have another technical question for Cluso, if I may. All through the zicog code (with I/O commands) is this statement:
Some are ram_dir_input. What is this code doing, and why is it needed in the zicog? (I was thinking that all I/O was serviced in spin in the main program)
eg for the Z80 OUT instruction there is this:
Which appears to put all the pins to a tristate state while waiting for the io_command to complete in spin. Is this in case the io_command happened to want to access the sd card and then zicog couldn't work out what to put the pins back to?
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
www.smarthome.viviti.com/build
Post Edited (Dr_Acula) : 11/10/2009 4:22:52 AM GMT
The Z80 emulation PASM code ZiCog.spin has to be able to read and write from Z80's RAM space in the external RAM.
It does this directly. That is it waggles all the pins connected to the RAM itself rather than relying on some external module/driver. This is so that it works at a reasonable speed. Look for PASM routines read_memory_byte and write_memory_byte.
BUT of course those RAM access pins are shared with the SD card driver and any other user of the RAM. So we have the complicated situation of two different pieces of code wanting to use the same pins. This is normally a no-no but in ZiCog CP/M we are OK because only one of those pieces of code needs to be running at any given time. So either ZiCog is emulating at full speed and "owns" the I/O pins or it hangs in a loop during an I/O operation during which time the I/O emulation Spin code can "own" the pins.
So as you see each side has to release control of the pins when it does not need them and you have seen ZiCog.spin does this by the "mov dira, ram_dir_read" which insures they not driven when ZiCog hangs waiting on the I/O driver code. This has to be done at every place ZiCog hangs waiting for an I/O to complete as it does not know what pins any I/O driver may use.
There is no issue of zicog not knowing what to "put the pins back to". More simply it's just that we can't allow two COGs to drive outputs simultaneously.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
For me, the past is not over yet.
Post Edited (heater) : 11/10/2009 5:01:57 AM GMT
I've just completed rewriting the read_memory_byte and write_memory_byte subroutines. Translated them from spin.
Nooo - 11 longs too many!!
As I've not got any conflicts with sd card pins I went and commented out all those #ifdefs in the zicog that were related to the triblade. There were more than 11, so theoretically I should have saved those 11 longs.
Now I'm getting a slightly different error - still 11 longs but at a different place.
Line 1298 is the fit $1F at the end of the DAA. @heater I think there might be some tweaking to do with the way you squeezed everything in with overlays. Could you explain these a bit more? Why do they all start at Overlay_start? Where does the code come from and how does it save memory?
I'm happy to lose one or two instructions eg some of the block 'out' instructions if it will save space, but first, why did it not create any new space when I deleted all those triblade #ifdefs in the zicog?
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
www.smarthome.viviti.com/build
So, because your RAM access is much more complicated than mine, you use more cog instructions in the ZiCog pasm code, and as a consequence you have run out of space. I am not sure how you are going to overcome this.
As for the overlay routines, I suggest you look at my original overlay loader (you can find the thread under my tools link below). Basically, it loads a pasm routine into the cog at overlay_start and executes it, either by a jmp or call.
The FIT $1F0 is to ensure all cog code fits into the cog.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Links to other interesting threads:
· Home of the MultiBladeProps: TriBlade,·RamBlade,·SixBlade, website
· Single Board Computer:·3 Propeller ICs·and a·TriBladeProp board (ZiCog Z80 Emulator)
· Prop Tools under Development or Completed (Index)
· Emulators: CPUs Z80 etc; Micros Altair etc;· Terminals·VT100 etc; (Index) ZiCog (Z80) , MoCog (6809)
· Search the Propeller forums·(uses advanced Google search)
My cruising website is: ·www.bluemagic.biz·· MultiBladeProp is: www.bluemagic.biz/cluso.htm
Last time I checked I think we were down to 6 LONGs free in ZiCog, perhaps even less. So I guess things are going to be tight.
Not sure why you are deleting the #ifdefs why not just not define triblade prop? But as Cluso says most of those instructions to tristate the pins will be needed as you are accessing RAM from outside ZiCog, in the driver codes.
Re: overlays. There is a non-obvious thing going on here - that when you remove LONGS from overlays it appears not to save any space or the FIT "exceeds cog memory" error moves around from one overlay to another.
So consider this:
1) There is the bulk of zicog PASM that is always in the COG. That is everything up to OVERLAY_START. This is normally referred to as "resident" code. Same as in CP/M with bank switched memory or other such systems.
2) There is a bunch of small bits of PASM (overlays) that are sitting in HUB. Each of these small bits of code can be read into COG by the overlay loader when it is required to run them.
3) There is necessarily a free space in the COG that these overlays are read into in order to execute them. Rather like the Transient Program Area (TPA) in CP/M. This is at address OVERLAY_START and is at the end of the "resident" area in the COG.
So how much COG space is used? Well it's the size of the "resident" PASM code plus the size of the area reserved for overlay loading. The overlay area must be the size of the largest existing overlay.
So COG space used = "size of resident code + size of largest overlay"
What does this mean? Well what I found myself doing is shaving LONGS of of overlays and finding it did not save space. Crazy. But now we see that unless you are shaving the biggest overlay, and hence the required overlay area size, the change does not make any difference.
So in fact you could delete most of the overlays, which is what happens when CPU_8080 is defined instead of CPU_Z80, and find that no change in the size of code, still only 6 free LONGS. This is because the biggest overlay is DAA which is used by 8080. There has to be space for that in the "non resident" area.
(Thinks..If I remember correctly DAA is still the biggest overlay).
To your questions:
"Why do they all start at Overlay_start?" - The expression "$ - OVERLAY_START" is giving the length of the overlay.
OVERLAY_START is a fixed address in COG where the overlay will be loaded. "$" is the current address where PASM is assembling code (which may not still be within the COG). BUT because the address used by PASM is reset at the beginning of each overlay with " org OVERLAY_START" the "$" ends up giving us the address where the end of the overlay will be when it is loaded into the COG. Devious ha?
"Where does the code come from and how does it save memory" - Not sure I understand the question. The code comes form the fact that it is just sitting there at the end of the PASM in HUB memory. When the COG is run the first 496 LONGS are loaded into COG and run. The rest of it, the overlays, are just sitting there in HUB memory. When an overlay is to be run the overlay loader reads it from HUB and writes it to OVERLAY_START and runs it. So that how it saves memory, not all routines are in COG at the same time.
Note. The is no "free space" explicitly defined in COG for overlays to be read into. Rather the first overlay, DAA in our case is actually the overlay loader space. It is loaded anyway when the COG is first started for free.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
For me, the past is not over yet.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Links to other interesting threads:
· Home of the MultiBladeProps: TriBlade,·RamBlade,·SixBlade, website
· Single Board Computer:·3 Propeller ICs·and a·TriBladeProp board (ZiCog Z80 Emulator)
· Prop Tools under Development or Completed (Index)
· Emulators: CPUs Z80 etc; Micros Altair etc;· Terminals·VT100 etc; (Index) ZiCog (Z80) , MoCog (6809)
· Search the Propeller forums·(uses advanced Google search)
My cruising website is: ·www.bluemagic.biz·· MultiBladeProp is: www.bluemagic.biz/cluso.htm
Do use CPU_8080 instead of CPU_Z80. That gets rid of most overlays.
How we get this space in the long term I'm not sure yet. It will be tricky.
Looks like you second compile error is because OVERLAY_START has been commented out or has been lost behind ifdefs.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
For me, the past is not over yet.
Ok, short answer is that I changed to 8080 code for the moment and now there is enough room and it compiles and runs.
I'm working with one sd card at the moment and it is a card that won't boot on the triblade any more (lots of reboots in the middle of reads = ? corrupted files). But it takes about 2 hours to copy the files over to the sd card so I don't want to do a reformat right now. Awaiting some new cards.
I put back in the ifdefs for the triblade in the zicog - not saving anything as you say. But possibly part of the problem too, especially the OUT command.
So - I have a board working to the point it hands over to the zicog routine. This is now getting into familiar territory for me as I can recognise certain Z80 instructions by their hex opcodes (very sad I know). This ought to be easier than programming eproms one instruction at a time! So - given there is no A>, and given there might possibly be corrupted boot files on the sd card, I'd first like to start with some very simple programs. Eg an OUT and see if iocommand can trap it. So, I could write a little program on the N8VEM, compile it, put the binary on the sd card , rename the boot program to this new program, and it should run.
How would I go about putting the single step back in so I can trace program execution?
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
www.smarthome.viviti.com/build
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
For me, the past is not over yet.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
For me, the past is not over yet.
Does the zicog start at FF00 or at 0000? There is a JMP FF00 at 0000 so I'm wondering if that is where it starts. If so, it ought to be easy to poke a few bytes into 0000 and up using spin and then run them. Eg LD A,5 then LD (nnnn),A and then a halt (is halt implemented?) and then see if the number is at nnnn in the memory. Basic stuff I know, but it is the simplest way I can think of to test the PASM code that does ram read and write.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
www.smarthome.viviti.com/build
Poking a few bytes into 0000 is how I originally tested zicog op code handling.
HALT is implemented, should cause a break and dumpt the regs like a single step. But you may as well be single stepping anyway when testing some initial op codes at 0000.
What you are suggesting to do is about the best way to proceed during these initial stages of getting the emulator running. Much like bringing up a real Z80 on new hardware and following it along with a logic analyser on the busses.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
For me, the past is not over yet.
I think you best buy an USB SD card reader/writer from Officeworks. It will save you hours for reformatting and copying new files to your SD card. Did you take a copy of the files we loaded onto your card??
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Links to other interesting threads:
· Home of the MultiBladeProps: TriBlade,·RamBlade,·SixBlade, website
· Single Board Computer:·3 Propeller ICs·and a·TriBladeProp board (ZiCog Z80 Emulator)
· Prop Tools under Development or Completed (Index)
· Emulators: CPUs Z80 etc; Micros Altair etc;· Terminals·VT100 etc; (Index) ZiCog (Z80) , MoCog (6809)
· Search the Propeller forums·(uses advanced Google search)
My cruising website is: ·www.bluemagic.biz·· MultiBladeProp is: www.bluemagic.biz/cluso.htm
I've spent some time inside the code. Boy is it clever. Great fun working through step by step. I've come up against a small snag and the answer is eluding me. I just can't seem to make a couple of pins go low within PASM
I've narrowed it down to a very small bit of code.
Ok, in the main zicog program, right near the end of the PUB start there is this bit of code:
If I add before the cpu.start the following then I can make pins 0-7, 8,10,11,12 go low:
But if I remove that little bit of code and let it run the zicog and add some code right after
to go to
and then in pinslow
I can make most of the dira pins go low (pins 0-7 10 11) but I cannot make pins 8 or 12 go low.
It is as if there is another cog running somewhere that is issuing another dira and overriding my dira.
In desperation I went through all the zicog and commented out every dira I could find, but no luck there. Could it be in the service_io code?
This minor problem has me completely stumped, as I can't do any I/O if I can't get control of all the pins. Help etc would be most appreciated.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
www.smarthome.viviti.com/build
So I presume cpu.start or service_IO is driving the lines at some point in time causing your problem.
BTW I presume that the DAT normally follows and you are starting it correctly. i.e. You understand how cogs and pasm work.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Links to other interesting threads:
· Home of the MultiBladeProps: TriBlade,·RamBlade,·SixBlade, website
· Single Board Computer:·3 Propeller ICs·and a·TriBladeProp board (ZiCog Z80 Emulator)
· Prop Tools under Development or Completed (Index)
· Emulators: CPUs Z80 etc; Micros Altair etc;· Terminals·VT100 etc; (Index) ZiCog (Z80) , MoCog (6809)
· Search the Propeller forums·(uses advanced Google search)
My cruising website is: ·www.bluemagic.biz·· MultiBladeProp is: www.bluemagic.biz/cluso.htm
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
www.smarthome.viviti.com/build
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Links to other interesting threads:
· Home of the MultiBladeProps: TriBlade,·RamBlade,·SixBlade, website
· Single Board Computer:·3 Propeller ICs·and a·TriBladeProp board (ZiCog Z80 Emulator)
· Prop Tools under Development or Completed (Index)
· Emulators: CPUs Z80 etc; Micros Altair etc;· Terminals·VT100 etc; (Index) ZiCog (Z80) , MoCog (6809)
· Search the Propeller forums·(uses advanced Google search)
My cruising website is: ·www.bluemagic.biz·· MultiBladeProp is: www.bluemagic.biz/cluso.htm
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Links to other interesting threads:
· Home of the MultiBladeProps: TriBlade,·RamBlade,·SixBlade, website
· Single Board Computer:·3 Propeller ICs·and a·TriBladeProp board (ZiCog Z80 Emulator)
· Prop Tools under Development or Completed (Index)
· Emulators: CPUs Z80 etc; Micros Altair etc;· Terminals·VT100 etc; (Index) ZiCog (Z80) , MoCog (6809)
· Search the Propeller forums·(uses advanced Google search)
My cruising website is: ·www.bluemagic.biz·· MultiBladeProp is: www.bluemagic.biz/cluso.htm
In revision 2 of the board design I changed the pinouts so the SD pins are contiguous. I also dropped in a 9 resistor 10k SIL for pullups on everything that is needed if any/all prop pins are tristated. In particular, the SD pins and also the gate going into the 138, so that even if the 3 inputs to the 138 are floating, the outputs will all be high because the gate is pulled high.
Back to coding...
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
www.smarthome.viviti.com/build
Haven't had a chance to get back to coding since I was in Adelaide :-(
Suggest you hold off on Rev 2 until you checkout the performance of the system running. I suspect it will not be very efficent.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Links to other interesting threads:
· Home of the MultiBladeProps: TriBlade,·RamBlade,·SixBlade, website
· Single Board Computer:·3 Propeller ICs·and a·TriBladeProp board (ZiCog Z80 Emulator)
· Prop Tools under Development or Completed (Index)
· Emulators: CPUs Z80 etc; Micros Altair etc;· Terminals·VT100 etc; (Index) ZiCog (Z80) , MoCog (6809)
· Search the Propeller forums·(uses advanced Google search)
My cruising website is: ·www.bluemagic.biz·· MultiBladeProp is: www.bluemagic.biz/cluso.htm
(allowing for the forum not quite reproducing all the buff arrays which are contiguous)
and watch register A as this is single stepped:
Thanks ++ for that clue re non contiguous pins. That has really got things moving along quickly now.
Just a quick addition to your code in the single step could be the spacebar instruction
as it took me a little while to work out what to do to single step.
Ok, next step is to single step through the boot code. This is about 100 bytes of hex code. Not that reverse compiling isn't fun, but is there the source code for this tiny program somewhere?
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
www.smarthome.viviti.com/build
Post Edited (Dr_Acula) : 11/11/2009 1:16:02 PM GMT
I'd attach it here but I'm away from by Prop PC for a few hours.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
For me, the past is not over yet.
I must say it is a great way to learn about the zicog by building it up one step at a time.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
www.smarthome.viviti.com/build
Post Edited (Dr_Acula) : 11/11/2009 10:49:41 PM GMT
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
For me, the past is not over yet.
I'll be single stepping this, but just a quick note - it has a .org of 100H, but the zicog puts this code at $FF00. Anyway, it should be possible to trace as it sends back lots of messages to the spin code.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
www.smarthome.viviti.com/build
Post Edited (Dr_Acula) : 11/12/2009 7:26:00 AM GMT
If you look in ZIBOOT.PRN you can see the actual assembled opcodes. Notice all the jumps have the correct destination addresses for when running at FF00.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
For me, the past is not over yet.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
www.smarthome.viviti.com/build