;; -*- mode: common-lisp -*- #| clasm-6502: An assembler for the 6502 written in Common Lisp. Copyright (C) 2024 Aleksei Eaves This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |# ;; Rules for the interpretation of lines. (defparameter *syntax-line* '( (label (lambda (l) (and (eq (last-char (first l)) #\:) (eq (length l) 1)))) (label-instruction (lambda (l) (and (eq (last-char (first l)) #\:) (member (read-from-string (second l)) *opcodes*)))) (attribute (lambda (l) (and (equal (char (first l) 0) #\.) (not (equal (first l) ".WORD"))))) (word (lambda (l) (and (equal (char (first l) 0) #\.) (equal (first l) ".WORD")))) (instruction (lambda (l) (member (read-from-string (first l)) *opcodes*))) (macro (lambda (l) (equal (second l) "="))) (unknown (lambda (l) t)))) ;; Rules for identifying addressing modes. (defparameter *syntax-addressing-modes* '((immediate ; #?? (lambda (s) (eq "#" (subseq s 0 1)))) (absolute ;"$????" (lambda (s) (and (equal (length s) 5) (equal "$" (subseq s 0 1)) (hexd? (subseq s 1 5))))) (zero-page ;"$??" (lambda (s) (and (equal (length s) 3) (equal "$" (subseq s 0 1)) (hexd? (subseq s 1 3))))) (implied nil) (indirect-absolute ;($????) (lambda (s) (and (equal (length s) 7) (equal "($" (subseq s 0 2)) (hexd? (subseq s 1 5)) (equal ")" (subseq s 5 6))))) (absolute-indexed-x ;"$????,X" (lambda (s) (and (equal (length s) 7) (equal "$" (subseq s 0 1)) (hexd? (subseq s 1 5)) (equal ",X" (subseq s 5 7))))) (absolute-indexed-y ;"$????,Y" (lambda (s) (and (equal (length s) 7) (equal "$" (subseq s 0 1)) (hexd? (subseq s 1 5)) (equal ",Y" (subseq s 5 7))))) (zero-page-indexed-x ;"$??,X" (lambda (s) (and (equal (length s) 5) (equal (subseq s 0 1) "$") (hexd? (subseq s 1 3)) (equal (subseq s 3 5) ",X")))) (zero-page-indexed-y ;"$??,Y" (lambda (s) (and (equal (length s) 5) (equal (subseq s 0 1) "$") (hexd? (subseq s 1 3)) (equal (subseq s 3 5) ",Y")))) (indexed-indirect ;"($??,X)" (lambda (s) (and (equal (length s) 7) (equal (subseq s 0 2) "($") (hexd? (subseq s 2 4)) (equal (subseq s 4 7) ",X)")))) (indirect-indexed ;"($??),Y" (lambda (s) (and (equal (length s) 7) (equal (subseq s 0 2) "($") (hexd? (subseq s 2 4)) (equal (subseq s 4 7) "),Y")))) ;;How to fix that relative and absolute are the same rule? ;;A check upstream would suffice. (relative ;"$????" (lambda (s) (and (equal (length s) 5) (equal (subseq s 0 1) "$") (hexd? (subseq s 1 5))))) (accumulator ;"A" (lambda (s) (and (equal (length s) 1) (equal "A" (subseq s 0 1))))))) (defun syntax-rule (line list) "Apply a syntax rule against a delimited line from a program." (dolist (i (extract-keys list)) (let ((z (funcall (eval (cadr (assoc i list))) line))) (if (not (equal z nil)) (return i) nil))))