Next Previous Contents

6. Adding Custom Instructions

The cc65 instruction set only supports the WAI (Wait for Interrupt) and STP (Stop) instructions when used with the 65816 CPU (accessed via the --cpu command line option of the ca65 macro assembler). The 65C02 core used in this example supports these two instructions, and in fact the system benefits from the use of both the WAI and STP instructions.

In order to use the WAI instruction in this case, a C routine named "wait" was created that consists of the WAI opcode followed by a subroutine return. It was convenient in this example to put the IRQ interrupt enable in this subroutine as well, since interrupts should only be enabled when the code is in this wait condition.

For both the WAI and STP instructions, the assembler is "fooled" into placing those opcodes into memory by inserting a single byte of data that just happens to be the opcode for those instructions. The assembly code routines are placed in a file, named "wait.s", which is shown below:


; ---------------------------------------------------------------------------
; wait.s
; ---------------------------------------------------------------------------
;
; Wait for interrupt and return

.export  _wait, _stop

; ---------------------------------------------------------------------------
; Wait for interrupt:  Forces the assembler to emit a WAI opcode ($CB)
; ---------------------------------------------------------------------------

.segment  "CODE"

.proc _wait: near

           CLI                    ; Enable interrupts
.byte      $CB                    ; Inserts a WAI opcode
           RTS                    ; Return to caller

.endproc

; ---------------------------------------------------------------------------
; Stop:  Forces the assembler to emit a STP opcode ($DB)
; ---------------------------------------------------------------------------

.proc _stop: near

.byte      $DB                    ; Inserts a STP opcode

.endproc

The label _wait, when exported, can be called by using the wait () subroutine call in C. The section is marked as code so that it will be stored in read-only memory, and the procedure is tagged for 16-bit absolute addressing via the "near" modifier. Similarly, the _stop routine can be called from within the C-level code via a call to stop (). In addition, the routine can be called from assembly code by calling _stop (as was done in the interrupt service routine).


Next Previous Contents