diff options
-rw-r--r-- | 6502.lisp | 2 | ||||
-rw-r--r-- | attributes.lisp | 39 | ||||
-rw-r--r-- | macro.lisp | 2 | ||||
-rw-r--r-- | main.lisp | 14 | ||||
-rw-r--r-- | syntax.lisp | 141 |
5 files changed, 195 insertions, 3 deletions
@@ -40,7 +40,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ;; Generated list of addressing modes. (defparameter *addressing-modes* - (extract-keys *addressing-modes-lengths*)) + (extract-keys *addressing-mode-lengths*)) ;;; Instructions, with decimal opcode and ;;; addressing modes. diff --git a/attributes.lisp b/attributes.lisp new file mode 100644 index 0000000..9cfc6b7 --- /dev/null +++ b/attributes.lisp @@ -0,0 +1,39 @@ +;; -*- 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 +|# + +(defun attributes-list (program-list) + "Grab a progams attributes." + (let ((get-attribute-list nil)) + (dolist (i program-list) + (if (eq (syntax-rule (cadr i) *line-syntax*) 'attribute) + (setf get-attribute-list + (cons (cadr i) + get-attribute-list)))) + get-attribute-list)) + +(defun attributes-remove (program-list) + "Remove a progams attributes." + (let ((return-list nil)) + (dolist (i program-list) + (if (not (eq (syntax-rule (cadr i) *line-syntax*) 'attribute)) + (setf return-list + (cons i + return-list)))) + (reverse return-list))) @@ -29,7 +29,7 @@ This owuld make it simple |# (defun macro-pass (program-list) - "Translate a programs macros" + "Translate a programs macros." (let ((macro-association-list (let ((return-alist nil)) (dolist (i program-list) @@ -28,10 +28,22 @@ ESPECIALLY run through the output of macro-list to find collisions This owuld make it simple |# +;; Utility functions used in all other files. (load "~/clasm-6502/utilities.lisp") +;; Data related to the CPU (load "~/clasm-6502/6502.lisp") -(load "~/calsm-6502/grammar.lisp") +;; Syntax rules +(load "~/clasm-6502/syntax.lisp") +;; Parse the source file into a list. +(load "~/clasm-6502/parse-source.lisp") +;; Process the program list macros. +(load "~/clasm-6502/macro.lisp") + +;; Process the program list attributes +(load "~/clasm-6502/attributes.lisp") + +(load "~/clasm-6502/labels.lisp") diff --git a/syntax.lisp b/syntax.lisp new file mode 100644 index 0000000..982397a --- /dev/null +++ b/syntax.lisp @@ -0,0 +1,141 @@ +;; -*- 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 + *line-syntax* + '( + (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 + *addressing-modes-syntax* + '((immediate ; #?? ... more complex syntax rules for later + (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)))) |