Self modifying PASM help
blittled
Posts: 681
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.
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.
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
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.
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.
2048 bytes, 512 long indices, which is why cog addresses are 9 bits each.