Solved:: Help with PASM code
Yoda
Posts: 132
I am interfacing a propeller to a z80 computer to provide keyboard, vga, and uSD for hard drives. I have the output to the vga working. I am having trouble with the input ports. I seem to be getting random data. I think it is because of the variable timing of reading from the hub and the z80 is reading the port before the data is truly there. So I decided to implement the /WAIT signal on the z80 and let the propeller assert it while it is getting the data and then releasing it after the data is on the port. For some reason the I can never get the /WAIT signal to go low with the attached assembler code. I can write a simple spin toggle pin and that works fine. Here is the code - would appreciate any suggestions:
Also I have attached logic analyzer output that shows the problem. I am triggering on /CS and the signals from bottom to top are: /CS A0 A1 /RD /WAIT /WAIT NC NC /WAIT after to hex inverters
Thanks
Dave
Post Edited (Yoda) : 8/14/2009 9:20:16 PM GMT
{{ Input Ports +------/WAIT |+-----/RD ||+---- A1 |||+--- A0 ||||+--/CS ||||| ||||| P15..P0 --> xxxxxxxx_xxxxxxxx +------+ D7....D0 A1 A2 = 0 0 Status Port A1 A2 = 0 1 Keyboard Input Port }} Var long cog PUB start(statusPtr, keyPtr) status := statusPtr key := keyPtr cog := cognew(@input, 0) + 1 Dat org 0 input mov dira, input_port_mask 'set control + data = inputs, wait as output or outa, wait_bit 'make sure wait bit is high now input_loop waitpeq input_read, cntl_mask 'wait for CS and RD = Low xor outa, wait_bit 'toggle wait low mov t1, ina 'get input bits shr t1,#9 and t1, #1 wz 'check if A0 = 1 if_nz jmp #keyin 'A0 = 1, is a keyboard read request 'A0 = 0, is a staus read request rdlong t1, status 'get status byte and t1, #$FF 'make sure byte or dira, data_bits 'set D0-D7 as ouputs mov outa, t1 'output the status byte nop xor outa, wait_bit 'release wait waitpeq cs_bit, cs_bit 'wait for CS to go high mov dira, input_port_mask 'tri-state data and set cntl for input jmp #input_loop keyin rdlong t1,key 'Get Key from Hub and t1, #$FF 'Make sure it is a byte or dira, data_bits 'set D0-D7 as outputs mov outa, t1 'output key nop xor outa, wait_bit 'release wait waitpeq cs_bit, cs_bit 'wait for CS to go high mov dira, input_port_mask 'tri-state data and set cntl for input rdlong t2, status 'get status xor t2, #1 'clear key status bit wrlong t2, status 'write it to the global status jmp #input_loop data_bits LONG %00000000_00000000_00000000_11111111 input_read LONG %00000000_00000000_00000000_00000000 cntl_mask LONG %00000000_00000000_00001001_00000000 'mask for CS and RD Low ignore A0, A1 cs_bit LONG %00000000_00000000_00000001_00000000 wait_bit LONG %00000000_00000000_00010000_00000000 input_port_mask LONG %00000000_00000000_00010000_00000000 status LONG 0 key LONG 0 t1 LONG 0 t2 LONG 0
Also I have attached logic analyzer output that shows the problem. I am triggering on /CS and the signals from bottom to top are: /CS A0 A1 /RD /WAIT /WAIT NC NC /WAIT after to hex inverters
Thanks
Dave
Post Edited (Yoda) : 8/14/2009 9:20:16 PM GMT
Comments
Status and Key are pointers to hub addresses which have not been set correctly. You need to pass the pointers via the cognew command and fetch via the PTR register. Currently they are pointing to location 0 in hub and maybe corrupting any spin programs running. The spin instruction status := StatusPtr and key := KeyPtr does not do what you think it does :-(
I would also recomment you use ANDN DIRA,WAIT_BIT to turn off the bit (make input) and OR DIRA,WAIT_BIT to turn it on (make output). Saves a problem if you make a mistake with the XOR.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Links to other interesting threads:
· Home of the MultiBladeProps: TriBladeProp, RamBlade, TwinBlade,·SixBlade, website
· Single Board Computer:·3 Propeller ICs·and a·TriBladeProp board (ZiCog Z80 Emulator)
· Prop Tools under Development or Completed (Index)
· Emulators: Micros eg Altair, and Terminals eg VT100 (Index) ZiCog (Z80), MoCog (6809)
· Search the Propeller forums (via Google)
My cruising website is: ·www.bluemagic.biz·· MultiBladeProp is: www.bluemagic.biz/cluso.htm
Thanks for the input. I had seen parameter passing done this way in daSilva's tutorial. I can change that easily.
I am a little confused with second statement. I always want WAIT to be an ouptut. The only thing I want to do after the data is sent is to tri-state (make input) is D0-D7. Ah now that I think about it, I think you mean OUTA, not DIRA ?
Thanks again for looking at the code
I guess it still doesn't explain why the WAIT line is not going low?
If I run simple Toggle program from propeller manual with P12 it toggles perfectly?
Dave
Post Edited (Yoda) : 8/14/2009 1:46:33 PM GMT
You can force /WAIT to low with a pull-down and gate the output driver with a modification to DIRA, well that's what Cluso meant. I understand what you do and I simulated the code and it works fine. P12, i.e. /WAIT is asserted after the waitpeq and is always an output. :?:
The method is similar to the one I used for pPropQL (but inverted: I had to delay the assertion of DTACK) it should work.
Are /CS and /RD being asserted ? How is your decoding logic ? I mean you speak about a port.. is CS derived from IORQ or MEMRQ ? are you reading via in or ld ?
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Visit some of my articles at Propeller Wiki:
MATH on the propeller propeller.wikispaces.com/MATH
pPropQL: propeller.wikispaces.com/pPropQL
pPropQL020: propeller.wikispaces.com/pPropQL020
OMU for the pPropQL/020 propeller.wikispaces.com/OMU
I think I understand what you are saying, but what I am doing should work there ? Yes /CS is generating by combining A7-A3 and IORQ and RD comes directly buffered from z80. If I can get this /WAIT to work I think I am pretty much home free. It is really bugging me - I thought I had it working the other night as I was getting reliable data and last night it was not and I put logic analyzer on and can see that /WAIT is always HI now.
Dave
Use an extra pin as debug and toggle it before waitpeq (with an XOR). be careful to have the output always enabled.
One of two things can happen:
The code got out of sync
The condition CS+RD is not being met.
In yout scope/LA traces I do not know which trace is what, Can you re-post it with labels ?
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Visit some of my articles at Propeller Wiki:
MATH on the propeller propeller.wikispaces.com/MATH
pPropQL: propeller.wikispaces.com/pPropQL
pPropQL020: propeller.wikispaces.com/pPropQL020
OMU for the pPropQL/020 propeller.wikispaces.com/OMU
Cluso:
The parameters seem to be OK - I was following the model on page 10 of DaSilva's Machine Language Tutorial. The values seem to be going back and forth. The only problem I am occasionally getting double characters so it looks like I have a synchronization problem with the keyboard code I need to solve.
Thanks all for the help in solving.
The other point I was making, is that you should use ANDN and OR to set/clear pins or directions as this guarantees the correct value. XOR does in fact invert the pin/direction but if there is an error somewhere in the code, it can incorrectly change the pin/direction. Once you get used to the instruction, it makes more sense.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Links to other interesting threads:
· Home of the MultiBladeProps: TriBladeProp, RamBlade, TwinBlade,·SixBlade, website
· Single Board Computer:·3 Propeller ICs·and a·TriBladeProp board (ZiCog Z80 Emulator)
· Prop Tools under Development or Completed (Index)
· Emulators: Micros eg Altair, and Terminals eg VT100 (Index) ZiCog (Z80), MoCog (6809)
· Search the Propeller forums (via Google)
My cruising website is: ·www.bluemagic.biz·· MultiBladeProp is: www.bluemagic.biz/cluso.htm
I understand what you are saying about andn and it is a good point.
I am struggling with the second part of your answer. I understand how to pass parameters with par from cognew.
Why does what I am doing not work as it appears to work and if I add prints to my main module I can see status and key changing in the ways I would expect?
status and key are in the DAT section so have real addresses, so when I assign status:= statusPtr in the spin start routine, why is it not doing effectively a mov status, statusPtr so that status in assembler routine does not contain the address of statusPtr so that when I use status in the pasm code I am referencing the correct address in the hub? You say I am referencing hub address 0 in the pasm code - what am I missing. I probably should do a res 1 instead of long 0 but I do initialize status and key in the start routine?
Just to be clear I am calling start in main as inp.start(@status, @key) so I am passing addresses not values.
I can switch the code, but I am asking the question more for education and understanding.
Thanks
Dave
Post Edited (Yoda) : 8/15/2009 9:38:47 PM GMT
We seem to be travelling the same path. I have stuck to spin and /wailt until now. I an just sticking together a MK II on which I hope to allow the Z80 run on 3.3V or the prop on 5V or, in a British sort of way, both on 4.15V. I hope to improve on the fast clock, slower clock, walking pace clock and /wait variations. This one will rely on the prop for its clock via the synth object and give pal 48x16 (nascom)
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Style and grace : Nil point