- at initial breakpoint address, steal the existing instruction and tuck it away somewhere safe
- replace the instruction first byte with a BRK
- wait for the BRK to trigger the interrupt
- ...
- in the interrupt, having checked the B flag, do the register view or whatever you need to see the status. Probably await some user instruction to do the single step (or escape)
- look at the stack to see where we came from
- subtract two to point (the return is always two past the interrupt, right?) back to the original instruction address and put that back on the stack
- replace the original instruction
- calculate the length of the original instruction
- using that value, grab the next instruction, store that, and replace it with a BRK
- rti to execute the current instruction
- repeat until bored
Did I miss anything? The processor status is pushed, I think, on a BRK so I need to check the order of the stack, but other than that I think I have everything.
Neil
Single step (ram) with BRK
Single step (ram) with BRK
I'm currently thinking this through, but do I have the right sequence of steps here?
Re: Single step (ram) with BRK
barnacle wrote:
Did I miss anything? The processor status is pushed, I think, on a BRK so I need to check the order of the stack, but other than that I think I have everything.
Dave
Re: Single step (ram) with BRK
Ack, yes. Thank you; they'll need some consideration.
The 'calculate the length of the instruction' bit to calculate the next BRK becomes 'calculate the address of the next instruction to execute'.
Neil
The 'calculate the length of the instruction' bit to calculate the next BRK becomes 'calculate the address of the next instruction to execute'.
Neil
Re: Single step (ram) with BRK
barnacle wrote:
The 'calculate the length of the instruction' bit to calculate the next BRK becomes 'calculate the address of the next instruction to execute'.
Dave
Re: Single step (ram) with BRK
Though perhaps simplified as I'm looking at an 'all RAM' system. Otherwise, one might have to trace through ROM until you hit something in RAM again. A naive approach might be to execute a call to ROM - the next BRK is where the call returns to - but that doesn't resolve the JMP issue (direct or indirect).
More thinking...
Neil
More thinking...
Neil
-
teamtempest
- Posts: 443
- Joined: 08 Nov 2009
- Location: Minnesota
- Contact:
Re: Single step (ram) with BRK
Don't let the perfect get in the way of the good. If you can get something useful working now, you can worry about extending it later.
- barrym95838
- Posts: 2056
- Joined: 30 Jun 2013
- Location: Sacramento, CA, USA
Re: Single step (ram) with BRK
I'm a fan of studying prior art for my own use. The pertinent section starts around address $FA43 and continues for 200 bytes or so.
Got a kilobyte lying fallow in your 65xx's memory map? Sprinkle some VTL02C on it and see how it grows on you!
Mike B. (about me) (learning how to github)
Mike B. (about me) (learning how to github)
-
kernelthread
- Posts: 166
- Joined: 23 Jun 2021
Re: Single step (ram) with BRK
barnacle wrote:
Though perhaps simplified as I'm looking at an 'all RAM' system. Otherwise, one might have to trace through ROM until you hit something in RAM again. A naive approach might be to execute a call to ROM - the next BRK is where the call returns to - but that doesn't resolve the JMP issue (direct or indirect).
More thinking...
Neil
More thinking...
Neil
Re: Single step (ram) with BRK
I think it might be nice to work on the 'step into' 'step over' approach; one tries to follow the program flow and one waits until the return with the other. As it's a manual operation, it might be thought that the user will know when he's trying to go out of userland and into possible rom, but it might be nice to check, or blacklist certain addresses.
Ah, but where's the fun in that?
I need to sort out the disassembler first (which coincidentally has a routine which calculates the instruction length) but for some reason at the moment my multiply by seven routine to index into a table has decided to multiply by seven and a half.
Neil
barrym95838 wrote:
I'm a fan of studying prior art for my own use. The pertinent section starts around address $FA43 and continues for 200 bytes or so.
I need to sort out the disassembler first (which coincidentally has a routine which calculates the instruction length) but for some reason at the moment my multiply by seven routine to index into a table has decided to multiply by seven and a half.
Neil
- barrym95838
- Posts: 2056
- Joined: 30 Jun 2013
- Location: Sacramento, CA, USA
Re: Single step (ram) with BRK
Split your table into seven pieces ... problem solved! 
Regarding "fun" factor, Woz authored some fascinating balls of twine during the late 1970s, and I love trying to pick them apart to see if some of the magic is still available.
Regarding "fun" factor, Woz authored some fascinating balls of twine during the late 1970s, and I love trying to pick them apart to see if some of the magic is still available.
Got a kilobyte lying fallow in your 65xx's memory map? Sprinkle some VTL02C on it and see how it grows on you!
Mike B. (about me) (learning how to github)
Mike B. (about me) (learning how to github)
-
rudla.kudla
- Posts: 41
- Joined: 20 Apr 2010
Re: Single step (ram) with BRK
If you just need the size of instruction, maybe a part of my simple relocation routine may be of use for you. It can tell you addressing mode of the instruction (no OP code though, so not really usable for disassembler). It uses just 32 byte table.
Attached is full routine that uses this to perform simple
Attached is full routine that uses this to perform simple
Code: Select all
;6502 code relocation routine
;Address mode
;0 - none
;1 - immediate,relative #x
;2 - zero page ZP; ZP,X; ZP,Y; (ZP,X); (ZP),Y
;3 - abs adr; adr,X; adr,Y
;argument size in bytes
; 0 - none
; 1 - byte
; 2 - two bytes
;argument decoding (if there is one)
; 0 - immediate
; 1 - absolute address (either ZP or ABS)
; 2 - relative address (BEQ, ...)
; 3 - indirect address (either ZP or ABS) ABS only for JMP
;address register
; 0 - none
; 1 - X
; 2 - Y
;+---+---+---+---+---+---+---+---+
;| | reg | arg_t | size |
;+---+---+---+---+---+---+---+---+
I_SIZE_MASK = %11
I_ZERO = 0
I_BYTE = 1
I_WORD = 2
I_ARG_IMM = (0 << 2)
I_ADR = (1 << 2)
I_ARG_REL = (2 << 2)
I_IND = (3 << 2) ;indirect is adr+relative
I_X = (1 << 4)
I_Y = (2 << 4)
I_A = (3 << 4)
;--- modes
I_IMPL = 0
I_IMM = I_BYTE + I_ARG_IMM
I_ZP = I_BYTE + I_ADR
I_ZPX = I_BYTE + I_ADR + I_X
I_ZPY = I_BYTE + I_ADR + I_Y
I_ABS = I_WORD + I_ADR
I_ABSX = I_WORD + I_ADR + I_X
I_ABSY = I_WORD + I_ADR + I_Y
I_REL = I_BYTE + I_ARG_REL ;todo - we should have rel
I_INDX = I_BYTE + I_IND + I_X
I_INDY = I_BYTE + I_IND + I_Y
org $2000
ptr = $A0
adr = $A2
code = $a4
decode
ldy #0
lda (ptr),y
iny
tax
and #%00011111
bne regular
txa
;%xxx00000 -> %000xxx00
lsr
lsr
lsr
ora #%11 ;add 3
regular
tax
lda instr_mode_table,x
;--- now we have our addressing mode
and #I_SIZE_MASK
;--- and this is the size
rts
instr_mode_table
; this column is used for special purpose
.byte 0, I_INDX, I_IMM, I_IMM
.byte I_ZP, I_ZP, I_ZP, I_ABS
.byte I_IMPL, I_IMM, I_IMPL, I_IMPL
.byte I_ABS, I_ABS, I_ABS, I_IMPL
.byte I_REL, I_INDY, 0, 0
.byte I_ZPX, I_ZPX, I_ZPX, I_IMM
.byte I_IMPL, I_ABSY, I_IMPL, I_IMM
.byte I_ABSX, I_ABSX, I_ABSX, I_IMM
- Attachments
-
- reloc.asm
- (3.7 KiB) Downloaded 184 times
Last edited by rudla.kudla on Thu Feb 16, 2023 7:18 am, edited 1 time in total.
Re: Single step (ram) with BRK
Thanks, I'll look into that. At the moment I have an existing disassemble-one-instruction routine which returns the length of the instruction so I get it for free
But I have other things to do first!
Neil
Neil
Re: Single step (ram) with BRK
(Edit: misguided first paragraph deleted
)
Yes, for a BRK or for an NMI or IRQ, PC is first to get pushed and P is last, so P will be what's most accessible on stack. Remember, though, that the BRK bit exists only in the P byte pushed to stack. Unlike most bits of P, the BRK bit is never stored within the CPU.
Hoping this is clear.. Probably you've already gotten these details straight in the week that's elapsed since you first posted.
-- Jeff
Quote:
The processor status is pushed, I think, on a BRK
Hoping this is clear.. Probably you've already gotten these details straight in the week that's elapsed since you first posted.
-- 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: Single step (ram) with BRK
Well I might have done, if little things like 'life' wouldn't insist on getting in the way!
The disassembler is about done; just need to make the right things happen when the opcode is invalid, and that's most of the bits in place for the line by line assembler so that shouldn't take too long (hah!) and then I can get on with this bit (though there's some circuit investigation going on in parallel...)
I'm considering a kind of double-layer system with multiple breakpoints (seven seems likely, plus the 'next instruction); I can replace two bytes at the breakpoint with the first being a BRK instruction and the second an ident 0-7 with 0 being reserved for the single step. The BRK interrupt triggers replacement of the bytes from the store, and depending on a command, either simply runs until another existing breakpoint, runs a single instruction, or if the instruction is a call runs until the call returns. Somewhere in there it will obviously spit out the current processor status, of course.
Neil
The disassembler is about done; just need to make the right things happen when the opcode is invalid, and that's most of the bits in place for the line by line assembler so that shouldn't take too long (hah!) and then I can get on with this bit (though there's some circuit investigation going on in parallel...)
I'm considering a kind of double-layer system with multiple breakpoints (seven seems likely, plus the 'next instruction); I can replace two bytes at the breakpoint with the first being a BRK instruction and the second an ident 0-7 with 0 being reserved for the single step. The BRK interrupt triggers replacement of the bytes from the store, and depending on a command, either simply runs until another existing breakpoint, runs a single instruction, or if the instruction is a call runs until the call returns. Somewhere in there it will obviously spit out the current processor status, of course.
Neil
-
kernelthread
- Posts: 166
- Joined: 23 Jun 2021
Re: Single step (ram) with BRK
barnacle wrote:
I can replace two bytes at the breakpoint with the first being a BRK instruction and the second an ident 0-7 with 0 being reserved for the single step.