JSR Indirect Address
- BitWise
- In Memoriam
- Posts: 996
- Joined: 02 Mar 2004
- Location: Berkshire, UK
- Contact:
Re: JSR Indirect Address
BigDumbDinosaur wrote:
Alarm Siren wrote:
BigDumbDinosaur wrote:
As a rule, I never use subroutine calls in an ISR.
Andrew Jacobs
6502 & PIC Stuff - http://www.obelisk.me.uk/
Cross-Platform 6502/65C02/65816 Macro Assembler - http://www.obelisk.me.uk/dev65/
Open Source Projects - https://github.com/andrew-jacobs
6502 & PIC Stuff - http://www.obelisk.me.uk/
Cross-Platform 6502/65C02/65816 Macro Assembler - http://www.obelisk.me.uk/dev65/
Open Source Projects - https://github.com/andrew-jacobs
- BigDumbDinosaur
- Posts: 9428
- Joined: 28 May 2009
- Location: Midwestern USA (JB Pritzker’s dystopia)
- Contact:
Re: JSR Indirect Address
BitWise wrote:
If the extra cycles screws up your code then either lower the communications speed, add flow control, add buffers or increase the CPU frequency.
x86? We ain't got no x86. We don't NEED no stinking x86!
- Alarm Siren
- Posts: 363
- Joined: 25 Oct 2016
Re: JSR Indirect Address
Dr Jefyll wrote:
floobydust wrote:
It would be interesting to figure what it is.
Using a hex editor one could open the assembler executable and search for the text strings BBS0 (...) BBS7. Then have a look at the surrounding bytes, and see what pattern exists. Presumably all eight BBS instances will have accompanying bytes which are identical; also one which varies according to the associated opcode.
The smoking gun is if you find a byte(s) which is identical for only seven out of eight BBS instances. Presumably that encodes the permissible address modes, and for whatever reason it's corrupted in the BBS0 case. Change it to match the others, and see what happens!
Not everyone will consider this fun or worthwhile, and I'm half joking after all. But floating prospective solutions exercises creativity. A challenge like this is catnip for me!
Edited to add:
- >for whatever reason it's corrupted in the BBS0 case
Hmm, the corruption could be a typo or copy-paste error in the source code for the assembler, but it could also happen later when the code actually loads into RAM and runs. If it's the latter then I'm SOL.
The string "bbs0" only appears once in the entire exectuable, within a data structure that appears to be a table of recognised instructions.
The BBSx part of said datastructure:
Code: Select all
bbs0<NUL>.<NUL><NUL><NUL><NUL><SOH>Ÿ
bbs1<NUL>/<NUL><NUL><NUL><NUL><SOH>¯
bbs2<NUL>0<NUL><NUL><NUL><NUL><SOH>¿
bbs3<NUL>1<NUL><NUL><NUL><NUL><SOH>Ï
bbs4<NUL>2<NUL><NUL><NUL><NUL><SOH>ß
bbs5<NUL>3<NUL><NUL><NUL><NUL><SOH>ï
bbs6<NUL>4<NUL><NUL><NUL><NUL><SOH>ÿ
bbs7‡<NUL><NUL><NUL><NUL><BEL><LF>Unfortunately I don't believe there's any smoking gun here.
BitWise wrote:
If the addresses you are testing are relative then you will need to prefix them with a '<' for force the assembler to see them as page zero (although in this case they must always be)
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.
Also, I maintain KiCad libraries of Retro Computing and Arduino components you might find useful.
Re: JSR Indirect Address
Alarm Siren wrote:
The BBSx part of said datastructure:
(new lines added by me for clarity).
Code: Select all
bbs0<NUL>.<NUL><NUL><NUL><NUL><SOH>Ÿ <-- $9F
bbs1<NUL>/<NUL><NUL><NUL><NUL><SOH>¯ <-- $AF
bbs2<NUL>0<NUL><NUL><NUL><NUL><SOH>¿ <-- $BF
bbs3<NUL>1<NUL><NUL><NUL><NUL><SOH>Ï <-- $CF
bbs4<NUL>2<NUL><NUL><NUL><NUL><SOH>ß <-- $DF
bbs5<NUL>3<NUL><NUL><NUL><NUL><SOH>ï <-- $EF
bbs6<NUL>4<NUL><NUL><NUL><NUL><SOH>ÿ <-- $FF
bbs7‡<NUL><NUL><NUL><NUL><BEL><LF>The bytes you listed do roughly match what I vaguely imagined -- an array of data structures. I see each instance has twelve bytes (including four bytes for the mnemonic). And indeed the opcodes are in there, too, as predicted! For example, what prints as the character ÿ is really $FF (as per the notations I added above), and $FF is the opcode for BBS7. Likewise ï is $EF which is BBS6, ß is $DF which is BBS5, and so on...
... all except $8F aka BBS0 which is missing. I think there's a framing error in the way you've added the new-lines. Unexpectedly, the four bytes for the mnemonic appear at the end of each structure, not the beginning. For example I mentioned ÿ is $FF, which is the opcode for BBS7, and see how ÿ precedes the mnemonic bbs7? I'm afraid that at the end you listed some bytes which aren't part of the array, and at the beginning you omitted eight bytes which are.
It's easy to work backwards and predict what "should" be there. If the hex bytes 00, 2D, 00, 00, 00, 00, 01, 8F are prepended to your listing then the resulting pattern is consistent across all eight 12-byte structures. My goal was to see if that consistency is intact. But the anomaly, if any, would appear in the portion you accidentally omitted, so now I'm in suspense!
-- Jeff
PS and slightly OT -- or maybe not:
while preparing this post I noticed I could copy and paste most of the unusual characters (the ¿ and the Ÿ and so on) without difficulty, but I wasn't able to copy and paste the character encoded by $8F (which is the opcode for our problematic BBR0). Probably there's a simple reason, although it's not known to me (7-bit ASCII is the only encoding I have a solid grasp on). But perhaps $8F's lack of pastability, or a closely related issue, has a bearing on the puzzle at hand. It may only be coincidence. But $8F stands out as a case of "one of these things is not like the others" -- and that aptly describes the BBS0 puzzle as well.
In 1988 my 65C02 got six new registers and 44 new full-speed instructions!
https://laughtonelectronics.com/Arcana/ ... mmary.html
https://laughtonelectronics.com/Arcana/ ... mmary.html
- Alarm Siren
- Posts: 363
- Joined: 25 Oct 2016
Re: JSR Indirect Address
Dr Jefyll wrote:
Alarm Siren wrote:
The BBSx part of said datastructure:
(new lines added by me for clarity).
Code: Select all
bbs0<NUL>.<NUL><NUL><NUL><NUL><SOH>Ÿ <-- $9F
bbs1<NUL>/<NUL><NUL><NUL><NUL><SOH>¯ <-- $AF
bbs2<NUL>0<NUL><NUL><NUL><NUL><SOH>¿ <-- $BF
bbs3<NUL>1<NUL><NUL><NUL><NUL><SOH>Ï <-- $CF
bbs4<NUL>2<NUL><NUL><NUL><NUL><SOH>ß <-- $DF
bbs5<NUL>3<NUL><NUL><NUL><NUL><SOH>ï <-- $EF
bbs6<NUL>4<NUL><NUL><NUL><NUL><SOH>ÿ <-- $FF
bbs7‡<NUL><NUL><NUL><NUL><BEL><LF>Quote:
The bytes you listed do roughly match what I vaguely imagined -- an array of data structures. I see each instance has twelve bytes (including four bytes for the mnemonic). And indeed the opcodes are in there, too, as predicted! For example, what prints as the character ÿ is really $FF (as per the notations I added above), and $FF is the opcode for BBS7. Likewise ï is $EF which is BBS6, ß is $DF which is BBS5, and so on...
... all except $8F aka BBS0 which is missing. I think there's a framing error in the way you've added the new-lines. Unexpectedly, the four bytes for the mnemonic appear at the end of each structure, not the beginning. For example I mentioned ÿ is $FF, which is the opcode for BBS7, and see how ÿ precedes the mnemonic bbs7? I'm afraid that at the end you listed some bytes which aren't part of the array, and at the beginning you omitted eight bytes which are.
It's easy to work backwards and predict what "should" be there. If the hex bytes 00, 2D, 00, 00, 00, 00, 01, 8F are prepended to your listing then the resulting pattern is consistent across all eight 12-byte structures. My goal was to see if that consistency is intact. But the anomaly, if any, would appear in the portion you accidentally omitted, so now I'm in suspense!
Would you mind checking, please, to see if the pattern is intact?
-- Jeff
PS and slightly OT -- or maybe not:
while preparing this post I noticed I could copy and paste most of the unusual characters (the ¿ and the Ÿ and so on) without difficulty, but I wasn't able to copy and paste the character encoded by $8F (which is the opcode for our problematic BBR0). Probably there's a simple reason, although it's not known to me (7-bit ASCII is the only encoding I have a solid grasp on). But perhaps $8F's lack of pastability, or a closely related issue, has a bearing on the puzzle at hand. It may only be coincidence. But $8F stands out as a case of "one of these things is not like the others" -- and that aptly describes the BBS0 puzzle as well.
... all except $8F aka BBS0 which is missing. I think there's a framing error in the way you've added the new-lines. Unexpectedly, the four bytes for the mnemonic appear at the end of each structure, not the beginning. For example I mentioned ÿ is $FF, which is the opcode for BBS7, and see how ÿ precedes the mnemonic bbs7? I'm afraid that at the end you listed some bytes which aren't part of the array, and at the beginning you omitted eight bytes which are.
It's easy to work backwards and predict what "should" be there. If the hex bytes 00, 2D, 00, 00, 00, 00, 01, 8F are prepended to your listing then the resulting pattern is consistent across all eight 12-byte structures. My goal was to see if that consistency is intact. But the anomaly, if any, would appear in the portion you accidentally omitted, so now I'm in suspense!
-- Jeff
PS and slightly OT -- or maybe not:
while preparing this post I noticed I could copy and paste most of the unusual characters (the ¿ and the Ÿ and so on) without difficulty, but I wasn't able to copy and paste the character encoded by $8F (which is the opcode for our problematic BBR0). Probably there's a simple reason, although it's not known to me (7-bit ASCII is the only encoding I have a solid grasp on). But perhaps $8F's lack of pastability, or a closely related issue, has a bearing on the puzzle at hand. It may only be coincidence. But $8F stands out as a case of "one of these things is not like the others" -- and that aptly describes the BBS0 puzzle as well.
Code: Select all
bbr7<NUL>-<NUL><NUL><NUL><NUL><SOH>EDIT: changed my text editor's charset to ISO-8859-15 and, yep, <SS3> right where it should be.
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.
Also, I maintain KiCad libraries of Retro Computing and Arduino components you might find useful.
Re: JSR Indirect Address
Alarm Siren wrote:
<SS3> right where it should be.
If you discover it also eliminates the BBS0 error message which you were getting then we have a red-hot clue.
Edit: typo - BBS0 not BBR0
Last edited by Dr Jefyll on Fri Jun 02, 2017 7:58 pm, edited 1 time in total.
In 1988 my 65C02 got six new registers and 44 new full-speed instructions!
https://laughtonelectronics.com/Arcana/ ... mmary.html
https://laughtonelectronics.com/Arcana/ ... mmary.html
- BigDumbDinosaur
- Posts: 9428
- Joined: 28 May 2009
- Location: Midwestern USA (JB Pritzker’s dystopia)
- Contact:
Re: JSR Indirect Address
A little historical aside for the truly OCD in the audience.
The syntax for the BBx instructions has been implemented in several different ways, depending on the assembler. For example, using the BBS instruction, one could write:
or could write:
or perhaps:
Of the above, the first form is the implied syntax in the WDC 65C02 data sheet. I say "implied" because while the data sheet lists all the instruction mnemonics (listing BBS as BBS0, BBS1, BBS2, etc.) and available addressing modes, it doesn't actually describe the recommended 65C02 assembly language syntax.
The WDC syntax is not in agreement with that documented in chapter 17 of the Lance A. Leventhal book 6502 Assembly Language Programming (1986, revised from the 1979 edition), which is considered to be the standard reference work on the eight bit 6502 family. Leventhal got his 65C02 material from Leo Scanlon at Rockwell International, so I'm inclined to think that the second form is the "official" form, as it was Rockwell who added the BBx, RMB, SMB, TRB and TSB instructions to the 65C02.¹
The third form is the one that is accepted by the Kowalski assembler as valid syntax. In a way, it makes sense, since the bit number (2) is immediate data, not an address.
From the point of view of someone writing a 65C02 assembler, the second and third forms would be more inviting, since the three-character mnemonic size is unchanged, and parsing comma-separated operands is relatively easy to accomplish. Also, these forms are easy for the programmer to read. The first form, I would think, would complicate mnemonic parsing, since the three-character uniformity is not maintained. Although I have no plans to write a 65C02 assembler, if I did I'd go with the Kowalski form due to its readability in a program listing.
——————————————————————————————————————————
¹Rockwell used the 65C02 in a modem they developed, which is the likely reason they added BBx et al to the instruction set.
The syntax for the BBx instructions has been implemented in several different ways, depending on the assembler. For example, using the BBS instruction, one could write:
Code: Select all
BBS2 $80,$A604Code: Select all
BBS 2,$80,$A604Code: Select all
BBS #2,$80,$A604The WDC syntax is not in agreement with that documented in chapter 17 of the Lance A. Leventhal book 6502 Assembly Language Programming (1986, revised from the 1979 edition), which is considered to be the standard reference work on the eight bit 6502 family. Leventhal got his 65C02 material from Leo Scanlon at Rockwell International, so I'm inclined to think that the second form is the "official" form, as it was Rockwell who added the BBx, RMB, SMB, TRB and TSB instructions to the 65C02.¹
The third form is the one that is accepted by the Kowalski assembler as valid syntax. In a way, it makes sense, since the bit number (2) is immediate data, not an address.
From the point of view of someone writing a 65C02 assembler, the second and third forms would be more inviting, since the three-character mnemonic size is unchanged, and parsing comma-separated operands is relatively easy to accomplish. Also, these forms are easy for the programmer to read. The first form, I would think, would complicate mnemonic parsing, since the three-character uniformity is not maintained. Although I have no plans to write a 65C02 assembler, if I did I'd go with the Kowalski form due to its readability in a program listing.
——————————————————————————————————————————
¹Rockwell used the 65C02 in a modem they developed, which is the likely reason they added BBx et al to the instruction set.
x86? We ain't got no x86. We don't NEED no stinking x86!
- Alarm Siren
- Posts: 363
- Joined: 25 Oct 2016
Re: JSR Indirect Address
So, I've written some simple macros for the WDC compiler which allow you to use the second (Rockwell) syntax, and which also get around the BBS0 bug we've encountered by prefixing the address with < to force it to treat it as ZP.
Note that you must call them as "BBSx" rather than "BBS", etc. I did this because "RMB" clashes with a built-in macro.
I've not yet done the most recently suggested experiment in editing the executable, though I do intend to do so soon.
Code: Select all
BBRx MACRO mBit, mZP, mBranchTarget
BBR@<mBit> <mZP, mBranchTarget
ENDM
BBSx MACRO mBit, mZP, mBranchTarget
BBS@<mBit> <mZP, mBranchTarget
ENDM
SMBx MACRO mBit, mZP
SMB@<mBit> <mZP
ENDM
RMBx MACRO mBit, mZP
RMB@<mBit> <mZP
ENDMI've not yet done the most recently suggested experiment in editing the executable, though I do intend to do so soon.
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.
Also, I maintain KiCad libraries of Retro Computing and Arduino components you might find useful.
- Alarm Siren
- Posts: 363
- Joined: 25 Oct 2016
Re: JSR Indirect Address
Remember that BBS0 bug? Well, I just went back to do some more experimentation on it, and it seems to have fixed itself. I can no longer replicate the bug, even on the original codebase where the problem was. I am very confused.
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.
Also, I maintain KiCad libraries of Retro Computing and Arduino components you might find useful.
Re: JSR Indirect Address
Hi
I was looking at this thread, looking for something else.
ISRs should be as short a possible in time, even if it takes more
space. In general, they should do the absolute minimum of calculation.
Like reading or writing a byte from/to a port:
Get the byte
update the pointer
possible overflow flag
done
Any other calculation or action with the byte do not belong in
an ISR. There is clearly no need for a JSR.
At most, there might be a test at the beginning to look for possible
multiple sources of the interrupt.
There should never be something, like converting an ascii letter to a
number in an ISR.
Dwight
I was looking at this thread, looking for something else.
ISRs should be as short a possible in time, even if it takes more
space. In general, they should do the absolute minimum of calculation.
Like reading or writing a byte from/to a port:
Get the byte
update the pointer
possible overflow flag
done
Any other calculation or action with the byte do not belong in
an ISR. There is clearly no need for a JSR.
At most, there might be a test at the beginning to look for possible
multiple sources of the interrupt.
There should never be something, like converting an ascii letter to a
number in an ISR.
Dwight
- GARTHWILSON
- Forum Moderator
- Posts: 8775
- Joined: 30 Aug 2002
- Location: Southern California
- Contact:
Re: JSR Indirect Address
dwight wrote:
ISRs should be as short a possible in time, even if it takes more
space. In general, they should do the absolute minimum of calculation.
Like reading or writing a byte from/to a port:
Get the byte
update the pointer
possible overflow flag
done
space. In general, they should do the absolute minimum of calculation.
Like reading or writing a byte from/to a port:
Get the byte
update the pointer
possible overflow flag
done
Quote:
At most, there might be a test at the beginning to look for possible multiple sources of the interrupt.
Quote:
There should never be something, like converting an ascii letter to a number in an ISR.
GARTHWILSON wrote:
Alarm Siren wrote:
GARTHWILSON wrote:
If it's only in one place, and in RAM, it would work well to use self-modifying code, where the variable holding the address to JSR to is the JSR instruction's own operand. That eliminates the need for variable space elsewhere too, including in precious ZP space.
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?
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?
Re: JSR Indirect Address
It is quite possible that you might have such a real time
system. If it was that critical, you should have used more than
one controller.
Using that much time in an interrupt is most likely poor initial design.
Dwight
system. If it was that critical, you should have used more than
one controller.
Using that much time in an interrupt is most likely poor initial design.
Dwight
- GARTHWILSON
- Forum Moderator
- Posts: 8775
- Joined: 30 Aug 2002
- Location: Southern California
- Contact:
Re: JSR Indirect Address
dwight wrote:
It is quite possible that you might have such a real time system. If it was that critical, you should have used more than one controller.
Quote:
Using that much time in an interrupt is most likely poor initial design.
It worked quite well, although the client kept changing his mind and I eventually had to tell him that I'm not going to try to shoot a moving target anymore. I told him, "We're going to do it this way for a first model, and we can add the new features to the next model." It ended up that I used all the main microcontroller's program memory (there were about five program words left), all the RAM, every I/O module, every timer, every pin, maximum clock speed, and I was overflowing the stack until I made changes to avoid that problem). If I ever take on a project like that again, I will need to move up to a more powerful microcontroller family.
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?
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?
Re: JSR Indirect Address
The most I ever did was to run 50 temperature PIDs and a control from a
keypad and LCD display.
It was for a 15 watt laser diode burn-in. Each diode had its own current
ramp and I'd correct the PID for the increased power as they heated up.
Lasers are funny, you have to limit the current when cold or they
wipe them selves out. As they heat up, you can increase the current
and it doesn't hurt them.
I was told that the efficiency drops of with temperature and they don't
lase as much.
Anyway, it was all run from a 2MHz Z80. It held the heat chucks to 0.2C.
It was a little tricky because you had to compensate for the additional
power of the diodes, either ramping up or down. I'd control the heat by
how many cycles of 60Hz I'd let into the heater. This would dither at each
step because the 60Hz steps were too course. You drop or add a cycle so
the average resolution was 1/10th of a cycle. The thermal inertia was enough
to average over the number of dithered cycles.
We used 1K RTDs rather than thermal couples. Thermal couples can't really be
calibrated because you can't recreate the thermal gradient on the wires
leading up to the heat chucks when they are removed from the heat chuck.
Platinum RTDs of the higher resistance are easier and they can be linearized
easier than thermal couples as well.
Dwight
keypad and LCD display.
It was for a 15 watt laser diode burn-in. Each diode had its own current
ramp and I'd correct the PID for the increased power as they heated up.
Lasers are funny, you have to limit the current when cold or they
wipe them selves out. As they heat up, you can increase the current
and it doesn't hurt them.
I was told that the efficiency drops of with temperature and they don't
lase as much.
Anyway, it was all run from a 2MHz Z80. It held the heat chucks to 0.2C.
It was a little tricky because you had to compensate for the additional
power of the diodes, either ramping up or down. I'd control the heat by
how many cycles of 60Hz I'd let into the heater. This would dither at each
step because the 60Hz steps were too course. You drop or add a cycle so
the average resolution was 1/10th of a cycle. The thermal inertia was enough
to average over the number of dithered cycles.
We used 1K RTDs rather than thermal couples. Thermal couples can't really be
calibrated because you can't recreate the thermal gradient on the wires
leading up to the heat chucks when they are removed from the heat chuck.
Platinum RTDs of the higher resistance are easier and they can be linearized
easier than thermal couples as well.
Dwight
- Alarm Siren
- Posts: 363
- Joined: 25 Oct 2016
Re: JSR Indirect Address
dwight wrote:
Hi
I was looking at this thread, looking for something else.
ISRs should be as short a possible in time, even if it takes more
space. In general, they should do the absolute minimum of calculation.
Like reading or writing a byte from/to a port:
Get the byte
update the pointer
possible overflow flag
done
Any other calculation or action with the byte do not belong in
an ISR. There is clearly no need for a JSR.
At most, there might be a test at the beginning to look for possible
multiple sources of the interrupt.
There should never be something, like converting an ascii letter to a
number in an ISR.
Dwight
I was looking at this thread, looking for something else.
ISRs should be as short a possible in time, even if it takes more
space. In general, they should do the absolute minimum of calculation.
Like reading or writing a byte from/to a port:
Get the byte
update the pointer
possible overflow flag
done
Any other calculation or action with the byte do not belong in
an ISR. There is clearly no need for a JSR.
At most, there might be a test at the beginning to look for possible
multiple sources of the interrupt.
There should never be something, like converting an ascii letter to a
number in an ISR.
Dwight
As a general case you're 100% right and I totally agree, however in my original application there was virtually nothing for the program to do outside the ISR (the non-ISR code was just a three instruction flip-a-bit-and-loop) so it really didn't matter that I was doing all the work in the ISR.
For the Nimbot I am definitely going to be optimizing the ISRs hard, but at least one type of them is going to take a long time by definition as it is copying the frame buffer into the screen. To save cycles I've put one type of ISR on to the NMI pin instead; I don't envisage needing to disable this one but if I need to it can be disabled in the VIA so it being on the NMI pin isn't too much of a problem, and I save some cycles checking the source. I've also long since concluded that BRK on a 65C02 is far too much hassle to be worthwhile - I was trying to emulate the x86 INT <vector> syntax, and whilst you can do this, the amount of cycles required to decode work out if its a BRK and get the <vector> if it is just isn't worth it. BRK/COP are much more practical in the '816.
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.
Also, I maintain KiCad libraries of Retro Computing and Arduino components you might find useful.