Skip to content

Finding The SmartPort Dispatcher

Norman Davie edited this page Feb 20, 2023 · 6 revisions

Before using the SmartPort, you have to find it. More specifically, you have to find the dispatcher.

Finding the Slot

The first part, finding the slot, is accomplished by scanning the I/O space for each slot ($C000, $C100, ...), for the following four bytes at offsets 1, 3, 5, and 7:

Offset Byte
1 $20
3 $00
5 $03
7 $00

C implementation

/**
 * Check for SmartPort presence
 * @return slot #, or 0xFF if not present.
 */
uint8_t sp_find_slot(void)
{
  uint8_t s=0;

  for (s=7; s-- > 0;)
    {
      uint16_t a = 0xc000 + (s * 0x100);
      if ((PEEK(a+1) == 0x20) &&
          (PEEK(a+3) == 0x00) &&
          (PEEK(a+5) == 0x03) &&
          (PEEK(a+7) == 0x00))
        return s;
    }

  // Did not find.
  return 0;
}

6502 Assembly Example


SRC_ADDR		=	$ED
SRC_ADDR_LO	        =	$ED
SRC_ADDR_HI		=	$EE

;*******************************
; FIND_SMARTPORT_SLOT
; INPUT:
;   NONE
;***
; RETURN
;   A = $FF - NO SMARTPORT FOUND
;   A = $CX - WHERE X IS THE SLOT
;**********************************

FIND_SMARTPORT_SLOT:

        LDA     #$C7            ; START AT SLOT 7 ($C700)
        STA     SLOT_ADDR_HI
        LDA     #$00
        STA     SLOT_ADDR_LO

SCAN:
        LDY #$01                ; LOOK AT BYTES 1,3,5,AND 7
        LDX #$00

NEXT_MATCH:
        LDA (SLOT_ADDR),Y       ; COMPARE TO THE MAGIC NUMBERS
        CMP FIJINET_ID,X        ; 
        BNE NEXT_SLOT           ; NOT THE SAME, SO GO TO NEXT SLOT

        INY                     ; PREPARE TO CHECK THE NEXT NUMBER
        INY
        INX                     ; POINTER TO NEXT NUMBER TO CHECK
        CPX #$04                ; HAVE WE COMPARED ALL 4 NUMBERS?
        BEQ FOUND               ; YES, WE'VE FOUND IT
        BNE NEXT_MATCH          ; MORE TO MATCH

NEXT_SLOT:
        LDX SLOT_ADDR_HI        ; MOVE TO THE NEXT LOWER SLOT
        DEX                     ; $C700 -> $C600
        STX SLOT_ADDR_HI
        CPX #$C0                ; HAVE WE GONE BELOW SLOT 1?
        BEQ NOT_FOUND           ; WE'RE DONE
        BNE SCAN                ; CONTINUE SCANNING
FOUND:
        LDA SLOT_ADDR_HI
        RTS                     ; WE FOUND IT! A = SLOT ADDRESS

NOT_FOUND:
        LDA #$FF                ; WE DIDN'T FIND IT
        RTS
        
FIJINET_ID:     .BYTE $20, $00, $03, $00 

Finding the dispatch address

Once the slot has been found, the dispatcher address can be found by reading offset $FF at the found slot, then taking the value found, adding 3 to it, and adding that to the slot address.

C implementation

/**
 * Return dispatch address for Smartport slot.
 * @param s Slot # (1-7)
 * @return smartport dispatch address
 */
uint16_t sp_dispatch_address(uint8_t slot)
{
  uint16_t a = (slot * 0x100) + 0xC000;
  uint8_t j = PEEK(a+0xFF);

  return a + j + 3;
}

6502 Assembly Example

;*******************************
; GET_SMARTPORT_DISPATCH_ADDRESS
; INPUT:
;   NONE
;***
; RETURN
;   -A DISPATCHER ADDRESS HIGH
;   -X DISPATCHER ADDRESS LOW
; OR A AND X WILL BE SET TO $FF
; IF DISPATCHER NOT FOUND
;**********************************

DISPATCHER		=	$EB
DISPATCHER_ADDR_LO      =	$EB
DISPATCHER_ADDR_HI   	= 	$EC

GET_SMARTPORT_DISPATCH_ADDRESS:
        JSR FIND_SMARTPORT_SLOT 
        CMP #$FF                ; IF A == $FF THEN NOT FOUND
        BEQ NO_DISPATCHER

        STA DISPATCHER_ADDR_HI  ; A = $CX WHERE X IS THE SLOT
        LDA #$00
        STA DISPATCHER_ADDR_LO  ; COMPLETE ADDRESS IS $CX00
        
        LDY #$FF
        LDA (SLOT_ADDR),Y        ; j= peek(a+0xFF)
        CLC
        ADC DISPATCHER_ADDR_LO   ; DISPATCHER_ADDR += J
        STA DISPATCHER_ADDR_LO

        LDA DISPATCHER_ADDR_HI
        ADC #$00
        STA DISPATCHER_ADDR_HI

        CLC                     ; DISPATCHER_ADDR += 3
        LDA DISPATCHER_ADDR_LO
        ADC #$03
        STA DISPATCHER_ADDR_LO
        
        LDA DISPATCHER_ADDR_HI
        ADC #$00
        STA DISPATCHER_ADDR_HI

        LDA DISPATCHER_ADDR_HI  ; PUT ADDRESS IN A AND X
        LDX DISPATCHER_ADDR_LO
        CLC
        BCC DONE

NO_DISPATCHER:
        LDA #$FF                ; NO ADDRESS FOUND
        LDX #$FF

DONE:        
        RTS

Once this is found, you can start Issuing SmartPort Commands.

Clone this wiki locally