Skip to content

Issuing SmartPort Commands

Thomas Cherryhomes edited this page Dec 26, 2022 · 8 revisions

Once the SmartPort dispatcher is found, commands can be issued. The FujiNet can respond to STATUS, CONTROL, READ, WRITE, OPEN, and CLOSE commands.

STATUS

Status commands are used to ask for information from the FujiNet.

C implementation (CC65)

int8_t sp_status(uint8_t dest, uint8_t statcode)
{
  sp_error = 0;
  // build the command list
  sp_cmdlist[0] = SP_STATUS_PARAM_COUNT;
  sp_cmdlist[1] = dest; // set before calling sp_status();
  sp_cmdlist[2] = (uint8_t)((uint16_t)&sp_payload & 0x00FF);
  sp_cmdlist[3] = (uint8_t)((uint16_t)&sp_payload >> 8) & 0xFF;
  sp_cmdlist[4] = statcode;

  sp_cmdlist_low = (uint8_t)((uint16_t)&sp_cmdlist & 0x00FF);
  sp_cmdlist_high = (uint8_t)((uint16_t)&sp_cmdlist >> 8) & 0xFF;


  // store cmd list
  __asm__ volatile ("lda #%b", SP_CMD_STATUS);
  __asm__ volatile ("sta %g", spCmd); // store status command # 
  __asm__ volatile ("lda %v", sp_cmdlist_low);
  __asm__ volatile ("sta %g", spCmdListLow); // store status command #
  __asm__ volatile ("lda %v", sp_cmdlist_high);
  __asm__ volatile ("sta %g", spCmdListHigh); // store status command #

  __asm__ volatile ("jsr $C50D"); // to do - find SP entry point using algorithm from firmware reference
spCmd:
  __asm__ volatile ("nop");
spCmdListLow:
  __asm__ volatile ("nop");
spCmdListHigh:
  __asm__ volatile ("nop");
  __asm__ volatile ("stx %v", sp_rtn_low);
  __asm__ volatile ("sty %v", sp_rtn_high);
  __asm__ volatile ("sta %v", sp_err);

  sp_count = ((uint16_t)sp_rtn_high << 8) | (uint16_t)sp_rtn_low;
  sp_error = sp_err;
  return sp_err;
}

Asm implementation

STATUSCODE = $00

	jsr DISPATCH
	DFB #STATUSCODE
	DW  CMLIST
	BCS ERROR

	; Everything ok
	CLC
	RTS
	
ERROR	; not okay
	RTS
	
CMLIST: DFB	#$04		; status has length of 4	
	DFB	#DEST           ; Destination device #
	DW	BUFFER          ; lo and hi bytes for buffer address
	DFB	STATUSCODE      ; The status code

CONTROL

CONTROL commands are typically imperative in nature, asking the FujiNet to perform an operation.

Asm Implementation

CTRLCODE = $04

	jsr DISPATCH
	DFB #CTRLCODE
	DW  CMLIST
	BCS ERROR

	; Everything ok
	CLC
	RTS
	
ERROR	; not okay
	RTS
	
CMLIST: DFB	#$04		; status has length of 4	
	DFB	#DEST           ; Destination device #
	DW	BUFFER          ; lo and hi bytes for buffer address
	DFB	CTRLCODE        ; The status code

C (CC65) implementation

int8_t sp_control(uint8_t dest, uint8_t ctrlcode)
{
  sp_error = 0;
  // sp_dest = 5; // need to search
  // build the command list
  sp_cmdlist[0] = SP_CONTROL_PARAM_COUNT;
  sp_cmdlist[1] = dest; // set before calling sp_status();
  sp_cmdlist[2] = (uint8_t)((uint16_t)&sp_payload & 0x00FF);
  sp_cmdlist[3] = (uint8_t)((uint16_t)&sp_payload >> 8) & 0xFF;
  sp_cmdlist[4] = ctrlcode;

  sp_cmdlist_low = (uint8_t)((uint16_t)&sp_cmdlist & 0x00FF);
  sp_cmdlist_high = (uint8_t)((uint16_t)&sp_cmdlist >> 8) & 0xFF;

  // store cmd list
  __asm__ volatile ("lda #%b", SP_CMD_CONTROL);
  __asm__ volatile ("sta %g", spCmd); // store status command #
  __asm__ volatile ("lda %v", sp_cmdlist_low);
  __asm__ volatile ("sta %g", spCmdListLow); // store status command #
  __asm__ volatile ("lda %v", sp_cmdlist_high);
  __asm__ volatile ("sta %g", spCmdListHigh); // store status command #

  __asm__ volatile ("jsr $C50D"); // to do - find entry point and used it instead of hardcoded address
spCmd:
  __asm__ volatile ("nop");
spCmdListLow:
  __asm__ volatile ("nop");
spCmdListHigh:
  __asm__ volatile ("nop");
  __asm__ volatile ("sta %v", sp_err);
  sp_error = sp_err;
  return sp_err;
}

READ

WRITE

Clone this wiki locally