Page 3 of 3
Re: JSR Indirect Address
Posted: Wed Aug 16, 2017 8:05 am
by BigEd
How much an ISR should do is of course application dependent. If the application is real time control, and if the response time is very tight relative to the clock speed, then every instruction is going to have to count. But this is not the only situation!
In Acorn's MOS, IRQ is relatively pedestrian - for good engineering reasons it indirects through RAM. On the other hand, NMI is absolutely minimal, because it is used solely for interacting with the floppy controller, which is very much a real time subsystem.
Re: JSR Indirect Address
Posted: Wed Aug 16, 2017 2:59 pm
by dwight
Rules are made to be broken. There is always the exception.
As for copying a frame buffer, this is where hardware should
replace program. A DMA transfer would have been the right
way, in general.
It sounds as though there wasn't much else to do anyway.
It is just that over the years I've seen cases where too much processing
was done in the interrupts.
I saw one that they read an A/D, offset the value ( dangerous to do without care )
and multiplied by a ratio. All in the interrupt.
If there are more than one critical operation to handle, one needs to look
carefully at how it will handle multiple events. This is hard to do while locked
in an interrupt.
Dwight
Re: JSR Indirect Address
Posted: Sat Dec 15, 2018 2:43 pm
by 8bit-Dude
Not sure if it is helpful, but to change JSR addresses I just edit the address bytes.
This is an example used to dynamically specify the JSR address of a SID file...
Code: Select all
playMusic:
; set address
sta initSID+1
stx initSID+2
initSID:
; init code (Dummy address)
jsr $0000
Re: JSR Indirect Address
Posted: Sat Dec 15, 2018 3:19 pm
by Chromatix
That's a valid technique if you can tolerate self-modifying code. It disqualifies that code from running from ROM. A more universal technique, which is one byte shorter but slightly slower:
Code: Select all
JSR indirectEntry
; Returns to here
[...]
indirectEntry:
PHX ; push subroutine address on stack
PHA
RTS ; indirect jump
Re: JSR Indirect Address
Posted: Sat Dec 15, 2018 3:25 pm
by BigEd
(Don't forget to adjust those addresses by 1!)
Re: JSR Indirect Address
Posted: Sat Dec 15, 2018 3:28 pm
by Chromatix
Or, having set up the address in RAM, just make indirectEntry be a simple JMP (target).
Re: JSR Indirect Address
Posted: Sat Dec 15, 2018 4:22 pm
by Dr Jefyll
(Don't forget to adjust those addresses by 1!)
Right.
Or, if you find adjusting the address to be inconvenient -- and you have a byte to spare -- use
PHP RTI to conclude the sequence (instead of
RTS).

Re: JSR Indirect Address
Posted: Sat Dec 15, 2018 4:24 pm
by BigEd
Oh, I like that!
Re: JSR Indirect Address
Posted: Sat Dec 15, 2018 4:51 pm
by Dr Jefyll
Happy to entertain you.

Here's a related trick which could in some cases be an attractive way of returning altered flags to a bios caller, without relying on stack gymnastics. In
this thread (whose context is 65816), ...
Let's say a bios routine needs to return a yes-no message, either "a" or "b," to the caller. For message "a" the routine exits using RTI, and a one-byte instruction located right after the BRK in the calling code will get executed. But for message "b" the bios routine would exit using PLP followed by RTL [RTS, for 6502], which results in the one-byte instruction following the BRK getting skipped. So, for example, by using CLC or SEC as the conditionally-executed instruction after the BRK you can cause the "message" to end up in the carry flag!

(Carry would have to be in a known state beforehand.)
Re: JSR Indirect Address
Posted: Sun Dec 23, 2018 6:43 pm
by kakemoms
Hmm. I have used this subroutine in the past to get indirect JSR:
Code: Select all
*=$2000
defm ijsr ; addr
jsr injsr
jmp (/1)
endm
injsr
pla
tax
pla
tay
txa
clc
adc #3 ; check overflow
tya
adc #0 ; add msb
pha
txa
adc #3 ; add lsb
pha ;jmp return address
tya
pha
txa
pha ;restore return address
rts
*=$2100
ijsr $2200
rts
*=$2200
byte 0,$30
*=$3000
lda #5 ; do something
rts ; return
Its slow, but the macro reuses the code, so it only requires 6 bytes per indirect JSR after the first one.
Re: JSR Indirect Address
Posted: Sun Dec 23, 2018 6:53 pm
by Chromatix
It looks like you're duplicating and modifying a copy of the return address on the stack, using NMOS instructions only (CMOS has direct PLX/Y). That *will* be slow, especially compared to the six bytes *total* required for a JSR to a simple indirect-jump trampoline.
Re: JSR Indirect Address
Posted: Mon Dec 24, 2018 3:36 am
by kakemoms
Yes I use a 6502, but it works on a 65C02 as well. Its fairly easy to get 65c02-only code:
Code: Select all
injsr
plx
ply
txa
clc
adc #3 ; check overflow
tya
adc #0 ; add msb
pha
txa
adc #3 ; add lsb
pha ;jmp return address
phy
phx ;restore return address
rts
Slightly faster...
If you simply want a fast method, just use the direct modification of the JSR instruction:
Code: Select all
defm ijsr ; addr
lda /1
sta @jta+1
lda /1+1
sta @jta+2
@jta jsr $ffff
endm