It is currently Thu Oct 19, 2017 3:10 pm

All times are UTC - 7 hours





Post new topic Reply to topic  [ 23 posts ]  Go to page Previous  1, 2
Author Message
 Post subject:
PostPosted: Mon Dec 12, 2005 2:22 pm 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 19103
Location: NE Indiana, USA (NTSC)
blargg wrote:
The way an IRQ handler determines whether the cause was an IRQ of BRK is by examining bit 4 of the byte at the top of the stack (which also contains the saved status flags in other bits).

Like this?
Code:
irqvector:
  pha
  txa
  pha  ; stack state after: SP | X | A | P | LR_low | LR_high | ...
  tsx
  lda #$10
  and $103,x
  beq irqhandler
  lda $104,x
  sta zp_lr
  lda $105,x
  sta zp_lr+1
  tya
  pha  ; stack state after: SP | Y | X | A | P | LR_low | LR_high | ...
  ldy #0
  lda (zp_lr),y
  asl a
  tax
  jmp (brktable,x)

  ; Each entry in brktable is responsible for pulling arguments that
  ; were originally passed in Y, X, A, and P, and then doing RTS.

irqhandler:
  ; [omitted IRQ handler code]
  pla
  tax
  pla
  rti

But then I don't see the point of BRK if it means wasting all this time to save one byte of code.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Dec 12, 2005 9:11 pm 
Offline
User avatar

Joined: Mon Sep 27, 2004 8:33 am
Posts: 3715
Location: Central Texas, USA
Ugh, I get your point. I guess BRK isn't much use beyond invoking a debugger by changing a single byte.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Dec 13, 2005 5:56 am 
Offline
User avatar

Joined: Thu Mar 24, 2005 3:17 pm
Posts: 355
WedNESday wrote:
Does anyone know of any games that actually use the BRK opcode? I can't imagine so, as the vector is the same as the sound's, unless you wanted to prematurely process sound code...


Dragon Warrior 1 uses it, I don't know of any other games that do, but I'm sure there are a few.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Dec 13, 2005 10:22 am 
If you don't implement IRQs in any way (as is the case with most pre-MMC3 games), then BRK can be useful as a subroutine call. The BRK handler wouldn't have to check the B flag, nor would it necessarily need to preserve registers (particularly if they are parameters).

I noticed that some games that don't use IRQs set the IRQ vector to match the RESET vector. In this scenario, should a bug cause the PC to get corrupted, there's a chance that the game would reset, particularly if the PC ends up in RAM that was cleared to zero and since unused. I know that some newer architectures (such as PowerPC) will always consider opcode 0 as illegal and trigger an exception, since a PC pointed to unused memory often causes a zero to be read for the next instruction.


Top
  
 
 Post subject:
PostPosted: Tue Dec 13, 2005 2:21 pm 
Offline
User avatar

Joined: Mon Sep 27, 2004 8:33 am
Posts: 3715
Location: Central Texas, USA
Quote:
I know that some newer architectures (such as PowerPC) will always consider opcode 0 as illegal and trigger an exception, since a PC pointed to unused memory often causes a zero to be read for the next instruction.


Modern architectures offer both an MMU to mark unmapped pages as invalid, and bus signals to signal an error for the memory transaction. Taking an exception for undefined instructions is to allow detection of erroneous execution, and emulation of unsupported instructions and modes (for example, unaligned access support and older complex instructions are sometimes removed from the silicion and put in the operating system instead).


Top
 Profile  
 
 Post subject:
PostPosted: Tue Dec 13, 2005 8:43 pm 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 19103
Location: NE Indiana, USA (NTSC)
Anonymous wrote:
BRK can be useful as a subroutine call. The BRK handler wouldn't have to check the B flag, nor would it necessarily need to preserve registers (particularly if they are parameters).

Wouldn't it still need to use A, X, and Y in order to get the syscall number from the byte after the BRK opcode?

Same code with IRQ support deleted and with an optimization to use the rare (d,x) mode:
Code:
brkvector:
  ; First copy the return address to the zero page, giving a
  ; pointer to the syscall number (e.g. $69 in BRK $69).
  pha
  txa
  pha  ; stack state after: SP | X | A | P | LR_low | LR_high | ...
  tsx
  lda $104,x
  sta zp_lr
  lda $105,x
  sta zp_lr+1

  ; Now read the syscall number.
  ldx #0
  lda (zp_lr,x)

  ; Look up the syscall in the jump table.
  asl a
  tax
  jmp (brktable,x)

  ; Each entry in brktable is responsible for pulling arguments that
  ; were originally passed in X, A, and P, and then doing RTS.
  ; This new BRK handler does not modify the Y register.
  ; This code is NOT reentrant because there's a race condition on
  ; zp_lr.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Dec 13, 2005 8:54 pm 
Offline
User avatar

Joined: Sun Sep 19, 2004 10:59 pm
Posts: 1389
There's just one problem: there is no "JMP (addr,X)" instruction on the 6502, so you'll have to load the address manually.

_________________
Quietust, QMT Productions
P.S. If you don't get this note, let me know and I'll write you another.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Dec 13, 2005 9:34 pm 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 19103
Location: NE Indiana, USA (NTSC)
diff:
Code:
-  jmp (brktable,x)
+  lda brktable,x
+  sta zp_lr
+  lda brktable+1,x
+  sta zp_lr+1
+  jmp (zp_lr)

Of course it becomes an order of magnitude simpler in the degenerate case where the syscall number does not matter (BRK $00 is the same as BRK $01 is the same as BRK $FF), but how is that useful?


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 23 posts ]  Go to page Previous  1, 2

All times are UTC - 7 hours


Who is online

Users browsing this forum: No registered users and 9 guests


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:  
Powered by phpBB® Forum Software © phpBB Group