Shop OBEX P1 Docs P2 Docs Learn Events
Self modifying PASM help — Parallax Forums

Self modifying PASM help

blittledblittled Posts: 681
edited 2015-11-06 02:22 in Propeller 1
I have a project where I am interfacing a ZX81 running at 3.25MHz to a Propeller to emulate a ZON-X81 sound board. I have one cog continually monitoring the bus and grabbing values from an IOREQ. Those values, the register index and value are stored into the hub. To speed the AYCog response up I want to pass the two values into the AYCog directly by using the par variable. I also put the 16 registers into the PASM rather than reading/writing the hub to hopefully make it more responsive since Z80 assembly code drivers do not work but ZX81 Basic code drivers do when interfacing with the AYCog found in the OBEX.
getRegisters  mov       tempValue, par     ' Get addr of Hub values for index and value
              rdlong    temp1, tempValue   ' Get index
              shl       temp1, #2          ' Adjust for long length
              add       temp1, #Reg0       ' Set up pointer to indexed register
              movd      :Setptr, temp1     ' Modify the read value
              add       tempValue, #4      ' Move to address of value destination to pointer
:SetPtr       rdlong    0-0, tempValue     ' store value into indexed register
              mov       frequency1, Reg0
              shl       frequency1, #8
              add       frequency1, Reg1
              shl       frequency1, #20
              mov       frequency2, Reg2
              shl       frequency2, #8
              add       frequency2, Reg3
              shl       frequency2, #20
              mov       frequency3, Reg4
              shl       frequency3, #8
              add       frequency3, Reg5
              shl       frequency3, #20
              add       tempValue,  #2
              mov       noisePeriod, Reg6
              and       noisePeriod, #$1f
              mov       enableRegister, Reg7
              min       noisePeriod, #2
              mov       amplitude1, Reg8
              and       amplitude1, #31
              mov       amplitude2, Reg9
              and       amplitude2, #31
              mov       amplitude3, Reg10
              and       amplitude3, #31
              mov       envelopePeriod, Reg11
              shl       noisePeriod, #20
              mov       temp1, Reg12
              shl       temp1, #8
              or        envelopePeriod, temp1           wz
        if_z  mov       envelopePeriod, half_period         ' 0 == half the period of 1
        if_nz shl       envelopePeriod, #16
              mov       envelopeShape, Reg13
              movd      oscValues, enableRegister
'             AYCog stuff
              jmp       #getRegisters

Reg0          res       1  
Reg1          res       1  
Reg2          res       1  
Reg3          res       1  
Reg4          res       1  
Reg5          res       1  
Reg6          res       1  
Reg7          res       1  
Reg8          res       1  
Reg9          res       1  
Reg10         res       1  
Reg11         res       1  
Reg12         res       1  
Reg13         res       1  
Res14         res       1  
Reg15         res       1

temp1         res       1
temp2         res       1 

Something isn't right with the code. All I get is silence. If I remove shl temp1, #2 I get a repeating patterns of tones that is not correct. Any advice would be appreciated. :)

Comments

  • ElectrodudeElectrodude Posts: 1,658
    edited 2015-11-06 04:06
    The "shl temp1, #2" line should not be there. Cogram is long addressed, so you shouldn't be adjusting for long length.

    Also, I don't really understand your register passing method. I'm guessing that another cog is writing a index to long[par] and a value to long[par+4]. Unless you're doing magic with timing that you haven't shown, a write request might get missed if you do two quickly in succession. What if you modify your code to set long[par] := -1 after it reads the value (and add a test in your reader to not read a value if index == -1)? Then, the writing cog will have a way to know that the old write request was seen and that it is safe to write a new request.
  • blittledblittled Posts: 681
    edited 2015-11-06 12:04
    You are right the cog that monitors the bus places the 2 values this cog uses into the hub.

    Isn't RES used to reserve a long? If so then when I get the address of Reg0 and add the index I have to multiply the index by 4 (shl #2) to point to the next Reg address since each Reg is a long not a byte.

    As for -1 index I'll just and $0F to the index before multiplying to keep the range to 0-15.

    I'm thinking of merging the cogs into one cog. I was just wondering if my use of MOVD was correct in using a pointer to an indexed reg was correct.
  • RES is used to reserve a long, but addressing in a cog is all done with longs. You can't directly address bytes in a cog.

    2048 bytes, 512 long indices, which is why cog addresses are 9 bits each.
Sign In or Register to comment.