heater said...
Here zicog with the working DAA for inspection.
Hmm.. here the ldi_lmm and ldd_lmm differ in the flags handling. The latter has the flags as MAME's z80 core does them, while the ldi_lmm keeps X and Y flags (should they be set). Perhaps the EXZ80DOC code expects X and Y to not be altered by LDI and LDD?
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
He died at the console of hunger and thirst.
Next day he was buried. Face down, nine edge first.
Re heater
1) Add a small Spin method to object that has recyclable DAT space. This new method simply returns the address of the start of the DAT section.
2) Call that method from your main code and save the address returned.
3) Start the COG of whatever object it is.
4) Now you can use the memory from the address you have saved for disk buffers or whatever. Be sure not to use too much!
That sounds just the sort of cunning plan that I need. I'll check that out tonight when I get home. Hopefully that will free up more than enough for the new opcodes as they are written.
The ldi and ldd do differ a bit in that version as was trying some experiments this evening. Previously they had the same flag setting steps and ldd failed. I'm almost sure ldd used to work in the last overlay version. I'll have to run that again. It takes such a long time.
I'm also pretty sure exz80doc does not care about X and Y flags. It has a mask in there that removes those flags when it accumulates checks sums and then it compares against a "doc" checksum instead of an "all" checksum. Besides many other ops work and none of them set X or Y at all.
I suspect the problem is elsewhere. For example this EX is using LDIR to shunt things around. LDIR has not been proven to work correctly in this new version.
Attached is a log of the last EX test run I made. It stops short, with a half dozen tests to go, due to the rechargeable batteries powering my Prop going flat! I'll try another run tomorrow.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
For me, the past is not over yet.
heater said...
The ldi and ldd do differ a bit in that version as was trying some experiments this evening. Previously they had the same flag setting steps and ldd failed. I'm almost sure ldd used to work in the last overlay version. I'll have to run that again. It takes such a long time.
I'm also pretty sure exz80doc does not care about X and Y flags. It has a mask in there that removes those flags when it accumulates checks sums and then it compares against a "doc" checksum instead of an "all" checksum. Besides many other ops work and none of them set X or Y at all.
I suspect the problem is elsewhere. For example this EX is using LDIR to shunt things around. LDIR has not been proven to work correctly in this new version.
Attached is a log of the last EX test run I made. It stops short, with a half dozen tests to go, due to the rechargeable batteries powering my Prop going flat! I'll try another run tomorrow.
Well, you are right. I took a look at the EX.MAC file on the CP/M disk. Pretty complicated and hard to understand, but the flags mask is obvious.
You could perhaps shorten the list in EX.MAC and not run the known-to-work tests? That should save some time.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
He died at the console of hunger and thirst.
Next day he was buried. Face down, nine edge first.
heater said...
I've already been playing with EX. Notice all the tests are ordered quickest ones first.
Well, I didn't see anything obvious in the first sweep. I'll take another look at it tomorrow, after taking a nap. Usually I spot bugs easier in the morning [noparse]:)[/noparse]
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
He died at the console of hunger and thirst.
Next day he was buried. Face down, nine edge first.
I am thinking of getting MP/M running with the zicog. I can see two solutions to running multiple user software. The first takes advantage of the fact that switching banks is very easy by changing the latch settings of the upper bytes on the ram chip. Exit the zicog (with an IN instruction, which might be trapped in CONIN polling for keyboard input, as this means CP/M is idling anyway), store the Z80 registers - especially the program counter, change the bank, get the Z80 registers from when this bank last ran (especially the program counter) and set the zicog running. One could have 8 CP/M machines all running at once.
But - there are issues with two programs trying to access files at the same time as well as ports, and maybe it might be better to run standard MP/M as this sort of thing has already been coded? Also, I think register A is stored locally in the cog - and I'm not sure how the 'main' spin program could access this?
Cluso did some work on banked memory. The standard system seems to be to preserve the top 16k and switch in and out the lower 48k. This is possibly easier on the triblade than on the dracblade, but at the simplest level, it needs some sort of trap in the memory access routine with the rule:-If the location is > 48k, then switch in bank 000% and if the location is <48k then switch in the bank nnn% that is currently selected (and I think MP/M needs a way to do that). It might only be 2-3 lines of pasm code to do this - and there is no space free on the dracblade!!
So - now a question about the new code being written. Firstly, now DAA is done, how many bytes did it end up (bigger or smaller than the old DAA)?
And the next question - is it possible to sacrifice a little speed by moving one or more other instructions into an overlay or LMM and save a few bytes necessary for running bank code in the memory access routine?
Why MP/M? Well I'm working on networking and it would be really cool to be happily typing in wordstar or coding in C, but at the same time another board is accessing a file in the background. Wirelessly even. And I think all that this needs is one user on MP/M to be the main user, and another user is the "network" program that is handling file transfers and forwarding of packets etc.
Your first multi-user CP/M is fraught with problems. As you observe you would need to keep track of multiple open files etc etc. I was wrong in a previous statement, reg A is actually in HUB. That was changed somewhere along the line. However flags and PC are in COG most of the time. Anyway that is the least of the problems with that technique.
I already added code to ZiCog to do bank switching a long time ago, 48K banked, 16K resident. It uses an OUT instruction to switch banks as expected by CP/M 3 and MP/M. It's behind #ifdefs so is not used and takes no space just now. It has never been tested but works much like you say. Look for "ifdef BANKED_MEMORY".
One day we will have CP/M 3 and maybe MP/M working. Actually MP/M may be easier to get going as it is built and booted from a working CP/M 2 system. We will have banked memory.
Big hold up here is that we no longer support the floppy drives. Sadly the CP/M 3 loader only understands floppy drives. I need to modify it for hard drive only system in much the same way as I did our CBIOSX.
Not sure about MP/M but if I remember correctly one can run CP/M 2 and then start MP/M as a command from there. This means no loader BIOS is required. Only the MP/M BIOS would need fixing for a HD system.
New DAA is 28 LONGs. Old DAA is 24 LONGs.
BUT new DAA does not need an overlay area in COG, it lives in HUB as LMM. So 24 LONGs saved in COG.
Also there is no overlay loader any more saving 14 LONGS.
Instead the is an LMM virtual machine 5 LONGs (could be 14 for the fast version).
Pullmoll has discovers a few wasted LONGs in ZiCog, I have added is suggestions.
Well after all these swings and roundabouts the LMM version of full up Z80 ZiCog I'm running here has 34 LONG's free.
We may well eat a few of these LONGs while fixing the broken ops but I'm hoping not many as we should be able to do most things in LMM now.
It is possible to move bits of our "resident" code to LMM if desperate for space. I'm not going to look at that just yet. Not whole instructions so much as most of that code is utility functions or "micro-ops" that are used by many instructions.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
For me, the past is not over yet.
I'm making some progress on recycling leftover hub space for variables. I'm using the serial port object. Call this after the cog has been started:
PUB location
return @entry ' returns the location of the hub space used by the serial port driver
DAT
'***********************************
'* Assembly language serial driver *
'***********************************
entry
...
Then define a pointer for this in the main VAR section
long buffcogserial ' location of serial port cog code (for recycling)
then define it, send it and test it reads back
buffcogserial :=uart.location ' find where the serial port cog code was - must run AFTER cog started
StoreBuff(5,150,1) ' store a test byte
vgatext.dec(getbuff(5,1)) ' not working
but here is the problem. I can send a byte and read it back if it is in the same PUB. But if I run the same code in a different PUB then the byte is not returned.
PUB Storebuff(i,j,k) ' replace the buff[noparse][[/noparse]] array with the leftover space from the serial driver
' i=location (0-255),j=value, k=number of bytes
i:=i + buffcogserial
vgatext.dec(i) ' this works
bytemove(@i,@j,k) ' this works
j:=0 'this works - clear j to make sure it really reads it back
bytemove(@j,@i,k) ' this works - read it back
vgatext.dec(j) ' this works - prints correct value in j
PUB GetBuff(i,k) | j ' i=location (0-255),j=value, k=number of bytes
'vgatext.dec(i) ' this works
i:=i + buffcogserial ' this works
vgatext.dec(i)' this works, same value as i above
vgatext.dec(k)' this works
bytemove(@j,@i,k) ' ? not working
vgatext.dec(j) ' correct value not returned
return j
comments next to each line re which ones work and which ones do not.
I suspect I'm missing something fundamental in Spin rather than the value not being there.
@ can get you the wrong address as it is supposed to return the offset from start of object.
@@ should get you the real address in HUB
@@@ Is in BST and HomeSpun for cases where none of the above work.
To be honest every time I think I understand the use of @s in Spin I'm wrong.
Now: buffcogserial is a pointer, a HUB memory address.
Therefore so is "i". As in after i:=i + buffcogserial
BYTEMOVE uses pointers as parameters. So
bytemove(@i,@j,k)
may well sort of work but it does not look right to me. It is passing the address of i and j as places to get and put bytes rather than i and j which are the addresses at which to get and put bytes.
Looks like you should drop The @'s there. You are probably not writing/reading from where you think you are.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
For me, the past is not over yet.
That is relevant even today. CP/M has a punch card reader port. I intend using that port for networking...
@heater, I hope you are ok multitasking here - questions and tasks coming from all directions. Ok, I'm stuck with saving the 256 bytes for the buffer, so I've gone and looked at the banked memory problem. I have found a rather big problem.
'Read a BYTE from location given by "address" of Z80 RAM into byte data_8
read_memory_byte
#ifdef banked_memory
cmp address, common_ram wc 'Address in resident RAM area ?
if_c add address, bank_offset 'No: Add offset to current memory bank in ext RAM
#endif
this is the code from your original zicog with options for the triblade, and it is the beginning of the code that writes to memory.
I can't add that code on the dracblade as I'm out of longs!
Yet, logically, testing for the bounds of the memory is going to be best done right at the beginning of read ram code, and at the beginning of write code too. (as indeed it is, but with 3 lines as there is an out of bounds line as well. ? that line not needed).
So four extra longs there. I deleted those some time ago to fit the dracblade ram driver.
I see the bank is selected with a write to port $40. That looks pretty straightforward.
So - how are things going on the LMM zicog with respect to cog memory requirements?
Be careful with that attempt of banked memory code. It buggers up the "address" variable when changing banks which I'm sure is going to upset a few Z80 instructions that expect "address" not to change after read/write_memory_byte.
That banked memory code is between #ifdef BANKED_MEMORY and #endif you should not need to delete any lines if BANKED_MEMORY is not defined.
What did I say? I forget. About 39 LONGs free in COG for a full up Z80! Hope not to eat too many fixing our broken ops.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
For me, the past is not over yet.
PUB Storebuff(i,j,k) ' replace the buff[noparse][[/noparse]] array with the leftover space from the serial driver
' i=location (0-255),j=value, k=number of bytes
i:=i + buffcogserial
vgatext.dec(i)
bytemove(i,@j,k) ' this stores the byte
j:=0 ' reset j
bytemove(@j,i,k) ' get the byte back - this works
vgatext.dec(j) ' prints correct value
PUB GetBuff(l,m) | n ' l=location (0-255),n=value, m=number of bytes
l:=l + buffcogserial ' this works
bytemove(@n,l,m)
vgatext.dec(n) ' not correct value
return n
I tried changing the variables between storebuff and getbuff but it doesn't help.
ok, @j is because the variable is going to where j is. but not @i because i is the memory location (somewhere round 23549).
storebuff is reading the byte back correctly so I'm pretty sure the @j is working. But if you do the same code from getbuff it does not read back (either with i,j,k or l,m,n)
I wish I understood spin better [noparse]:([/noparse]
That is relevant even today. CP/M has a punch card reader port. I intend using that port for networking...
Geeky, isn't it?
What's one little bug?
But he was determined, Then change two, then three more,
The others went home. As year followed year.
He dug out the flow chart And strangers would comment,
Deserted, alone. "Is that guy still here?"
Night passed into morning. He died at the console
The room was cluttered Of hunger and thirst
With core dumps, source listings. Next day he was buried
"I'm close," he muttered. Face down, nine edge first.
Chain smoking, cold coffee, And his wife through her tears
Logic, deduction. Accepted his fate.
"I've got it!" he cried, Said "He's not really gone,
"Just change one instruction." He's just working late."
-- The Perfect Programmer
Did anyone run my uber-geeky pm80_demo? It dumps the entire address space of the prop to Debug_1pinTV.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
He died at the console of hunger and thirst.
Next day he was buried. Face down, nine edge first.
Post Edited (pullmoll) : 3/10/2010 10:11:19 AM GMT
Yes, I don't understand spin. Using local variables didn't work. Maybe because the local variables are defined as longs with the | in a pub. So I defined a global variable
byte testbyte ' byte for buffcogserial
and then this code does work
PUB Storebuff(i) ' replace the buff[noparse][[/noparse]] array with the leftover space from the serial driver
' i=location (0-255),uses common variable testbyte, moves 1 byte
i:=i + buffcogserial
vgatext.dec(i)
bytemove(i,@testbyte,1) ' this stores the byte
testbyte:=0 ' testbyte
bytemove(@testbyte,i,1) ' get the byte back - this works
vgatext.dec(testbyte) ' prints correct value
PUB GetBuff(i) ' i =location
i:=i + buffcogserial
bytemove(@testbyte,i,1) ' this returns correct value in testbyte
return
I'm not sure but doesn't vgatxt.dec(n) print the string representing the value of the LONG n ?
So if BYTEMOVE only sets one byte at n the other three bytes of the LONG at n is undefined and it prints gibbersh?
Unless n or k are 4 at least in this case.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
For me, the past is not over yet.
I finally remove the entire buff[noparse]/noparse array and all references to it, replace it all with moving data in and out of the leftover hub space from a cog, it works and boots CP/M (this is vital for all sorts of things including poking the initial JMP in CP/M) and finally I do the grand finale and comment out array in the main VAR section
'byte buff[noparse][[/noparse]256]
and it doesn't save any memory?
Is this real or is it an error with the compiler? I thought adding variables in the VAR section reserved space for those variables
even more strange:
byte myarray[noparse][[/noparse]1000]
and download and it adds no more longs at all. But add myarray[noparse][[/noparse]50000] and it overflows and says out of memory. I'm starting to think the number of longs downloaded to ram may not be accurate??
Ha, you are right. F8 answers the question. The total goes down. Life is good. Now I can tackle the 512 byte array for disk I/O
Another question. I am pondering the interrupt for MP/M. If you check for a pseudo interrupt, does that add another pasm line to each instruction in the zicog? If so, that will be a real speed penalty. Ditto a system that says - load bank 2 and run 1000 instructions. You still have to count them. Any way around this?
I'm looking at the I/O traps - these get called all the time and I've even got ports being polled only every 250 I/O calls. Theoretically, a program could be running that never calls to the I/O ports (eg a really complex math program) and so I/O doesn't work. But for practical purposes, could the I/O routine in the main spin program be used as the interrupt for MP/M to do the bank switching??
Well, out goes the 256 byte buff[noparse]/noparse array and out goes the 512 byte disk_buff[noparse]/noparse array.
449 longs free. Yippee! That should be plenty to accomodate all the extra overlays. And there are still more to go - eg the 80 bytes used for the 20x4 LCD display.
I wonder, is this recycling of leftover hub ram a recognised programming technique, and is it used commonly?
simplify, simplify. This is the little poke routine that starts the initial jump.
bytefill(buffcogserial+0,$C3,1) ' this stores a byte
bytefill(buffcogserial+1,$00,1) ' this stores a byte
bytefill(buffcogserial+2,$FF,1) ' this stores a byte
RamLatches.DoCmd("W", buffcogserial, 0, 3) ' write 3 bytes in buffcogserial to address 0
saved two more longs compared with calling a subroutine
Err.. yes! The PropRPM board by elmicro.com. I posted the link in the other Z80 thread some days ago. IMO the pm80 code is ready to be extended by some external RAM access code to throw bigger things at it. All opcodes are there and there's even some space left in hub RAM.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
He died at the console of hunger and thirst.
Next day he was buried. Face down, nine edge first.
bytefill(buffcogserial+0,$C3,1) ' this stores a byte
bytefill(buffcogserial+1,$00,1) ' this stores a byte
bytefill(buffcogserial+2,$FF,1) ' this stores a byte
RamLatches.DoCmd("W", buffcogserial, 0, 3) ' write 3 bytes in buffcogserial to address 0
saved two more longs compared with calling a subroutine
Hm.. wouldn't byte[noparse][[/noparse]buffcogserial+0] := $c3 etc. be shorter than calling that function? I don't know Spin enough, so perhaps the function calls are encoded just as good.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
He died at the console of hunger and thirst.
Next day he was buried. Face down, nine edge first.
Comments
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Style and grace : Nil point
Hmm.. here the ldi_lmm and ldd_lmm differ in the flags handling. The latter has the flags as MAME's z80 core does them, while the ldi_lmm keeps X and Y flags (should they be set). Perhaps the EXZ80DOC code expects X and Y to not be altered by LDI and LDD?
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
He died at the console of hunger and thirst.
Next day he was buried. Face down, nine edge first.
1) Add a small Spin method to object that has recyclable DAT space. This new method simply returns the address of the start of the DAT section.
2) Call that method from your main code and save the address returned.
3) Start the COG of whatever object it is.
4) Now you can use the memory from the address you have saved for disk buffers or whatever. Be sure not to use too much!
That sounds just the sort of cunning plan that I need. I'll check that out tonight when I get home. Hopefully that will free up more than enough for the new opcodes as they are written.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
www.smarthome.viviti.com/propeller
I'm also pretty sure exz80doc does not care about X and Y flags. It has a mask in there that removes those flags when it accumulates checks sums and then it compares against a "doc" checksum instead of an "all" checksum. Besides many other ops work and none of them set X or Y at all.
I suspect the problem is elsewhere. For example this EX is using LDIR to shunt things around. LDIR has not been proven to work correctly in this new version.
Attached is a log of the last EX test run I made. It stops short, with a half dozen tests to go, due to the rechargeable batteries powering my Prop going flat! I'll try another run tomorrow.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
For me, the past is not over yet.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
For me, the past is not over yet.
Well, you are right. I took a look at the EX.MAC file on the CP/M disk. Pretty complicated and hard to understand, but the flags mask is obvious.
You could perhaps shorten the list in EX.MAC and not run the known-to-work tests? That should save some time.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
He died at the console of hunger and thirst.
Next day he was buried. Face down, nine edge first.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
For me, the past is not over yet.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
He died at the console of hunger and thirst.
Next day he was buried. Face down, nine edge first.
I am thinking of getting MP/M running with the zicog. I can see two solutions to running multiple user software. The first takes advantage of the fact that switching banks is very easy by changing the latch settings of the upper bytes on the ram chip. Exit the zicog (with an IN instruction, which might be trapped in CONIN polling for keyboard input, as this means CP/M is idling anyway), store the Z80 registers - especially the program counter, change the bank, get the Z80 registers from when this bank last ran (especially the program counter) and set the zicog running. One could have 8 CP/M machines all running at once.
But - there are issues with two programs trying to access files at the same time as well as ports, and maybe it might be better to run standard MP/M as this sort of thing has already been coded? Also, I think register A is stored locally in the cog - and I'm not sure how the 'main' spin program could access this?
Cluso did some work on banked memory. The standard system seems to be to preserve the top 16k and switch in and out the lower 48k. This is possibly easier on the triblade than on the dracblade, but at the simplest level, it needs some sort of trap in the memory access routine with the rule:-If the location is > 48k, then switch in bank 000% and if the location is <48k then switch in the bank nnn% that is currently selected (and I think MP/M needs a way to do that). It might only be 2-3 lines of pasm code to do this - and there is no space free on the dracblade!!
So - now a question about the new code being written. Firstly, now DAA is done, how many bytes did it end up (bigger or smaller than the old DAA)?
And the next question - is it possible to sacrifice a little speed by moving one or more other instructions into an overlay or LMM and save a few bytes necessary for running bank code in the memory access routine?
Why MP/M? Well I'm working on networking and it would be really cool to be happily typing in wordstar or coding in C, but at the same time another board is accessing a file in the background. Wirelessly even. And I think all that this needs is one user on MP/M to be the main user, and another user is the "network" program that is handling file transfers and forwarding of packets etc.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
www.smarthome.viviti.com/propeller
I already added code to ZiCog to do bank switching a long time ago, 48K banked, 16K resident. It uses an OUT instruction to switch banks as expected by CP/M 3 and MP/M. It's behind #ifdefs so is not used and takes no space just now. It has never been tested but works much like you say. Look for "ifdef BANKED_MEMORY".
One day we will have CP/M 3 and maybe MP/M working. Actually MP/M may be easier to get going as it is built and booted from a working CP/M 2 system. We will have banked memory.
Big hold up here is that we no longer support the floppy drives. Sadly the CP/M 3 loader only understands floppy drives. I need to modify it for hard drive only system in much the same way as I did our CBIOSX.
Not sure about MP/M but if I remember correctly one can run CP/M 2 and then start MP/M as a command from there. This means no loader BIOS is required. Only the MP/M BIOS would need fixing for a HD system.
New DAA is 28 LONGs. Old DAA is 24 LONGs.
BUT new DAA does not need an overlay area in COG, it lives in HUB as LMM. So 24 LONGs saved in COG.
Also there is no overlay loader any more saving 14 LONGS.
Instead the is an LMM virtual machine 5 LONGs (could be 14 for the fast version).
Pullmoll has discovers a few wasted LONGs in ZiCog, I have added is suggestions.
Well after all these swings and roundabouts the LMM version of full up Z80 ZiCog I'm running here has 34 LONG's free.
We may well eat a few of these LONGs while fixing the broken ops but I'm hoping not many as we should be able to do most things in LMM now.
It is possible to move bits of our "resident" code to LMM if desperate for space. I'm not going to look at that just yet. Not whole instructions so much as most of that code is utility functions or "micro-ops" that are used by many instructions.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
For me, the past is not over yet.
I'm making some progress on recycling leftover hub space for variables. I'm using the serial port object. Call this after the cog has been started:
Then define a pointer for this in the main VAR section
then define it, send it and test it reads back
but here is the problem. I can send a byte and read it back if it is in the same PUB. But if I run the same code in a different PUB then the byte is not returned.
comments next to each line re which ones work and which ones do not.
I suspect I'm missing something fundamental in Spin rather than the value not being there.
Any help would be most appreciated.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
www.smarthome.viviti.com/propeller
In fix_flags you have
The %1_0000_0000 is the same as $100, so you can do
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
He died at the console of hunger and thirst.
Next day he was buried. Face down, nine edge first.
@ can get you the wrong address as it is supposed to return the offset from start of object.
@@ should get you the real address in HUB
@@@ Is in BST and HomeSpun for cases where none of the above work.
To be honest every time I think I understand the use of @s in Spin I'm wrong.
Now: buffcogserial is a pointer, a HUB memory address.
Therefore so is "i". As in after i:=i + buffcogserial
BYTEMOVE uses pointers as parameters. So
bytemove(@i,@j,k)
may well sort of work but it does not look right to me. It is passing the address of i and j as places to get and put bytes rather than i and j which are the addresses at which to get and put bytes.
Looks like you should drop The @'s there. You are probably not writing/reading from where you think you are.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
For me, the past is not over yet.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
For me, the past is not over yet.
That is relevant even today. CP/M has a punch card reader port. I intend using that port for networking...
@heater, I hope you are ok multitasking here - questions and tasks coming from all directions. Ok, I'm stuck with saving the 256 bytes for the buffer, so I've gone and looked at the banked memory problem. I have found a rather big problem.
this is the code from your original zicog with options for the triblade, and it is the beginning of the code that writes to memory.
I can't add that code on the dracblade as I'm out of longs!
Yet, logically, testing for the bounds of the memory is going to be best done right at the beginning of read ram code, and at the beginning of write code too. (as indeed it is, but with 3 lines as there is an out of bounds line as well. ? that line not needed).
So four extra longs there. I deleted those some time ago to fit the dracblade ram driver.
I see the bank is selected with a write to port $40. That looks pretty straightforward.
So - how are things going on the LMM zicog with respect to cog memory requirements?
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
www.smarthome.viviti.com/propeller
That banked memory code is between #ifdef BANKED_MEMORY and #endif you should not need to delete any lines if BANKED_MEMORY is not defined.
What did I say? I forget. About 39 LONGs free in COG for a full up Z80! Hope not to eat too many fixing our broken ops.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
For me, the past is not over yet.
great news re free longs.
good find re the @.
I tried changing the variables between storebuff and getbuff but it doesn't help.
ok, @j is because the variable is going to where j is. but not @i because i is the memory location (somewhere round 23549).
storebuff is reading the byte back correctly so I'm pretty sure the @j is working. But if you do the same code from getbuff it does not read back (either with i,j,k or l,m,n)
I wish I understood spin better [noparse]:([/noparse]
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
www.smarthome.viviti.com/propeller
Geeky, isn't it?
Did anyone run my uber-geeky pm80_demo? It dumps the entire address space of the prop to Debug_1pinTV.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
He died at the console of hunger and thirst.
Next day he was buried. Face down, nine edge first.
Post Edited (pullmoll) : 3/10/2010 10:11:19 AM GMT
Yes, I don't understand spin. Using local variables didn't work. Maybe because the local variables are defined as longs with the | in a pub. So I defined a global variable
byte testbyte ' byte for buffcogserial
and then this code does work
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
www.smarthome.viviti.com/propeller
So if BYTEMOVE only sets one byte at n the other three bytes of the LONG at n is undefined and it prints gibbersh?
Unless n or k are 4 at least in this case.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
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)·
· Prop OS: SphinxOS·, PropDos , PropCmd··· Search the Propeller forums·(uses advanced Google search)
My cruising website is: ·www.bluemagic.biz·· MultiBlade Props: www.cluso.bluemagic.biz
I finally remove the entire buff[noparse]/noparse array and all references to it, replace it all with moving data in and out of the leftover hub space from a cog, it works and boots CP/M (this is vital for all sorts of things including poking the initial JMP in CP/M) and finally I do the grand finale and comment out array in the main VAR section
'byte buff[noparse][[/noparse]256]
and it doesn't save any memory?
Is this real or is it an error with the compiler? I thought adding variables in the VAR section reserved space for those variables
even more strange:
and download and it adds no more longs at all. But add myarray[noparse][[/noparse]50000] and it overflows and says out of memory. I'm starting to think the number of longs downloaded to ram may not be accurate??
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
www.smarthome.viviti.com/propeller
Post Edited (Dr_Acula) : 3/10/2010 10:36:09 AM GMT
In BST it reports program size, variable size and stack free.
Program size will not change if VARs are removed.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
For me, the past is not over yet.
Another question. I am pondering the interrupt for MP/M. If you check for a pseudo interrupt, does that add another pasm line to each instruction in the zicog? If so, that will be a real speed penalty. Ditto a system that says - load bank 2 and run 1000 instructions. You still have to count them. Any way around this?
I'm looking at the I/O traps - these get called all the time and I've even got ports being polled only every 250 I/O calls. Theoretically, a program could be running that never calls to the I/O ports (eg a really complex math program) and so I/O doesn't work. But for practical purposes, could the I/O routine in the main spin program be used as the interrupt for MP/M to do the bank switching??
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
www.smarthome.viviti.com/propeller
A big thank you! It's just what I needed for a simple console output I only had to export the pRENDEZVOUS as a PUB returning the value.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
He died at the console of hunger and thirst.
Next day he was buried. Face down, nine edge first.
Well, out goes the 256 byte buff[noparse]/noparse array and out goes the 512 byte disk_buff[noparse]/noparse array.
449 longs free. Yippee! That should be plenty to accomodate all the extra overlays. And there are still more to go - eg the 80 bytes used for the 20x4 LCD display.
I wonder, is this recycling of leftover hub ram a recognised programming technique, and is it used commonly?
simplify, simplify. This is the little poke routine that starts the initial jump.
saved two more longs compared with calling a subroutine
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
www.smarthome.viviti.com/propeller
Post Edited (Dr_Acula) : 3/10/2010 11:24:15 AM GMT
Err.. yes! The PropRPM board by elmicro.com. I posted the link in the other Z80 thread some days ago. IMO the pm80 code is ready to be extended by some external RAM access code to throw bigger things at it. All opcodes are there and there's even some space left in hub RAM.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
He died at the console of hunger and thirst.
Next day he was buried. Face down, nine edge first.
Hm.. wouldn't byte[noparse][[/noparse]buffcogserial+0] := $c3 etc. be shorter than calling that function? I don't know Spin enough, so perhaps the function calls are encoded just as good.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
He died at the console of hunger and thirst.
Next day he was buried. Face down, nine edge first.
Great news with your board arriving. And when you have two, it will be even better.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
www.smarthome.viviti.com/propeller
So using your logic:
and that saved one more long.
You are very good. How many coffees have you had today?
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
www.smarthome.viviti.com/propeller
Post Edited (Dr_Acula) : 3/10/2010 11:49:19 AM GMT