6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Tue May 07, 2024 12:14 am

All times are UTC




Post new topic Reply to topic  [ 126 posts ]  Go to page Previous  1 ... 5, 6, 7, 8, 9
Author Message
PostPosted: Fri Aug 18, 2023 8:23 pm 
Offline
User avatar

Joined: Sat Jul 24, 2021 1:37 pm
Posts: 282
I've been working on getting the COP signature byte, no use case in mind just a fun challenge. Here is the code I came up with in emulation mode and in native mode.
I don't have the hardware to test it with me yet, which makes me think I need to work on an emulator for the project! I'll report back if any changes are needed.

One thing I'm not 100% sure of is bank crossing behavior. If we end up executing a COP at $FFFF, the next instruction from the CPU's point of view would be $0001, in the same program bank, right? That would make the signature byte $0000 in the same bank, and not in the next bank. I'm wondering because it prevents using stack relative indirect addressing to fetch the signature, since this addressing mode crosses over banks and so you can't just load Y with $FFFF to decrement the program counter.

Anyway, here is the code so far, only the COP sections:

Native mode

Code:
; where each register is relative to the stack pointer after interrupt entry
int_native_stack_offset_pb = 13
int_native_stack_offset_pc = 11
int_native_stack_offset_p  = 10
int_native_stack_offset_db = 9
int_native_stack_offset_d  = 7
int_native_stack_offset_a  = 5
int_native_stack_offset_x  = 3
int_native_stack_offset_y  = 1

  +mx_16_bits
  lda int_native_stack_offset_pc,s ; get program counter
  dec                              ; decrement it by one to get to signature byte
                                   ; note: if COP is at $FFFF, then the signature byte
                                   ; is at $0000 in the same bank (TODO: verify with hardware)
  tax                              ; save this address to a 16 bits X
  +m_8_bits

  lda int_native_stack_offset_pb,s ; get program bank register
  phb                              ; save current data bank register
  pha                              ; and save the new one as data bank register
  plb                              ; so we load signature byte from the right bank

  lda+2 0,x                        ; load the 8 bit signature, from the right bank and with
                                   ; a 16 bit offset address
  +x_8_bits

  plb                              ; restore original data bank
  and # $ff                        ; ensure flags are set by the value of A


Emulation mode

Code:
; where each register is relative to the stack pointer after interrupt entry
int_emu_stack_offset_pc = 5
int_emu_stack_offset_p  = 4
int_emu_stack_offset_a  = 3
int_emu_stack_offset_x  = 2
int_emu_stack_offset_y  = 1

  lda int_emu_stack_offset_pc+1,s  ; high byte program counter
  tax
  lda int_emu_stack_offset_pc,s    ; low byte program counter
  bne +                            ; decrement it by one to get to signature byte address
  dex
+ dec
  phx                              ; push new address to the stack
  pha
  ldy # 0
  lda (1,s),y                      ; load signature byte
  ply                              ; reset stack pointer
  ply
  and # $ff                        ; ensure flags are set by the value of A

_________________
BB816 Computer YouTube series


Top
 Profile  
Reply with quote  
PostPosted: Fri Aug 18, 2023 8:31 pm 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10799
Location: England
Quote:
If we end up executing a COP at $FFFF, the next instruction from the CPU's point of view would be $0001, in the same program bank, right? That would make the signature byte $0000 in the same bank, and not in the next bank

Indeed - the PC is 16 bits and only increments within that. The bank byte is independent.


Top
 Profile  
Reply with quote  
PostPosted: Fri Aug 18, 2023 10:56 pm 
Offline
User avatar

Joined: Fri Aug 03, 2018 8:52 am
Posts: 746
Location: Germany
having a multi-byte Instruction like COP split at the edge of a bank seems like a pretty rare scenario. unless the program is specifically written to make use of the PC wrapping... but even then it seems easier to just avoid split instructions like that.

anyways, my SBC's BIOS also uses COP for system calls because it's very convient and much easier to expand/move around in the ROM compared to jump tables accessed with JSL or Indirect Jumps.
but the way i get the signature byte is a bit different, as it loads the whole 24-bit address into a temporary DP location, subtracts 1 from it, and then uses the 24-bit Indirect Addressing mode to get the byte.
that way the code doesn't need to touch the data bank register.
The signature byte is then multiplied by 2 and put into X to be used as an index to a jump table. giving me 256 possible functions.

Code:
COP_HANDLER:
    ai16                    ; 16-bit A/X/Y
   
    PHA
    PHX
    PHY
    TDC
    PHA                     ; Save all Registers (A, X, Y, DP)
   
    LDA #SYS_DP
    TCD                     ; Set the Driect Page
   
    accu8
    ; Get the Return Address, subtract 1 from it, and store it into a Temp Pointer
    LDA 10,S                ; Low Byte
    CLC
    SBC #0
    STA T_PTR
    LDA 11,S                ; Middle Byte
    SBC #0
    STA T_PTR+1
    LDA 12,S                ; High Byte
    SBC #0
    STA T_PTR+2
   
    LDA #0
    XBA                     ; Clear the High Byte of A
    LDA [T_PTR]             ; Get the Signature Byte
    ASL A                   ; Multiply it by 2
    TAX                     ; And put it into X
   
    PEA .LOWORD(COP_RET - 1)
    JMP (COP_TABLE,X)       ; Then use it as an index for the Jump Table

COP_RET:
    ai16                    ; 16-bit A/X/Y
    PLA
    TCD
    PLY
    PLX
    PLA                     ; Restore all Registers
RTI

the PEA infront of the Indirect JMP pushes the address of (COP_RET - 1) to the stack, basically just emulating an Indirect JSR instruction.
so all the COP functions can jump to that code by using RTS instead of a regular JMP.


Top
 Profile  
Reply with quote  
PostPosted: Sat Aug 19, 2023 12:38 pm 
Offline
User avatar

Joined: Sat Jul 24, 2021 1:37 pm
Posts: 282
BigEd wrote:
Indeed - the PC is 16 bits and only increments within that. The bank byte is independent.


Thanks for confirming!

Proxy wrote:
having a multi-byte Instruction like COP split at the edge of a bank seems like a pretty rare scenario. unless the program is specifically written to make use of the PC wrapping... but even then it seems easier to just avoid split instructions like that.


Agreed, don't plan on intentionally writing a split instruction, just want to make sure the behavior is well defined in edge cases.

Proxy wrote:
anyways, my SBC's BIOS also uses COP for system calls because it's very convient and much easier to expand/move around in the ROM compared to jump tables accessed with JSL or Indirect Jumps.
but the way i get the signature byte is a bit different, as it loads the whole 24-bit address into a temporary DP location, subtracts 1 from it, and then uses the 24-bit Indirect Addressing mode to get the byte.
that way the code doesn't need to touch the data bank register.


Thanks for sharing your code, it was nice to see another approach.

Any reason for using TDC+PHA/PLA+TCD instead of PHD/PLD?

_________________
BB816 Computer YouTube series


Top
 Profile  
Reply with quote  
PostPosted: Sat Aug 19, 2023 12:58 pm 
Offline
User avatar

Joined: Fri Aug 03, 2018 8:52 am
Posts: 746
Location: Germany
akohlbecker wrote:
Any reason for using TDC+PHA/PLA+TCD instead of PHD/PLD?

because i didn't know or forgot those instructions existed :oops:


Top
 Profile  
Reply with quote  
PostPosted: Sat Aug 19, 2023 1:39 pm 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10799
Location: England
For info on 816 fine details and corner cases, see Bruce's major document


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 126 posts ]  Go to page Previous  1 ... 5, 6, 7, 8, 9

All times are UTC


Who is online

Users browsing this forum: No registered users and 12 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: