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