The byte after BRK is used as a signature byte, or data byte, by the BRK part of the interrupt-service routine, to know what it's supposed to do. The software to get it would have been easier though if it were BRK#$xx, with the operand getting loaded into a B register. Each BRK may be different. Whatever though. BRK apparently has uses in multitasking OSs, something the '02 is not very good at anyway; but I have not used BRK since that first 6502 class in 1982.
Extended 6502 Project (Logisim)
- GARTHWILSON
- Forum Moderator
- Posts: 8773
- Joined: 30 Aug 2002
- Location: Southern California
- Contact:
Re: Extended 6502 Project (Logisim)
Proxy wrote:
BigEd wrote:
I think this is the sense in which BRK is a two-byte instruction.
The byte after BRK is used as a signature byte, or data byte, by the BRK part of the interrupt-service routine, to know what it's supposed to do. The software to get it would have been easier though if it were BRK#$xx, with the operand getting loaded into a B register. Each BRK may be different. Whatever though. BRK apparently has uses in multitasking OSs, something the '02 is not very good at anyway; but I have not used BRK since that first 6502 class in 1982.
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: Extended 6502 Project (Logisim)
The BBC Micro uses it as an error reporting mechanism. The first byte after the BRK is a numeric error code, then the bytes following that are an error message, null-terminated. I think it's not supposed to allow resuming execution after the result - it just returns control to the current language.
Another use is as a software breakpoint mechanism. A hardware breakpoint mechanism would involve a comparator sitting on the address bus and triggering /NMI. BRK thus allows implementing a debugger without specialised hardware.
Another use is as a software breakpoint mechanism. A hardware breakpoint mechanism would involve a comparator sitting on the address bus and triggering /NMI. BRK thus allows implementing a debugger without specialised hardware.
- BigDumbDinosaur
- Posts: 9425
- Joined: 28 May 2009
- Location: Midwestern USA (JB Pritzker’s dystopia)
- Contact:
Re: Extended 6502 Project (Logisim)
GARTHWILSON wrote:
Proxy wrote:
BigEd wrote:
I think this is the sense in which BRK is a two-byte instruction.
The byte after BRK is used as a signature byte, or data byte...
Aside from that purpose, I and, I am sure, many others, use BRK to interrupt execution for debugging purposes.
x86? We ain't got no x86. We don't NEED no stinking x86!
- BigDumbDinosaur
- Posts: 9425
- Joined: 28 May 2009
- Location: Midwestern USA (JB Pritzker’s dystopia)
- Contact:
Re: Extended 6502 Project (Logisim)
Dr Jefyll wrote:
I agree that BRK's extra byte is a "feature" which no-one planned. 
Notably, COP in the 65C816 does the same thing. In the '816 data sheet, WDC expressly states that BRK and COP are two-byte instructions (section 7.22 on page 53).
BTW, I regret not hanging onto that old MOS Technology documentation. It would have made a great addition to the 6502.org library, as well as a sterling example of what happens when your copy is a copy of a copy of a copy of a...
x86? We ain't got no x86. We don't NEED no stinking x86!
Re: Extended 6502 Project (Logisim)
BigDumbDinosaur wrote:
Dr Jefyll wrote:
I agree that BRK's extra byte is a "feature" which no-one planned. 
I can't rule out the possibility they intended to do it that way right from the start. (And I'll happily concede the extra byte can end up being useful -- I never meant to imply otherwise.) But I think they would've gotten the extra byte whether they intended it or not because of the one-cycle decode delay I explained earlier.
As for vintage MOS doc, the MCS6500 Family Programming Manual (January 1976) lists BRK as a one-byte instruction (see pg B-8). That's not proof, but I suspect it does reveal their original intention.
ETA: looking for flaws in my own argument about the one-cycle decode delay, the 6502 does include a section known as Predecode Logic, and perhaps its responsibilities were originally supposed to include stopping the PC increment for BRK (thus suppressing the extra byte). From there we can further speculate that the increment suppression proved problematic and ultimately got dropped... despite being optimistically predicted in the MOS manual I just mentioned.
-- Jeff
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
Re: Extended 6502 Project (Logisim)
We can see in the implementation the decoding of three specific opcode byte patterns: one of these patterns, xxxx10x0, is used to create a signal called ONEBYTE. It's the ONEBYTE instructions which need special handling: although the following byte is necessarily always read (because in setting up that cycle the machine doesn't know what the opcode is) the PC should not be advanced a second time.
The operations RTS and RTI might seem to be exceptions, but as they will restore the PC it doesn't matter if it's incremented a second time. (And indeed it is.)
Similarly, BRK is not of the ONEBYTE pattern, so the PC is incremented a second time.
(As interrupt dispatch begins with the use of the ClearIR signal to put a zero in where the opcode would have landed, for many purposes it looks like a BRK. However, in this case the famous D1x1 signal is already in play to prevent the PC increment.)
So, the 6502's behaviour is natural and simple, as appropriate for an extreme cost-reduced processor. Later efforts were able to spend more transistors, decode more opcodes, and behave in more complex ways - but they didn't change BRK, for obvious reasons.
Given the way BRK works, if a BRK handler intends to return, it will be easiest to return as if BRK is a two byte instruction. And given that this is so, it's simplest to explain to the user that BRK is a two byte instruction. And it's not harmful for the customer to believe it. And it's then fruitful to think of how to use that unexpected operand. And that story can then be written into training materials and the operand can be called 'the signature byte'.
Which is to say, if you start from the documents, the story looks one way, but if you start from the implementation, the story looks different. I have no doubt the implementation came first, in this case.
Ref:
http://visual6502.org/wiki/index.php?ti ... PC_control
http://visual6502.org/wiki/index.php?ti ... ing_States
http://visual6502.org/wiki/index.php?ti ... te_Machine
http://nparker.llx.com/a2/opcodes.html
Without revisiting the implementation, my recollection is that one-byte opcodes have to be handled specially, because the PC must not be incremented in the second cycle - and yet that's the earliest the machine can know what the opcode is. An interrupt is taken by forcing the incoming opcode byte to a zero.
The operations RTS and RTI might seem to be exceptions, but as they will restore the PC it doesn't matter if it's incremented a second time. (And indeed it is.)
Similarly, BRK is not of the ONEBYTE pattern, so the PC is incremented a second time.
(As interrupt dispatch begins with the use of the ClearIR signal to put a zero in where the opcode would have landed, for many purposes it looks like a BRK. However, in this case the famous D1x1 signal is already in play to prevent the PC increment.)
So, the 6502's behaviour is natural and simple, as appropriate for an extreme cost-reduced processor. Later efforts were able to spend more transistors, decode more opcodes, and behave in more complex ways - but they didn't change BRK, for obvious reasons.
Given the way BRK works, if a BRK handler intends to return, it will be easiest to return as if BRK is a two byte instruction. And given that this is so, it's simplest to explain to the user that BRK is a two byte instruction. And it's not harmful for the customer to believe it. And it's then fruitful to think of how to use that unexpected operand. And that story can then be written into training materials and the operand can be called 'the signature byte'.
Which is to say, if you start from the documents, the story looks one way, but if you start from the implementation, the story looks different. I have no doubt the implementation came first, in this case.
Ref:
http://visual6502.org/wiki/index.php?ti ... PC_control
http://visual6502.org/wiki/index.php?ti ... ing_States
http://visual6502.org/wiki/index.php?ti ... te_Machine
http://nparker.llx.com/a2/opcodes.html
Without revisiting the implementation, my recollection is that one-byte opcodes have to be handled specially, because the PC must not be incremented in the second cycle - and yet that's the earliest the machine can know what the opcode is. An interrupt is taken by forcing the incoming opcode byte to a zero.
Re: Extended 6502 Project (Logisim)
ok quick question, I'm currently doing the BBR/BBS instructions and i'm not sure where the offset starts.
is it like the other branch instructions in the sense that the offset is calculated from the Opcode of the next instruction?
or is it exactly like the other branches and the offset is calcuated 2 bytes after the Opcode of the branch?
both of those are completely different and i don't know which is right... i can't find it in the datasheet either.
I currently just made the offset start from the Opcode of the next instruction.
and lastly, what exactly does the Memory Lock (MLB) pin do exactly? the datasheet isn't really helpful because:
1. i don't know what "defer arbitration" is supposed to mean
2. my cycle counts are different so "last 3 cycles" is not very helpful in this case
is it like the other branch instructions in the sense that the offset is calculated from the Opcode of the next instruction?
or is it exactly like the other branches and the offset is calcuated 2 bytes after the Opcode of the branch?
both of those are completely different and i don't know which is right... i can't find it in the datasheet either.
I currently just made the offset start from the Opcode of the next instruction.
and lastly, what exactly does the Memory Lock (MLB) pin do exactly? the datasheet isn't really helpful because:
1. i don't know what "defer arbitration" is supposed to mean
2. my cycle counts are different so "last 3 cycles" is not very helpful in this case
Re: Extended 6502 Project (Logisim)
"The Memory Lock (MLB) output may be used to ensure the integrity of Read-Modify-Write instructions in a multiprocessor system. Memory Lock indicates the need to defer arbitration of the bus cycle when MLB is low. Memory Lock is low during the last three cycles of ASL, DEC, INC, LSR, ROL, ROR, TRB, and TSB memory referencing instructions."
So, if there's a read-modify-write, you need MLB true for the read, for the write, and for any cycles in between.
So, if there's a read-modify-write, you need MLB true for the read, for the write, and for any cycles in between.
Re: Extended 6502 Project (Logisim)
BigEd wrote:
"The Memory Lock (MLB) output may be used to ensure the integrity of Read-Modify-Write instructions in a multiprocessor system. Memory Lock indicates the need to defer arbitration of the bus cycle when MLB is low. Memory Lock is low during the last three cycles of ASL, DEC, INC, LSR, ROL, ROR, TRB, and TSB memory referencing instructions."
So, if there's a read-modify-write, you need MLB true for the read, for the write, and for any cycles in between.
So, if there's a read-modify-write, you need MLB true for the read, for the write, and for any cycles in between.
what about the BBR/BBS offset thing?
Re: Extended 6502 Project (Logisim)
I don't know. I'd guess the offset has the same relationship to the following opcode as is normally the case, because PC will need to have been incremented to pick up the operands, so that's where it would end up.
This link looks like confirmation:
https://github.com/Trinity-11/Kernel/bl ... ADME#L2419
This link looks like confirmation:
https://github.com/Trinity-11/Kernel/bl ... ADME#L2419
- GARTHWILSON
- Forum Moderator
- Posts: 8773
- Joined: 30 Aug 2002
- Location: Southern California
- Contact:
Re: Extended 6502 Project (Logisim)
I see Ed just posted, but I'll finish this anyway.
I checked the Lichty & Eyes programming manual (which every 65xx enthusiast should have), and even that one doesn't say. I think it would be pretty safe to assume it's like the other branch instructions, where the op code of the next instruction is at offset 00. If you want to be even safer, you could just try it on an available assembler and examine the output to see what it does. Just branch to the very next instruction (meaning the BBR/BBS does nothing but take time), and see if the branch distance says 00.
Proxy wrote:
what about the BBR/BBS offset thing?
I checked the Lichty & Eyes programming manual (which every 65xx enthusiast should have), and even that one doesn't say. I think it would be pretty safe to assume it's like the other branch instructions, where the op code of the next instruction is at offset 00. If you want to be even safer, you could just try it on an available assembler and examine the output to see what it does. Just branch to the very next instruction (meaning the BBR/BBS does nothing but take time), and see if the branch distance says 00.
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?
- BigDumbDinosaur
- Posts: 9425
- Joined: 28 May 2009
- Location: Midwestern USA (JB Pritzker’s dystopia)
- Contact:
Re: Extended 6502 Project (Logisim)
Proxy wrote:
ok quick question, I'm currently doing the BBR/BBS instructions and i'm not sure where the offset starts.
Code: Select all
bne somewhere
lda somethingx86? We ain't got no x86. We don't NEED no stinking x86!
Re: Extended 6502 Project (Logisim)
The following passes Klaus' extended tests:
Code: Select all
uint16_t zp() { return read(PC++); }
uint16_t rel() { int8_t off = read(PC++); carryCycle(PC+off,PC); return PC + off; }
// Extended 65c02 branches, fixed cycle count
void branchBit(uint16_t ea1, uint16_t ea2, uint8_t mask, bool set) {
uint8_t B = read(ea1);
bool d = !(B & mask);
if(d ^ set)
PC = ea2;
}
void bbr0(uint16_t ea) { branchBit(ea, rel(), 1<<0, 0); }
// effectively called as:
if(read(PC++) == OP_BBR0)
bbr0(zp());
Re: Extended 6502 Project (Logisim)
thanks for the help, the BBR and BBS are exactly 1 cycle longer as their regular branch cousins. (3 when not taken, and 4 when taken)
i have to redo some parts of the Read Modify Write Instructions to have the MLB pin working.
strangely the datasheet only mentions ASL, DEC, INC, LSR, ROL, ROR, TRB, and TSB for that pin...
but aren't SMB and RMB also Read Modify Write? since they read a byte, modify it, and write it back.
i have to redo some parts of the Read Modify Write Instructions to have the MLB pin working.
strangely the datasheet only mentions ASL, DEC, INC, LSR, ROL, ROR, TRB, and TSB for that pin...
but aren't SMB and RMB also Read Modify Write? since they read a byte, modify it, and write it back.
Re: Extended 6502 Project (Logisim)
It would certainly make sense to do so. The intent is to prevent a DMA or other-CPU access from intervening in the supposedly atomic RMW operation.
Most 6502 systems, in practice, ignore the MLB signal.
Most 6502 systems, in practice, ignore the MLB signal.