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
===============================================================================