6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Mon Nov 11, 2024 8:13 pm

All times are UTC




Post new topic Reply to topic  [ 12 posts ] 
Author Message
PostPosted: Thu Aug 06, 2020 3:17 pm 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10977
Location: England
Prompted by a nearby comment, here's a pointless mini-challenge: what kinds of useful interrupt handler can be written without using A, X, or Y and therefore without saving or restoring them?

Is it even the case that such a hampered ISR can perform an arbitrary function, by means of great cunning?


Top
 Profile  
Reply with quote  
PostPosted: Thu Aug 06, 2020 3:36 pm 
Offline

Joined: Fri Jan 25, 2019 2:29 pm
Posts: 192
Location: Madrid, Spain
I'm thinking.... Some kind of debugging stuff...

Use an indirect zp addressing to store the accumulator into some position in memory. Then, increment the zp pointer.

Then you can inspect the different values the accumulator has had.

Can't see any real use for it though... But I'm just thinking out loud I guess


Top
 Profile  
Reply with quote  
PostPosted: Thu Aug 06, 2020 3:57 pm 
Offline

Joined: Tue Sep 03, 2002 12:58 pm
Posts: 336
Use BIT to check the interrupt request bits (which you have carefully placed in bits 6 and 7 of IO locations) and see which interrupt source needs handling.
Use LSR to read the bit coming in from your serial interface, and ROR to place it into your 'incoming bits' data.
If that location was initialised with $80, you can use the carry flag to see when all 8 bits have been shifted in, and use INC to set the "you have a new byte" flag for the main program. You'd have to ensure that it uses that byte before another bit comes in, but we're not going for practicality here. Or you can do 8 more shift/rotates and copy the byte somewhere else (setting 'incoming bits' back to $80 in the process).

Rotate instructions can be used to read and copy data (one bit at a time), and BCC/BCS can branch depending on their values. I'd say that's more than sufficient for general processing. If you don't mind horrendous inefficiency.


Top
 Profile  
Reply with quote  
PostPosted: Thu Aug 06, 2020 3:59 pm 
Offline
User avatar

Joined: Tue Mar 05, 2013 4:31 am
Posts: 1385
In general, nothing of much value can be done without registers. However, you could possibly have a free-running hardware timer that generates an interrupt at "x" clocks, ns, ms, etc. The ISR could simply increment or decrement a memory or I/O register and not much else... if in Page Zero, one could leverage some of Rockwell enhanced instructions for bit set/reset/test/branch... and could possibly be useful if I/O is located in Page Zero.

Beyond this, the mini-challenge falls into an old category we used to call "a solution in search of a problem".

_________________
Regards, KM
https://github.com/floobydust


Top
 Profile  
Reply with quote  
PostPosted: Thu Aug 06, 2020 4:22 pm 
Offline

Joined: Thu Apr 23, 2020 5:04 pm
Posts: 51
BigEd wrote:
Prompted by a nearby comment, here's a pointless mini-challenge: what kinds of useful interrupt handler can be written without using A, X, or Y and therefore without saving or restoring them?

Is it even the case that such a hampered ISR can perform an arbitrary function, by means of great cunning?

How about the following untested code:
Code:
stack: ; align to a page
 reserve 256
ival:
 inc stack
 rts
dval:
 dec stack
 rts
isp:
 inc ival+1
 inc dval+1
 rts
dsp:
 dec ival+1
 dec dval+1
 rts
checkzero:
 jsr ival
 jsr dval
 rts

Now brainfuck code can be translated as follows:
Code:
<: jsr dsp
>: jsr isp
+: jsr ival
-: jsr dval
[: <new-label>
]: jsr checkzero; bne <new-label>

Brainfuck is turing-complete (memory-limitations aside), so you should be able to compute arbitrary functions.


Top
 Profile  
Reply with quote  
PostPosted: Thu Aug 06, 2020 5:35 pm 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10977
Location: England
That's nice John - serial without registers!

And vbc - good one, as you say, once you have Turing-complete, you're there!


Top
 Profile  
Reply with quote  
PostPosted: Thu Aug 06, 2020 7:25 pm 
Offline
User avatar

Joined: Wed Feb 14, 2018 2:33 pm
Posts: 1485
Location: Scotland
vbc wrote:
BigEd wrote:
Prompted by a nearby comment, here's a pointless mini-challenge: what kinds of useful interrupt handler can be written without using A, X, or Y and therefore without saving or restoring them?

Is it even the case that such a hampered ISR can perform an arbitrary function, by means of great cunning?

How about the following untested code:
Code:
stack: ; align to a page
 reserve 256
ival:
 inc stack
 rts
dval:
 dec stack
 rts
isp:
 inc ival+1
 inc dval+1
 rts
dsp:
 dec ival+1
 dec dval+1
 rts
checkzero:
 jsr ival
 jsr dval
 rts

Now brainfuck code can be translated as follows:
Code:
<: jsr dsp
>: jsr isp
+: jsr ival
-: jsr dval
[: <new-label>
]: jsr checkzero; bne <new-label>

Brainfuck is turing-complete (memory-limitations aside), so you should be able to compute arbitrary functions.


Excellent, however I believe your [] test is the wrong way round - it's a while !0 BF code, not BF code while !0, so

Code:
[: jsr checkzero; beq :+
]: (empty label, just a : in ca65)


That way the loop can be executed zero times and using [] is a common way to write a comment at the start of a BF program (not that I've written many!)

Now to write a BF to 6502 translator...

(Also note that there is a C to BF 'compiler' which should probably raise more questions that is answers...)

-Gordon

_________________
--
Gordon Henderson.
See my Ruby 6502 and 65816 SBC projects here: https://projects.drogon.net/ruby/


Top
 Profile  
Reply with quote  
PostPosted: Thu Aug 06, 2020 7:49 pm 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8539
Location: Southern California
I set up T1 (timer/counter 1) in a 65c22 VIA on my workbench computer which is on NMI to interrupt every 10ms (a centisecond, or cs for short) to keep time. I have a four-byte variable which gets updated this way:
Code:
INC10ms: BIT  VIA1T1CL  ; Clear the VIA1 T1 interrupt.)
         INC  cs32+2    ; Increment low byte.
         BNE  E2$       ; Branch if it did not roll over.
         INC  cs32+3    ; Increment 2nd-to lowest byte.
         BNE  E2$
         INC  cs32
         BNE  E2$
         INC  cs32+1    ; Increment high byte.
 E2$:    RTI

In actuality, there's more to the ISR, as it does go on to update another set of variables where I have the centiseconds carry at 100, the seconds and minutes carry at 60, the hours carry at 24, the month at whatever number of days is appropriate for the month, and it checks to see if the next alarm is due; but the above is enough for the microcontrollers I've put in our products. In fact, they usually only need two bytes, not four. As you can see, in 255 out of 256 times, the first branch will be taken to the RTI.

Many uses don't want or need to know how the count aligns with the time of day or date. For example, when you hold a key, there's a variable where you keep the number of cs you want it to wait before the repeating starts, and another for how many cs you want between repeats for the repeat speed. It has no concern at all for what time of day it is, only a relative number of cs.

The ISR only updates the record of time. Various routines, taking their turn at running, look at the clock and compare it to target times to see if it's time for them to do what they're supposed to do next, and unless it is, they immediately exit and let something else run. In most cases the first byte they compare will be different, so there's no need to look further, so they take very little processor time.

That said, for most other interrupts, I would still like for the interrupt sequence to stack the accumulator, and RTI to pull it back off. I realize the chip-design limitations though which led to the way it is done.

_________________
http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?


Top
 Profile  
Reply with quote  
PostPosted: Thu Aug 06, 2020 8:33 pm 
Offline

Joined: Thu Apr 23, 2020 5:04 pm
Posts: 51
drogon wrote:
Excellent, however I believe your [] test is the wrong way round - it's a while !0 BF code, not BF code while !0, so

Code:
[: jsr checkzero; beq :+
]: (empty label, just a : in ca65)


That way the loop can be executed zero times and using [] is a common way to write a comment at the start of a BF program (not that I've written many!)

Yes, you are right (and we need a jmp back for ]).


Top
 Profile  
Reply with quote  
PostPosted: Thu Aug 06, 2020 9:15 pm 
Offline

Joined: Sun Apr 26, 2020 3:08 am
Posts: 357
I would toggle the speaker approx every 64 secs. Although 60 vblints in a second, the counters go to 64.

inc vblintcounter
bit vblintcounter
bvs secondary
rti

secondary equ *
asl vblintcounter ; clear bit 6
inc secscounter
bit secscounter
bvs togglespeaker
rti

togglespeaker equ *
]lp bit speaker
dec secscounter
bne ]lp
rti


Top
 Profile  
Reply with quote  
PostPosted: Fri Aug 07, 2020 9:45 pm 
Offline
User avatar

Joined: Tue Oct 25, 2016 8:56 pm
Posts: 362
Since I inspired the challenge, I can't very well avoid participating can I?

My suggestion does require special hardware, but if you have a FastIO port then you can read and write to the FastIO port, branch based on those values and (using zero-page rotates) receive or transmit serial values, all without touching a register. See these macros.

_________________
Want to design a PCB for your project? I strongly recommend KiCad. Its free, its multiplatform, and its easy to learn!
Also, I maintain KiCad libraries of Retro Computing and Arduino components you might find useful.


Top
 Profile  
Reply with quote  
PostPosted: Mon Aug 10, 2020 7:53 pm 
Offline

Joined: Wed Jan 08, 2014 3:31 pm
Posts: 578
@vbc, that self modifying code to create a Brainf#%k VM is a classic.


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 12 posts ] 

All times are UTC


Who is online

Users browsing this forum: No registered users and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to: