c64-livecoding/wip-duuqnd/instruction.lisp

54 lines
2.2 KiB
Common Lisp

(in-package #:user-side-compiler)
(defgeneric check-arguments (instruction))
(defclass instruction ()
((%mnemonic :allocation :class :reader mnemonic :initarg :mnemonic)
(%operand :accessor operand :initarg :operand)
(%next :accessor next :accessor normal-next :initarg :next)))
(defclass complete-mixin ()
((%opcode :allocation :class :reader opcode :initarg :opcode)))
(defclass immediate-mixin () ())
(defclass implied-mixin () ())
(defclass zero-page-mixin () ())
(defclass zero-page-x-mixin (zero-page-mixin) ())
(defclass absolute-mixin () ())
(defclass absolute-x-mixin (absolute-mixin) ())
(defclass absolute-y-mixin (absolute-mixin) ())
(defclass indirect-x-mixin (zero-page-mixin) ())
(defclass indirect-y-mixin (zero-page-mixin) ())
(defun addressing-mode-to-class-name (mode-keyword)
(cadr (assoc mode-keyword
'((:implied implied-mixin)
(:immediate immediate-mixin)
(:zero-page zero-page-mixin)
(:zero-page-x zero-page-x-mixin)
(:zero-page-y zero-page-y-mixin)
(:absolute absolute-mixin)
(:absolute-x absolute-x-mixin)
(:absolute-y absolute-y-mixin)
(:indirect-x indirect-x-mixin)
(:indirect-y indirect-y-mixin)))))
(defclass branching-mixin ()
((%branch-next :accessor branch-next :initarg :branch-next)))
(defmacro define-instruction (mnemonic branching-p &rest modes-and-codes)
(let* ((name (string-upcase mnemonic))
(base-name (intern (format nil "INST-~A" name))))
`(progn
(defclass ,base-name (instruction)
((%mnemonic :allocation :class :initform ',mnemonic)))
,@(loop :for (mode code) :in modes-and-codes
:collect `(defclass ,(intern (format nil "INST-~A-~A"
name mode))
,(append
`(,base-name
,(addressing-mode-to-class-name mode)
complete-mixin)
(when branching-p
'(branching-mixin)))
((%opcode :allocation :class :initform ,code)))))))