[comp.sys.handhelds] CHIP8.MACros, 2/3

SLSW2@cc.usu.edu (Roger Ivie) (09/20/90)

Here's CHIP8.MAC:

<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< CHIP8.MAC
; Define symbols for the registers. Note that the scheme assumes that 
; data will never be bigger than 12 bits.

V0	EQU 0F000H
V1	EQU 0F001H
V2	EQU 0F002H
V3	EQU 0F003H
V4	EQU 0F004H
V5	EQU 0F005H
V6	EQU 0F006H
V7	EQU 0F007H
V8	EQU 0F008H
V9	EQU 0F009H
VA	EQU 0F00AH
VB	EQU 0F00BH
VC	EQU 0F00CH
VD	EQU 0F00DH
VE	EQU 0F00EH
VF	EQU 0F00FH
.INSTRHI SET 0
.INSTRLO SET 0

;-------
;
;	Other-endian DW

.DW	MACRO VALUE
.INSTRHI SET HIGH (VALUE)
.INSTRLO SET LOW (VALUE)
	DB ..INSTRHI,..INSTRLO
	ENDM

;-------
;
;	Clear screen:
;
;	CLS

CLS	MACRO
	..DW 00E0H
	ENDM

;-------
;
;	Return from subroutine:
;
;	RET
;	RETURN

RET	MACRO
	..DW 00EEH
	ENDM
RETURN	MACRO
	..DW 00EEH
	ENDM

;-------
;
;	Jump to location:
;
;	JUMP <addr>
;	JUMP <addr>+V0

JUMP	MACRO DEST

IF1
	..DW 0
ELSE
  IFT	DEST GE V0	;; If it's JUMP <addr>+V0
	..DW <DEST AND 0FFFH + 0B000H>
  ELSE			;; Otherwise, it's JUMP <addr>
	..DW <DEST + 01000H>
  ENDIF
ENDIF
	ENDM

;-------
;
;	Call a subroutine:
;
;	CALL <addr>
;

CALL	MACRO DEST
IF1
	..DW 0
ELSE
	..DW <DEST + 02000H>
ENDIF
	ENDM

;-------
;
;	Skip if equal:
;
;	SKE Vx,<constant>
;	SKE Vx,Vy

SKE	MACRO X, Y

IF1
	..DW 0
ELSE
  IFT	X GE V0		;; Verify first operand is a register
    IFT	Y GE V0		;; It's SKE Vx,Vy
	..DW <( ( X AND 0FH ) SHL 8 ) + ( ( Y AND 0FH ) SHL 4 ) + 05000H>
    ELSE		;; It's SKE Vx,<constant>
	..DW <( ( X AND 0FH ) SHL 8 ) + Y + 03000H>
    ENDIF
  ELSE
	.PRINTX * The first operand of SKE must be a register *
	..DW 0
  ENDIF
ENDIF
	ENDM

;-------
;
;	Skip if not equal:
;
;	SKNE Vx,<constant>
;	SKNE Vx,Vy

SKNE	MACRO X, Y

IF1
	..DW 0
ELSE
  IFT	X GE V0		;; Verify first operand is a register
    IFT	Y GE V0		;; It's SKNE Vx,Vy
	..DW <( ( X AND 0FH ) SHL 8 ) + ( ( Y AND 0FH ) SHL 4 ) + 09000H>
    ELSE		;; It's SKNE Vx,<constant>
	..DW <( ( X AND 0FH ) SHL 8 ) + Y + 04000H>
    ENDIF
  ELSE
	.PRINTX * The first operand of SKNE must be a register *
	..DW 0
  ENDIF
ENDIF
	ENDM

;-------
;
;	Register transfer:
;
;	LD Vx,<constant>
;	LD Vx,Vy
;	LD I,<constant>
;	LD Vx,DELAY
;	LD DELAY,Vx
;	LD SOUND,Vx
;	LD BCD,Vx
;	LD @I,Vx
;	LD Vx,@I

LD	MACRO DEST, SRC

IF1
	..DW 0
ELSE
  IFIDN	<I>,<DEST>	;; It's LD I,?
    IFT	SRC LT V0	;;   Source has to be a constant
	..DW <SRC + 0A000H>
    ELSE
	.PRINTX * I can only be loaded from a constant *
	..DW 0
    ENDIF
    EXITM
  ENDIF

  IFIDN	<DELAY>,<DEST>	;; It's LD DELAY,?
    IFT	SRC GE V0	;;   Source has to be a register
	..DW <((SRC AND 0FH) SHL 8) + 0F015H>
    ELSE
	.PRINTX * DELAY can only be loaded from a register *
	..DW 0
    ENDIF
    EXITM
  ENDIF

  IFIDN	<DELAY>,<SRC>	;; It's LD ?,DELAY
    IFT	DEST GE V0	;;   Destination has to be a register
	..DW <((DEST AND 0FH) SHL 8) + 0F007H>
    ELSE
	.PRINTX * Only a register can be loaded from DELAY *
	..DW 0
    ENDIF
    EXITM
  ENDIF

  IFIDN	<SOUND>,<DEST>	;; It's LD SOUND,?
    IFT	SRC GE V0	;;   Source has to be a register
	..DW <((SRC AND 0FH) SHL 8) + 0F018H>
    ELSE
	.PRINTX * SOUND can only be loaded from a register *
	..DW 0
    ENDIF
    EXITM
  ENDIF

  IFIDN	<BCD>,<DEST>	;; It's LD BCD,?
    IFT	SRC GE V0	;; Source has to be a register
	..DW <((SRC AND 0FH) SHL 8) + 0F033H>
    ELSE
	.PRINTX * BCD can only be loaded from a register *
	..DW 0
    ENDIF
    EXITM
  ENDIF

  IFIDN	<@I>,<DEST>	;; It's LD @I,?
    IFT	SRC GE V0	;; Source has to be a register
	..DW <((SRC AND 0FH) SHL 8) + 0F055H>
    ELSE
	.PRINTX * @I can only be loaded from a register range *
	..DW 0
    ENDIF
    EXITM
  ENDIF

  IFIDN	<@I>,<SRC>	;; It's LD ?,@I
    IFT	DEST GE V0	;; Destination as to be a register
	..DW <((DEST AND 0FH) SHL 8) + 0F065H>
    ELSE
	.PRINTX * Only a register range can be loaded from @I *
	..DW 0
    ENDIF
    EXITM
  ENDIF

;; If we get here, it should be either LD Vx,Vy or LD Vx,<constant>

  IFT	DEST GE V0	;; Make certain destination is a register
    IFT	SRC LT V0	;;   It's LD Vx,<constant>
	..DW <((DEST AND 0FH) SHL 8) + SRC + 06000H>
    ELSE		;;   It has to be LD Vx,Vy
	..DW <((DEST AND 0FH) SHL 8) + ((SRC AND 0FH) SHL 4) + 08000H>
    ENDIF
  ELSE
	.PRINTX * Invalid destination *
	..DW 0
  ENDIF
ENDIF
	ENDM

;-------
;
;	Add two operands:
;
;	ADD Vx,<constant>
;	ADD Vx,Vy
;	ADD I,Vx

ADD	MACRO DEST,SRC

IF1
	..DW 0
ELSE
  IFIDN	<I>,<DEST>
			;; It's ADD I,Vx
    IFT	SRC GE V0	;;   Verify that the source is a register
	..DW <((SRC AND 0FH) SHL 8) + 0F01EH>
    ELSE
	.PRINTX * Only a register can be added to I *
	..DW 0
    ENDIF
    EXITM
  ENDIF

;; It has to be either ADD Vx,Vy or ADD Vx,<constant>

  IFT	DEST GE V0	;; Verify that the destination is a register
    IFT	SRC GE V0	;;   It's ADD Vx,Vy
	..DW <((DEST AND 0FH) SHL 8) + ((SRC AND 0FH) SHL 4) + 08004H>
    ELSE		;;   It's ADD Vx,<constant>
	..DW <((DEST AND 0FH) SHL 8) + SRC + 07000H>
    ENDIF
  ELSE
	.PRINTX * Things can be ADDed only to I or to a register *
	..DW 0
  ENDIF
ENDIF
	ENDM

;-------
;
;	Inclusive or:
;
;	OR Vx,Vy

OR	MACRO DEST,SRC

IF1
	..DW 0
ELSE
  IFT	(DEST GE V0) OR (SRC GE V0)
	..DW <((DEST AND 0FH) SHL 8) + ((SRC AND 0FH) SHL 4) + 08001H>
  ELSE
	.PRINTX * Both operands must be registers *
	..DW 0
  ENDIF
ENDIF
	ENDM

;-------
;
;	Bitwise and:
;
;	AND Vx,Vy

AND	MACRO DEST,SRC

IF1
	..DW 0
ELSE
  IFT	(DEST GE V0) OR (SRC GE V0)
	..DW <((DEST AND 0FH) SHL 8) + ((SRC AND 0FH) SHL 4) + 08002H>
  ELSE
	.PRINTX * Both operands must be registers *
	..DW 0
  ENDIF
ENDIF
	ENDM

;-------
;
;	Bitwise exclusive or:
;
;	XOR Vx,Vy

XOR	MACRO DEST,SRC

IF1
	..DW 0
ELSE
  IFT	(DEST GE V0) OR (SRC GE V0)
	..DW <((DEST AND 0FH) SHL 8) + ((SRC AND 0FH) SHL 4) + 08003H>
  ELSE
	.PRINTX * Both operands must be registers *
	..DW 0
  ENDIF
ENDIF
	ENDM

;-------
;
;	Subtract:
;
;	SUB Vx,Vy

SUB	MACRO DEST,SRC

IF1
	..DW 0
ELSE
  IFT	(DEST GE V0) OR (SRC GE V0)
	..DW <((DEST AND 0FH) SHL 8) + ((SRC AND 0FH) SHL 4) + 08005H>
  ELSE
	.PRINTX * Both operands must be registers *
	..DW 0
  ENDIF
ENDIF
	ENDM

;-------
;
;	Shift right:
;
;	SHR Vx

SHR	MACRO DEST

IF1
	..DW 0
ELSE
  IFT	(DEST GE V0) 
	..DW <((DEST AND 0FH) SHL 8) + 08006H>
  ELSE
	.PRINTX * Operand must be a register *
	..DW 0
  ENDIF
ENDIF
	ENDM

;-------
;
;	Reverse subtract:
;
;	RSUB Vx,Vy

RSUB	MACRO DEST,SRC

IF1
	..DW 0
ELSE
  IFT	(DEST GE V0) OR (SRC GE V0)
	..DW <((DEST AND 0FH) SHL 8) + ((SRC AND 0FH) SHL 4) + 08007H>
  ELSE
	.PRINTX * Both operands must be registers *
	..DW 0
  ENDIF
ENDIF
	ENDM

;-------
;
;	Shift left:
;
;	SHL Vx

SHL	MACRO DEST

IF1
	..DW 0
ELSE
  IFT	(DEST GE V0)
	..DW <((DEST AND 0FH) SHL 8) + 0800EH>
  ELSE
	.PRINTX * Operand must be a register *
	..DW 0
  ENDIF
ENDIF
	ENDM

;-------
;
;	And constant and random number:
;
;	RANDOM Vx		; Uses 0FFH for constant
;	RANDOM Vx,<constant>

RANDOM	MACRO DEST,MASK

IF1
	..DW 0
ELSE
  IFT	DEST GE V0
    IFB	<MASK>
	..DW <((DEST AND 0FH) SHL 8) + 0C0FFH>
    ELSE
	..DW <((DEST AND 0FH) SHL 8) + MASK + 0C000H>
    ENDIF
  ELSE
	.PRINTX * First operand must be a register *
	..DW 0
  ENDIF
ENDIF
	ENDM

;-------
;
;	Show sprite:
;
;	SHOW Vx,Vy,N

SHOW	MACRO X,Y,N

IF1
	..DW 0
ELSE
  IFT	(X GE V0) AND (Y GE V0)
	..DW <((X AND 0FH) SHL 8) + ((Y AND 0FH) SHL 4) + (N AND 0FH) + 0D000H>
  ELSE
	.PRINTX * Coordinates must be registers *
	..DW 0
  ENDIF
ENDIF
	ENDM

;-------
;
;	Skip if key pressed:
;
;	SKIFKEY Vx

SKIFKEY	MACRO DEST

IF1
	..DW 0
ELSE
  IFT	DEST GE V0
	..DW <((DEST AND 0FH) SHL 8) + 0E09EH>
  ELSE
	.PRINTX * Destination must be a register *
	..DW 0
  ENDIF
ENDIF
	ENDM

;-------
;
;	Skip if key not pressed:
;
;	SKIFNOTKEY Vx

SKIFNOTKEY	MACRO DEST

IF1
	..DW 0
ELSE
  IFT	DEST GE V0
	..DW <((DEST AND 0FH) SHL 8) + 0E0A1H>
  ELSE
	.PRINTX * Destination must be a register *
	..DW 0
  ENDIF
ENDIF
	ENDM

;-------
;
;	Get a keystroke:
;
;	GETKEY Vx

GETKEY	MACRO DEST

IF1
	..DW 0
ELSE
  IFT	DEST GE V0
	..DW <((DEST AND 0FH) SHL 8) + 0F00AH>
  ELSE
	.PRINTX * Destination must be a register *
	..DW 0
  ENDIF
ENDIF
	ENDM

;-------
;
;	Point to character font element:
;
;	CHAR Vx

CHAR	MACRO SRC

IF1
	..DW 0
ELSE
  IFT	SRC GE V0
	..DW <((SRC AND 0FH) SHL 8) + 0F029H>
  ELSE
	.PRINTX * Source must be a register *
	..DW 0
  ENDIF
ENDIF
	ENDM

	.PHASE 200H
-- 
===============================================================================
Roger Ivie

35 S 300 W
Logan, Ut.  84321
(801) 752-8633
===============================================================================