6502.org
http://forum.6502.org/

Up/Down counter With CUPL
http://forum.6502.org/viewtopic.php?f=10&t=8099
Page 1 of 1

Author:  GlennSmith [ Tue Jun 11, 2024 3:31 pm ]
Post subject:  Up/Down counter With CUPL

Hello all,
I'm posting 'cos I'm at my wits end... I'm playing with an idea to have a USER stack pointer managed in a CPLD that's also doing some sneaky things like a USER ZP at $0200 (the usual undocumented opcodes & address substitution techniques). The ZP stuff should be OK, I have a state machine that looks like it should work.
Where I'm stuck is that I need an 8-bit bidirectional counter so that I can increment or decrement by 1 each time I POP or PUSH my user stack.
I've tried many examples found on the web - most of them just do not work. (BTW I use wincupl, as its free and directly supports the Atmel "GAL" type chips 16v8 / 22v10 and the ATF150x chips). I tried going through wiring an U/D counter in digital and using it's CUPL output, but that didn't seem to be correct either...
Have any of you programmed such a thing, and can anyone point me in the right direction so that I can make a definite decision as to whether it's worthwhile pursuing on not. The super-fast prop delays of the CPLDs is very enticing, and I'm glad I took the learning curve to already use SPLD for address decoding on my POC-WBC.
Thanks, in advance, for any help or insights.

Author:  gregorio [ Mon Jun 17, 2024 12:02 pm ]
Post subject:  Re: Up/Down counter With CUPL

Do you have something in mind that would work this way?
Code:
Name     counter_UP_DOWN ;
PartNo   00 ;
Date     15/06/2024 ;
Revision 01 ;
Designer Engineer ;
Company  ggg ;
Assembly None ;
Location  ;
Device   g16v8ms ;

PIN  1 = CLK    ;
PIN  2 = I      ;
PIN  3 = D ;
PIN  [12..15]   = [Q0..Q3]     ;

Q3.d = Q3&D $ !Q2&D & !Q1&D & !Q0&D # Q3&!D $ Q2&!D & Q1&!D & Q0&!D;
Q2.d = Q2&D $ !Q1&D & !Q0&D # Q2&!D $ Q1&!D & Q0&!D;
Q1.d = Q1&D $ !Q0&D #Q1&!D $ Q0&!D;
Q0.d = Q0 $ I;


Attachments:
Screenshot (221).png
Screenshot (221).png [ 74.86 KiB | Viewed 696 times ]

Author:  GlennSmith [ Tue Jun 18, 2024 8:54 am ]
Post subject:  Re: Up/Down counter With CUPL

Hi Gregorio
Quote:
Do you have something in mind that would work this way?


Yes, that's the sort of thing I was looking for. I actually went back "to the drawing board" with digital (the logic design/simulation thingy) and managed to get a working and intelligible routine for the whole 8-bits. Thanks!

I'm now pushing the limits of my newly-learned SPLD/CPLD knowledge to try and create my stack management (in page 3), and a "user" page zero (in page 2) in one CPLD device. I have been much inspired by George Foot's (gfoot) post about creating the special Acorn Turbo functions in a 22V10 - thanks George.

Garden, motorcycles, sunshine... all keeping me away from my thinking hat at the moment - but I'll be back!

Author:  GlennSmith [ Wed Jun 19, 2024 6:05 pm ]
Post subject:  Re: Up/Down counter With CUPL

Well, as promised - I'm back!

Some success with my project, there are still a few gotchas I need to iron-out, but I thought that I'd publish here anyway to (hopefully) help a few others.
Resume: my goal is to have one programmable device to handle a few 'trick' features :
  • Add a user ZP residing in page 2
  • Add a user STACK residing in page 3
  • Using 3 "undocumented NOP" instructions as triggers
The ZP2 logic is fairly easy, and it actually fits in a 22V10 device, but the logic for the STACK is more challenging and the stack UP/DOWN counter itself won't fit in a small device. So the target, for the moment, is an ATF1504 (if possible a 44plcc with jtag still enabled) to test the concept.
How it (should) work :
Three NOP opcodes (0x0B, 0x1B, 0x2B) are used to trigger ZP2, stack PUSH, stack POP respectively. The actual reading/writing is performed using normal ZP instructions, the CPLD logic handles the address 'phishing' and the stack load/save/increment/decrement stuff. The logic became VERY complex if I tried to include the load/save logic in the state machine - so I've reverted to using a single register to read/write the value as an I/O location.

Now I need to add the rest of the logic to cope with load/save, and look at the *REAL* timing in real life...
(EDIT: added some info on the workings)
Here is how I hope the system will work :
Code:
PUSH (value on stack)

    State   cycles  uP Data Bus     Signals     uP Addr Bus     Next State
    ==================================================================
    Push0   1cyc    Magic Opcode    SYNC R      N/A             Push1
    Push1   1cyc    Opcode (*)      SYNC R      N/A             Push2   (*) STA, STX, STY : ZP
            - decrement stack counter
    Push2   1cyc    ZP Address      N/A  R      N/A             Push3
            - substitute Addr A9=1, A8=1, + Low byte from stack pointer  [b]
    Push3   1cyc    data value      N/A  W      (stack ptr)     Idle
            - data is written to ZP3 location.  [c]

POP (value from stack)

    State   cycles  uP Data Bus     Signals     uP Addr Bus     Next State
    ==================================================================
    Pop0    1cyc    Magic Opcode    SYNC R      N/A             Pop1
    Pop1    1cyc    Opcode (*)      SYNC R      N/A             Pop2    (*) LDA, LDX, LDY : ZP
    Pop2    1cyc    ZP Address      N/A  R      N/A             Pop3
            - substitute Addr A9=1, A8=1, + Low byte from stack pointer  [b]
    Pop3    1cyc    Mem. data       N/A  R      ZP Address      Idle
            - data is read from ZP3 address. Increment stack counter.  [c]

ZP2 (user zero page)

    State   cycles  uP Data Bus     Signals     uP Addr Bus     Next State
    ==================================================================
    Zp0     1cyc    Magic Opcode(s) SYNC R      N/A             Zp1
    Zp1     1cyc    Opcode (*)      SYNC R      N/A             Zp2     (*) any ZP instruction ?
    Zp2     1cyc    ZP Address      N/A  R      N/A             Zp3
            - substitute A9=1 on the system AB. [d]
    Zp3     ?cycles : Actual execution, but in "false" ZP       Idle   


[a] Isolate system DB from uP, place CPLD data on uP DB.                        ( CPLD <= DB => uP )
[b] The uP adress bus is piped through the CPLD. ( CPLD >= AB => System (+ A9, A8) )
[c] No isolation required, the LDx/STx will read/write from/to the 'false' address in ZP3.
[d] Force just A9, hold in place for ?? cycles (depends on the instruction !) use SYNC ?


... and I know that I have also to make sure that I avoid interrupts happening, and all sorts of other gotchas... but a few months ago I didn't have a clue about even SPLDs!

Attachments:
File comment: simulation definitions (change to .si)
STACK_TRY6-si.txt [1.37 KiB]
Downloaded 16 times
File comment: 6th try CUPL file (change to .pld)
Stack_Try6-pld.txt [4.57 KiB]
Downloaded 18 times

Page 1 of 1 All times are UTC
Powered by phpBB® Forum Software © phpBB Group
http://www.phpbb.com/