heater said...
As you see I put up a lot of objections to the dynamic compilation idea when Ale suggested it.
Seems I'm a bit to dim to see ways around them. It's a fascinating technique.
Perhaps you could have a look at Zog sometime. The virtual machine in Zog is much much smaller and simpler than a Z80 and it desperately needs all the performance enhancement it can get[noparse]:)[/noparse]
I will do that, but it looks like I really have to learn Spin first. I don't understand the passing of parameters between a main, an object and the object's PASM code.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
He died at the console of hunger and thirst.
Next day he was buried. Face down, nine edge first.
I just posted a version of ZiCog using LMM to the ZiCog thread.
You can see how I pass a register area and an I/O rendezvous area to the ZiCog emulator objects start method and then how I set up everything in DAT prior to starting the emulator PASM with cognew.
You could pass those parameters into the PASM running COG via the second parameter of cognew which ends up in the PAR register of the COG when the PASM runs. I did not do that because extracting the parameters that way eats LONGs in COG.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
For me, the past is not over yet.
Hmm that USB serial error is a bit nasty, I'm sure I've got a couple of those Prolific things and they were working on Linux sometime not that long ago. It is possible that the Prop loader software is sending some FTDI specific commands, not sure. However like you say if you can get it to work another way don't bother trying to fix the hard things.
When passing stuff between objects the @ symbol is the way to go, need to keep an eye on pointers and make sure things you think are contiguous will end up that way once compiled, but you can do some fun stuff once you have it sorted. There are undoubtedly more efficient ways to do it, but I use the model from the Parallax VGA/TV drivers where you pass a pointer to the parameter block in hub and then copy it to cog at the start using par.
My system is Ubuntu 9.10 with all the latest patches and kernel. If I wanted to go ambitious, I could try to nail down the following syslog excerpt:
ar 6 15:39:16 ubuntu kernel: [noparse][[/noparse]726704.471918] usb 3-5: USB disconnect, address 2
Mar 6 15:41:33 ubuntu kernel: [noparse][[/noparse]726841.620342] INFO: task khubd:40 blocked for more than 120 seconds.
Mar 6 15:41:33 ubuntu kernel: [noparse][[/noparse]726841.620348] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
Mar 6 15:41:33 ubuntu kernel: [noparse][[/noparse]726841.620353] khubd D 00000000ffffffff 0 40 2 0x00000000
Mar 6 15:41:33 ubuntu kernel: [noparse][[/noparse]726841.620362] ffff880216cb9be0 0000000000000046 ffff8801ce5040a0 0000000000015880
Mar 6 15:41:33 ubuntu kernel: [noparse][[/noparse]726841.620370] ffff880216cb3110 0000000000015880 0000000000015880 0000000000015880
Mar 6 15:41:33 ubuntu kernel: [noparse][[/noparse]726841.620376] 0000000000015880 ffff880216cb3110 0000000000015880 0000000000015880
Mar 6 15:41:33 ubuntu kernel: [noparse][[/noparse]726841.620382] Call Trace:
Mar 6 15:41:33 ubuntu kernel: [noparse][[/noparse]726841.620397] [noparse][[/noparse]<ffffffff8139ec55>] usb_kill_urb+0x85/0xc0
Mar 6 15:41:33 ubuntu kernel: [noparse][[/noparse]726841.620406] [noparse][[/noparse]<ffffffff810789c0>] ? autoremove_wake_function+0x0/0x40
Mar 6 15:41:33 ubuntu kernel: [noparse][[/noparse]726841.620413] [noparse][[/noparse]<ffffffff8139ef06>] ? usb_get_urb+0x16/0x20
Mar 6 15:41:33 ubuntu kernel: [noparse][[/noparse]726841.620424] [noparse][[/noparse]<ffffffff8139d903>] usb_hcd_flush_endpoint+0x123/0x130
Mar 6 15:41:33 ubuntu kernel: [noparse][[/noparse]726841.620430] [noparse][[/noparse]<ffffffff8139f85a>] usb_disable_endpoint+0x5a/0xa0
Mar 6 15:41:33 ubuntu kernel: [noparse][[/noparse]726841.620436] [noparse][[/noparse]<ffffffff8139f8d0>] usb_disable_device+0x30/0x130
Mar 6 15:41:33 ubuntu kernel: [noparse][[/noparse]726841.620443] [noparse][[/noparse]<ffffffff813998fa>] usb_disconnect+0xca/0x140
Mar 6 15:41:33 ubuntu kernel: [noparse][[/noparse]726841.620449] [noparse][[/noparse]<ffffffff81399d2a>] hub_port_connect_change+0x8a/0x960
Mar 6 15:41:33 ubuntu kernel: [noparse][[/noparse]726841.620455] [noparse][[/noparse]<ffffffff8139ba92>] hub_events+0x3a2/0x590
Mar 6 15:41:33 ubuntu kernel: [noparse][[/noparse]726841.620462] [noparse][[/noparse]<ffffffff81527999>] ? thread_return+0x48/0x37f
Mar 6 15:41:33 ubuntu kernel: [noparse][[/noparse]726841.620467] [noparse][[/noparse]<ffffffff8139bc80>] ? hub_thread+0x0/0x190
Mar 6 15:41:33 ubuntu kernel: [noparse][[/noparse]726841.620472] [noparse][[/noparse]<ffffffff8139bcba>] hub_thread+0x3a/0x190
Mar 6 15:41:33 ubuntu kernel: [noparse][[/noparse]726841.620477] [noparse][[/noparse]<ffffffff810789c0>] ? autoremove_wake_function+0x0/0x40
Mar 6 15:41:33 ubuntu kernel: [noparse][[/noparse]726841.620482] [noparse][[/noparse]<ffffffff8139bc80>] ? hub_thread+0x0/0x190
Mar 6 15:41:33 ubuntu kernel: [noparse][[/noparse]726841.620487] [noparse][[/noparse]<ffffffff810785d6>] kthread+0xa6/0xb0
Mar 6 15:41:33 ubuntu kernel: [noparse][[/noparse]726841.620493] [noparse][[/noparse]<ffffffff810130ea>] child_rip+0xa/0x20
Mar 6 15:41:33 ubuntu kernel: [noparse][[/noparse]726841.620498] [noparse][[/noparse]<ffffffff81078530>] ? kthread+0x0/0xb0
Mar 6 15:41:33 ubuntu kernel: [noparse][[/noparse]726841.620505] [noparse][[/noparse]<ffffffff810130e0>] ? child_rip+0x0/0x20
Mar 6 15:41:33 ubuntu kernel: [noparse][[/noparse]726841.620559] INFO: task python:28266 blocked for more than 120 seconds.
The serial adapter is disconnecting under the kernel while it is open. I guess I don't need to say "That's not supposed to happen". Are you using an intermediate hub between the adapter and the root hub? Regardless, it's a bug in the kernel and should not be hanging the loader like that. I'd be interested in seeing an strace of the loader to see what in particular it's hanging up on.
I've got some pl2302 units around here somewhere, but I've never used them to talk to a prop.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
You only ever need two tools in life. If it moves and it shouldn't use Duct Tape. If it does not move and it should use WD40.
The serial adapter is disconnecting under the kernel while it is open. I guess I don't need to say "That's not supposed to happen". Are you using an intermediate hub between the adapter and the root hub? Regardless, it's a bug in the kernel and should not be hanging the loader like that. I'd be interested in seeing an strace of the loader to see what in particular it's hanging up on.
I've got some pl2302 units around here somewhere, but I've never used them to talk to a prop.
No, as far as I can tell there's no intermediate hub. I have an ASUS M3N78-EM motherboard which has 6 usb ports.
This time 'only' my USB mouse was hanging after the timeout happened.
Here's the link to pastebin.com with the strace output. As you probably noticed I renamed the Python script to proploader.py.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
He died at the console of hunger and thirst.
Next day he was buried. Face down, nine edge first.
Just a heads up and FYI: The Z80 is running its first few recompiled instructions. In pm80_demo.spin a little piece of code is created that writes to Debug_1pinTV using the Z80 OUT ($40),A command. Port $40 is stdout..
The code uses RST $38 to do the actual outs, which means that the restart opcode and return from subroutine are working. I had no luck yet with a string in memory and using HL to read it. I have to find the bug that sits in there.
If anyone has an idea what and how to throw it at the Z80 emu, please let me know.
Juergen
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
He died at the console of hunger and thirst.
Next day he was buried. Face down, nine edge first.
I'm thinking something like the original MicroSoft 4K BASIC for the Altair. Does not need any operating system just console ports. We had it running on the predecessor of ZiCog, PropAltair. Just an 8080 emulator.
4K BASIC does need RST working and requires some fixed number to be input from a "switch" port. I have the details somewhere.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
For me, the past is not over yet.
1744 longs free, i.e. 6976 bytes plus the 1024 bytes I now use as RAM. I think it makes no difference if the RAM is in the VAR or DAT areas!?
Hmm.. it does make a difference. With a "memory res 1024/4" in the DAT area of pm80_demo.spin the whole thing doesn't run.
I could perhaps try to implement the DracBlade external memory access instead of hub RAM.
How big is the Z80 exerciser and does it need anything else but an output function?
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
He died at the console of hunger and thirst.
Next day he was buried. Face down, nine edge first.
The exerciser is reported as 12K by CP/M so anywhere between 8K and 12K.
It only requires a console. Can be built using only 8080 ops. I did have it running without CP/M once but I think that version has long since disappeared.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
For me, the past is not over yet.
heater said...
The exerciser is reported as 12K by CP/M so anywhere between 8K and 12K.
It only requires a console. Can be built using only 8080 ops. I did have it running without CP/M once but I think that version has long since disappeared.
I'm going to squeeze the code by using more nested code snippet longs, then it should be possible to try the exerciser. Is it included in some archive you posted, or can you post it here?
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
He died at the console of hunger and thirst.
Next day he was buried. Face down, nine edge first.
Best thing is to get the AltairZ80 simulator from the SIMH project installed and running. Get the quick start for Linux here www.schorn.ch/cpm/intro.php
When you have that running CP/M the exerciser is on the CP/M 2 disk along with assembler source. You could then hack with it to go straight to your console rather than use CP/M BDOS calls. You can easily export source and executables from the CP/M 2 disk with the read and write commands provided "R.COM" and "W.COM".
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
For me, the past is not over yet.
So according to the strace it is flipping the DTR line to reset the prop, then squirting out the LFSR and never seeing a reply.
I guess the usb port goes away when the kernel sees the disconnect but the device dying is not being passed up the stack as the select() never returns a non-zero value.
Don't know where to go from here other than to suggest compiling a late vanilla kernel and trying with that. I don't have a pl2302 that is connected to a prop I can try and test with and I don't run any late Ubuntu Kernels. Both my machines run 8.04LTS and only one of those runs an Ubuntu kernel.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
You only ever need two tools in life. If it moves and it shouldn't use Duct Tape. If it does not move and it should use WD40.
D'OH! So this is the way I learn PASM by trial and error.
The Z80 recompiler couldn't work right with me using rdword and wrword PASM opcodes to read/write words. The manual states the address' lower bit will be cleared to zero resulting in an address pointing to a word boundary. Great. But the Z80 can address words at odd addresses too.
So now the little Hello world! demo is running and I can try and throw bigger pieces of Z80 code at it. The simh package on Ubuntu doesn't seem to contain the CP/M disks, so I have to find them elsewhere.
If you want to take a look at it, see the attachment.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
He died at the console of hunger and thirst.
Next day he was buried. Face down, nine edge first.
Also brilliant is that you have reminded me of a little ZiCog optimization I thought of months ago and forgot all about. Namely do a quick check for WORD aligned memory accesses and use read/write word when appropriate. This makes no difference just now as we are using external byte wide RAM but when we take Bill Henning's Virtual Memory system into use it will speed thing up a tad.
Also brilliant is that you have reminded me of a little ZiCog optimization I thought of months ago and forgot all about. Namely do a quick check for WORD aligned memory accesses and use read/write word when appropriate. This makes no difference just now as we are using external byte wide RAM but when we take Bill Henning's Virtual Memory system into use it will speed thing up a tad.
There's always that little bit more to squeeze. I had rather lengthy code to get an immediate 16bit word into one of the registers, until it came to me that I could just as well store that word in a long somewhere and do a simple mov. Now all imm16 of a piece of code are stored stack-like to the end of the cog RAM growing down, and code is compiled growing up, until both meet or an instruction is a terminal.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
He died at the console of hunger and thirst.
Next day he was buried. Face down, nine edge first.
I have now refactored the JR cond and JP cond opcodes so that they completely execute in cog RAM as long as the destination address of the jump lies within the compiled block. The effect is dramatic. A delay loop with a count 65536 is executed in about 1/10th of a second's time (guessed). Here's the Z80 source code that runs in the recompiler now:
If my calculations are right, then the loop uses 10 + 4 + 4 + 10 = 28 cycles, times 65536 = 1.835.008 times 10 = 18.350.080 ... that's almost too impressive.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
He died at the console of hunger and thirst.
Next day he was buried. Face down, nine edge first.
Mind you if you are bored there is those outstanding ZiCog ops to fix [noparse]:)[/noparse]
For instance: What's up with LDD?
ldd_lmm rdword address, h_reg
call #read_memory_byte 'data_8 = [noparse][[/noparse]HL]
sub address, #1
wrword address, h_reg 'HL = HL - 1
rdword address, d_reg
call #write_memory_byte '[noparse][[/noparse]DE] = data_8
sub address, #1
wrword address, d_reg 'DE = DE - 1
rdword data_16, b_reg
sub data_16, #1 wz
wrword data_16, b_reg 'BC = BC - 1
and flags, #(sign_bit | zero_bit | carry_bit)
if_nz or flags, #parity_bit
jmp #fetch
Strangely our LDI passes the EX test and is very much similar.
Do you use EXZ80ALL or EXZ80DOC? The former expects all flags to be right, and this includes X and Y.
I don't see anything special in your code. For comparison here's the MAME Z80 LDI and LDD macros:
LDI:
UINT8 io = RM((Z), (Z)->HL);
WM((Z), (Z)->DE, io);
(Z)->F &= SF | ZF | CF;
if (((Z)->A + io) & 0x02) (Z)->F |= YF; /* bit 1 -> flag 5 */
if (((Z)->A + io) & 0x08) (Z)->F |= XF; /* bit 3 -> flag 3 */
(Z)->HL++; (Z)->DE++; (Z)->BC--;
if((Z)->BC) (Z)->F |= VF;
LDD:
UINT8 io = RM((Z), (Z)->HL);
WM((Z), (Z)->DE, io);
(Z)->F &= SF | ZF | CF;
if (((Z)->A + io) & 0x02) (Z)->F |= YF; /* bit 1 -> flag 5 */
if (((Z)->A + io) & 0x08) (Z)->F |= XF; /* bit 3 -> flag 3 */
(Z)->HL--; (Z)->DE--; (Z)->BC--;
if ((Z)->BC) (Z)->F |= VF;
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
He died at the console of hunger and thirst.
Next day he was buried. Face down, nine edge first.
heater said...
I'm using EXZ80DOC. The "ALL" is too ambitious.
Ok, then the flgmask for ldi and ldd is 0d7h, that is %11010111 meaning all but X and Y flags.
You keep sign, zero and carry and just alter parity flag = 1 for BC non-zero. That's it. I don't know how it could fail. Perhaps it's looking at the transferred bytes, too?
Edit: Do you have your latest source somewhere so I can follow it? The most recent has different ldi and ldd implementations (flag bits).
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
He died at the console of hunger and thirst.
Next day he was buried. Face down, nine edge first.
I managed to squeeze the size of pm80 down to a mere 18036 bytes (4509 longs). That includes all Z80 opcodes, even pointers to all invalid ED xx opcodes.
That way I was able to paste EXZ80DOC.COM into the image and run it. Unfortunately it still jumps into the wild after successfully running the first test, just like its 8080/8085 counterpart. I could use some eagle eye who is acquainted with Z80, and PASM, to take a look at specificially the stack modifying opcodes: calls, returns, push, pop, ex (sp),hl - because I suspect a stupid bug in there.
The cog RAM left for the execution of compiled code is at 198 longs. Since I changed all the code to use byte size registers in long variables, that helped to dramatically simplify many Z80 opcode snippets at the expense of a few more cog longs. I think that even long sequence of code - say 30-40 Z80 instructions - should now be compiled into PASM and, in case of backwards (conditional) jumps, executed at the full 80 MHz of the cog. Many Z80 functions involve such backwards jumps, often with DJNZ, so this is optimized pretty well now.
In the next days I'll try to write some Z80 test code, like multiplication, division, CRC16 etc. to benchmark the results.
I must find this stupid bug that is still there or I am going mad
Perhaps I should take a break and go to the pub to kill some cells of my brain that prevent me from seeing it.
Anyway, the latest code is in the CVS repository and I will also update the head of this thread.
Juergen
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
He died at the console of hunger and thirst.
Next day he was buried. Face down, nine edge first.
Could someone with a TriBladeProp give the code (first entry) a try? I implemented the memory access like ZiCog does it. I have no idea how you would get the Z80 code in the RAM there before firing up pm80, though. I guess there is some PROM emulation that has a boot loader? Perhaps I have to change more things for it to work with the TriBladeProp, just tell me what else you need.
Oh, forgot to say: you will need the packages bison and flex for your *nix or CYGWIN, because the source contains my Z80 assembler which is written in lex/yacc.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
He died at the console of hunger and thirst.
Next day he was buried. Face down, nine edge first.
To get code into external RAM before starting the Z80 you need Cluso's TriBladeProp_Blade2.spin driver. ZiCog uses it to write a 256 byte bootloader "ROM" image prior to starting emulation.
Best thing is to hunt backwards through the ZiCog or TriBladeProp threads and find a recent ZiCog test release where you will find everything. There has not been a proper major release for ages.
Note that either the Z80 emulation or the hardware support simulation, disks etc, can access the RAM whist running. To do that there are some PASM instructions in the emulated IN and OUT instruction that basically "handover" the external RAM pins to the Spin hardware emulation. This is basically because TriBlade has the SD card sharing RAM pins.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
For me, the past is not over yet.
heater said...
To get code into external RAM before starting the Z80 you need Cluso's TriBladeProp_Blade2.spin driver. ZiCog uses it to write a 256 byte bootloader "ROM" image prior to starting emulation.
Best thing is to hunt backwards through the ZiCog or TriBladeProp threads and find a recent ZiCog test release where you will find everything. There has not been a proper major release for ages.
Note that either the Z80 emulation or the hardware support simulation, disks etc, can access the RAM whist running. To do that there are some PASM instructions in the emulated IN and OUT instruction that basically "handover" the external RAM pins to the Spin hardware emulation. This is basically because TriBlade has the SD card sharing RAM pins.
Ah. Ok, I saw that port FE is used to communicate with the "hardware". Is there a source file for BOOTDSK_.ROM or was it coded in hex?
I guess I can peek at ZiCog to see how you handle port FE i/o. I hope it doesn't eat too many cog longs
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
He died at the console of hunger and thirst.
Next day he was buried. Face down, nine edge first.
heater said...
The boot code is attached. It's modified from the SIMH AltairZ80 DSKBOOT.MAC
Thanks a lot! I'll modify my rd_port and wr_port routines to support the TriBladeProp style of i/o. For the 1 prop environment I'll have to start another cog to handle the i/o requests...
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
He died at the console of hunger and thirst.
Next day he was buried. Face down, nine edge first.
Basically all our console and disk I/O is modelled on that of the AltairZ80 simulator. Originally we used the AltairZ80 floppy drive interface to boot from and could therefore take AltairZ80 floppy images to boot from. This was terrible slow as the floppy interface does not use DMA but byte by byte I/O through a port. Worse still the Altair floppies had 137 byte sectors, blech. So we threw out the floppy drive simulation and now have 8MB hard drives A: B: C:... This meant creating the ZIBOOT ROM loader so as to be able to boot from hard disks. Additionally the CP/M BIOS was changed to remove the floppy drivers.
Now those 8MB hard drive images live as files in the FAT formatted SD card. You have to write them to a newly formatted card to be sure they occupy contiguous sectors on the disk. zicog_cpm.spin finds the start sectors of those drive image files on SD and then accesses them during simulation as direct block reads/writes to the low level SD driver.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
For me, the past is not over yet.
heater said...
Basically all our console and disk I/O is modelled on that of the AltairZ80 simulator. Originally we used the AltairZ80 floppy drive interface to boot from and could therefore take AltairZ80 floppy images to boot from. This was terrible slow as the floppy interface does not use DMA but byte by byte I/O through a port. Worse still the Altair floppies had 137 byte sectors, blech. So we threw out the floppy drive simulation and now have 8MB hard drives A: B: C:... This meant creating the ZIBOOT ROM loader so as to be able to boot from hard disks. Additionally the CP/M BIOS was changed to remove the floppy drivers.
Now those 8MB hard drive images live as files in the FAT formatted SD card. You have to write them to a newly formatted card to be sure they occupy contiguous sectors on the disk. zicog_cpm.spin finds the start sectors of those drive image files on SD and then accesses them during simulation as direct block reads/writes to the low level SD driver.
Ok. I understand that. I'm not sure if I should support any of this in the 1 Propeller io.spin I just wrote. I don't (yet) have RAM or SD to access, so I just don't care.
However the Debug_1pinTV is now used in io.spin to redirect console output there. Ok, that is working now.
Do you run all the nops from 0000 until you hit the ROM at ff00? It seems so...
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
He died at the console of hunger and thirst.
Next day he was buried. Face down, nine edge first.
Re "Do you run all the nops from 0000 until you hit the ROM at ff00? It seems so..."
Ah, that was actually the code you were helping me with a couple of days ago. Poke 3 bytes at location 0,1,2 and those three bytes are C3, 00 and FF.
So the steps for startup on the dracblade are:
' Initialise serial ports, keyboard, vga screen
' Find the location of all the hard drives on the sd card and store the location of each
FindSDblock
' Poke C3, 00 FF to ram 0,1,2
long[noparse][[/noparse]buffcog]:=$00FF00C3 ' and then
RamLatches.DoCmd("W", buffcog, 0, 3) ' write 3 bytes in buffcog to address 0
' Load BOOT.DSK into the buffer
r := sd.readSDCard(drive_base[noparse][[/noparse]17], buffcog, 256) 'get 256 bytes "BOOTxxxx.ROM"
r := RamLatches.DoCmd("W", buffcog, $FF00, 256) 'write 256 bytes from buff to sram
and then start the zicog.
as an aside, my grand plan to recycle leftover cog space hit a slight problem. I was recycling vga space - then realised that the screensaver shuts down and then reloads vga code! So I change to recycling the serial port code, and then realised that needs reloading if the baud rate changes! So I'm recycling the keyboard code as that is never reloaded. So the pointer to the recycled hub ram is 'buffcog' above. Of course, now that this system works, it would be entirely possible to shift vga and serial port cog code over to ram or even sd card for temporary storage.
Comments
I will do that, but it looks like I really have to learn Spin first. I don't understand the passing of parameters between a main, an object and the object's PASM code.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
He died at the console of hunger and thirst.
Next day he was buried. Face down, nine edge first.
You can see how I pass a register area and an I/O rendezvous area to the ZiCog emulator objects start method and then how I set up everything in DAT prior to starting the emulator PASM with cognew.
You could pass those parameters into the PASM running COG via the second parameter of cognew which ends up in the PAR register of the COG when the PASM runs. I did not do that because extracting the parameters that way eats LONGs in COG.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
For me, the past is not over yet.
When passing stuff between objects the @ symbol is the way to go, need to keep an eye on pointers and make sure things you think are contiguous will end up that way once compiled, but you can do some fun stuff once you have it sorted. There are undoubtedly more efficient ways to do it, but I use the model from the Parallax VGA/TV drivers where you pass a pointer to the parameter block in hub and then copy it to cog at the start using par.
The serial adapter is disconnecting under the kernel while it is open. I guess I don't need to say "That's not supposed to happen". Are you using an intermediate hub between the adapter and the root hub? Regardless, it's a bug in the kernel and should not be hanging the loader like that. I'd be interested in seeing an strace of the loader to see what in particular it's hanging up on.
I've got some pl2302 units around here somewhere, but I've never used them to talk to a prop.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
You only ever need two tools in life. If it moves and it shouldn't use Duct Tape. If it does not move and it should use WD40.
No, as far as I can tell there's no intermediate hub. I have an ASUS M3N78-EM motherboard which has 6 usb ports.
This time 'only' my USB mouse was hanging after the timeout happened.
Here's the link to pastebin.com with the strace output. As you probably noticed I renamed the Python script to proploader.py.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
He died at the console of hunger and thirst.
Next day he was buried. Face down, nine edge first.
Post Edited (pullmoll) : 3/8/2010 10:09:15 AM GMT
The code uses RST $38 to do the actual outs, which means that the restart opcode and return from subroutine are working. I had no luck yet with a string in memory and using HL to read it. I have to find the bug that sits in there.
If anyone has an idea what and how to throw it at the Z80 emu, please let me know.
Juergen
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
He died at the console of hunger and thirst.
Next day he was buried. Face down, nine edge first.
How big a piece of code can we throw at it?
I'm thinking something like the original MicroSoft 4K BASIC for the Altair. Does not need any operating system just console ports. We had it running on the predecessor of ZiCog, PropAltair. Just an 8080 emulator.
4K BASIC does need RST working and requires some fixed number to be input from a "switch" port. I have the details somewhere.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
For me, the past is not over yet.
1744 longs free, i.e. 6976 bytes plus the 1024 bytes I now use as RAM. I think it makes no difference if the RAM is in the VAR or DAT areas!?
Hmm.. it does make a difference. With a "memory res 1024/4" in the DAT area of pm80_demo.spin the whole thing doesn't run.
I could perhaps try to implement the DracBlade external memory access instead of hub RAM.
How big is the Z80 exerciser and does it need anything else but an output function?
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
He died at the console of hunger and thirst.
Next day he was buried. Face down, nine edge first.
Post Edited (pullmoll) : 3/8/2010 6:39:59 PM GMT
It only requires a console. Can be built using only 8080 ops. I did have it running without CP/M once but I think that version has long since disappeared.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
For me, the past is not over yet.
I'm going to squeeze the code by using more nested code snippet longs, then it should be possible to try the exerciser. Is it included in some archive you posted, or can you post it here?
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
He died at the console of hunger and thirst.
Next day he was buried. Face down, nine edge first.
When you have that running CP/M the exerciser is on the CP/M 2 disk along with assembler source. You could then hack with it to go straight to your console rather than use CP/M BDOS calls. You can easily export source and executables from the CP/M 2 disk with the read and write commands provided "R.COM" and "W.COM".
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
For me, the past is not over yet.
So according to the strace it is flipping the DTR line to reset the prop, then squirting out the LFSR and never seeing a reply.
I guess the usb port goes away when the kernel sees the disconnect but the device dying is not being passed up the stack as the select() never returns a non-zero value.
Don't know where to go from here other than to suggest compiling a late vanilla kernel and trying with that. I don't have a pl2302 that is connected to a prop I can try and test with and I don't run any late Ubuntu Kernels. Both my machines run 8.04LTS and only one of those runs an Ubuntu kernel.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
You only ever need two tools in life. If it moves and it shouldn't use Duct Tape. If it does not move and it should use WD40.
The Z80 recompiler couldn't work right with me using rdword and wrword PASM opcodes to read/write words. The manual states the address' lower bit will be cleared to zero resulting in an address pointing to a word boundary. Great. But the Z80 can address words at odd addresses too.
So now the little Hello world! demo is running and I can try and throw bigger pieces of Z80 code at it. The simh package on Ubuntu doesn't seem to contain the CP/M disks, so I have to find them elsewhere.
If you want to take a look at it, see the attachment.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
He died at the console of hunger and thirst.
Next day he was buried. Face down, nine edge first.
Post Edited (pullmoll) : 3/9/2010 6:11:55 AM GMT
Also brilliant is that you have reminded me of a little ZiCog optimization I thought of months ago and forgot all about. Namely do a quick check for WORD aligned memory accesses and use read/write word when appropriate. This makes no difference just now as we are using external byte wide RAM but when we take Bill Henning's Virtual Memory system into use it will speed thing up a tad.
CP/M disks from www.schorn.ch/cpm/intro.php
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
For me, the past is not over yet.
There's always that little bit more to squeeze. I had rather lengthy code to get an immediate 16bit word into one of the registers, until it came to me that I could just as well store that word in a long somewhere and do a simple mov. Now all imm16 of a piece of code are stored stack-like to the end of the cog RAM growing down, and code is compiled growing up, until both meet or an instruction is a terminal.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
He died at the console of hunger and thirst.
Next day he was buried. Face down, nine edge first.
I have now refactored the JR cond and JP cond opcodes so that they completely execute in cog RAM as long as the destination address of the jump lies within the compiled block. The effect is dramatic. A delay loop with a count 65536 is executed in about 1/10th of a second's time (guessed). Here's the Z80 source code that runs in the recompiler now:
If my calculations are right, then the loop uses 10 + 4 + 4 + 10 = 28 cycles, times 65536 = 1.835.008 times 10 = 18.350.080 ... that's almost too impressive.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
He died at the console of hunger and thirst.
Next day he was buried. Face down, nine edge first.
Post Edited (pullmoll) : 3/9/2010 10:57:21 AM GMT
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
He died at the console of hunger and thirst.
Next day he was buried. Face down, nine edge first.
Zog thread starts here http://forums.parallax.com/showthread.php?p=878273
Zog is in much need of 1) External memory via VMCog 2) Optimizing, it's written in the most dumb straightforward way just now.
Mind you if you are bored there is those outstanding ZiCog ops to fix [noparse]:)[/noparse]
For instance: What's up with LDD?
Strangely our LDI passes the EX test and is very much similar.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
For me, the past is not over yet.
Do you use EXZ80ALL or EXZ80DOC? The former expects all flags to be right, and this includes X and Y.
I don't see anything special in your code. For comparison here's the MAME Z80 LDI and LDD macros:
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
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.
Post Edited (heater) : 3/12/2010 8:28:55 PM GMT
You keep sign, zero and carry and just alter parity flag = 1 for BC non-zero. That's it. I don't know how it could fail. Perhaps it's looking at the transferred bytes, too?
Edit: Do you have your latest source somewhere so I can follow it? The most recent has different ldi and ldd implementations (flag bits).
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
He died at the console of hunger and thirst.
Next day he was buried. Face down, nine edge first.
Post Edited (pullmoll) : 3/9/2010 7:51:01 PM GMT
That way I was able to paste EXZ80DOC.COM into the image and run it. Unfortunately it still jumps into the wild after successfully running the first test, just like its 8080/8085 counterpart. I could use some eagle eye who is acquainted with Z80, and PASM, to take a look at specificially the stack modifying opcodes: calls, returns, push, pop, ex (sp),hl - because I suspect a stupid bug in there.
The cog RAM left for the execution of compiled code is at 198 longs. Since I changed all the code to use byte size registers in long variables, that helped to dramatically simplify many Z80 opcode snippets at the expense of a few more cog longs. I think that even long sequence of code - say 30-40 Z80 instructions - should now be compiled into PASM and, in case of backwards (conditional) jumps, executed at the full 80 MHz of the cog. Many Z80 functions involve such backwards jumps, often with DJNZ, so this is optimized pretty well now.
In the next days I'll try to write some Z80 test code, like multiplication, division, CRC16 etc. to benchmark the results.
I must find this stupid bug that is still there or I am going mad
Perhaps I should take a break and go to the pub to kill some cells of my brain that prevent me from seeing it.
Anyway, the latest code is in the CVS repository and I will also update the head of this thread.
Juergen
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
He died at the console of hunger and thirst.
Next day he was buried. Face down, nine edge first.
Post Edited (pullmoll) : 3/11/2010 6:31:04 PM GMT
Oh, forgot to say: you will need the packages bison and flex for your *nix or CYGWIN, because the source contains my Z80 assembler which is written in lex/yacc.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
He died at the console of hunger and thirst.
Next day he was buried. Face down, nine edge first.
Post Edited (pullmoll) : 3/12/2010 7:17:18 PM GMT
Best thing is to hunt backwards through the ZiCog or TriBladeProp threads and find a recent ZiCog test release where you will find everything. There has not been a proper major release for ages.
Note that either the Z80 emulation or the hardware support simulation, disks etc, can access the RAM whist running. To do that there are some PASM instructions in the emulated IN and OUT instruction that basically "handover" the external RAM pins to the Spin hardware emulation. This is basically because TriBlade has the SD card sharing RAM pins.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
For me, the past is not over yet.
Ah. Ok, I saw that port FE is used to communicate with the "hardware". Is there a source file for BOOTDSK_.ROM or was it coded in hex?
I guess I can peek at ZiCog to see how you handle port FE i/o. I hope it doesn't eat too many cog longs
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
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.
Post Edited (heater) : 3/12/2010 8:29:42 PM GMT
Thanks a lot! I'll modify my rd_port and wr_port routines to support the TriBladeProp style of i/o. For the 1 prop environment I'll have to start another cog to handle the i/o requests...
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
He died at the console of hunger and thirst.
Next day he was buried. Face down, nine edge first.
Now those 8MB hard drive images live as files in the FAT formatted SD card. You have to write them to a newly formatted card to be sure they occupy contiguous sectors on the disk. zicog_cpm.spin finds the start sectors of those drive image files on SD and then accesses them during simulation as direct block reads/writes to the low level SD driver.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
For me, the past is not over yet.
Ok. I understand that. I'm not sure if I should support any of this in the 1 Propeller io.spin I just wrote. I don't (yet) have RAM or SD to access, so I just don't care.
However the Debug_1pinTV is now used in io.spin to redirect console output there. Ok, that is working now.
Do you run all the nops from 0000 until you hit the ROM at ff00? It seems so...
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
He died at the console of hunger and thirst.
Next day he was buried. Face down, nine edge first.
Post Edited (pullmoll) : 3/12/2010 9:28:39 PM GMT
Ah, that was actually the code you were helping me with a couple of days ago. Poke 3 bytes at location 0,1,2 and those three bytes are C3, 00 and FF.
So the steps for startup on the dracblade are:
and then start the zicog.
as an aside, my grand plan to recycle leftover cog space hit a slight problem. I was recycling vga space - then realised that the screensaver shuts down and then reloads vga code! So I change to recycling the serial port code, and then realised that needs reloading if the baud rate changes! So I'm recycling the keyboard code as that is never reloaded. So the pointer to the recycled hub ram is 'buffcog' above. Of course, now that this system works, it would be entirely possible to shift vga and serial port cog code over to ram or even sd card for temporary storage.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
www.smarthome.viviti.com/propeller
Post Edited (Dr_Acula) : 3/12/2010 11:54:08 PM GMT