Shop OBEX P1 Docs P2 Docs Learn Events
Solved:: Help with PASM code — Parallax Forums

Solved:: Help with PASM code

YodaYoda Posts: 132
edited 2009-08-15 21:51 in Propeller 1
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:


{{                        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
889 x 732 - 99K

Comments

  • Cluso99Cluso99 Posts: 18,069
    edited 2009-08-14 09:34
    Yoda:
    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
  • YodaYoda Posts: 132
    edited 2009-08-14 13:41
    Cluso99:

    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
  • AleAle Posts: 2,363
    edited 2009-08-14 15:15
    Yoda:

    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
  • YodaYoda Posts: 132
    edited 2009-08-14 17:57
    Ale:

    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
  • AleAle Posts: 2,363
    edited 2009-08-14 20:23
    Yoda:

    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
  • YodaYoda Posts: 132
    edited 2009-08-14 21:15
    Problem is solved!! I had forgotten as temporary workaround I had set P12 to output HI in the initialization section so I could debug other things with out know what state /WAIT was in. Of course this cog was or'd output with the cog that was trying to set it low so it was never being set low Very embarrassing redface.gif

    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.
  • Cluso99Cluso99 Posts: 18,069
    edited 2009-08-15 05:43
    Yoda: Yes you need to pass the parameters otherwise you will find all sorts of strange behaviour because you are reading/writing to incorrect hub locations.

    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
  • YodaYoda Posts: 132
    edited 2009-08-15 21:33
    Hi Cluso

    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
  • Toby SeckshundToby Seckshund Posts: 2,027
    edited 2009-08-15 21:51
    @ Yoda

    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
Sign In or Register to comment.