diff options
-rw-r--r-- | 6502.lisp | 42 | ||||
-rw-r--r-- | grammar.lisp | 100 | ||||
-rw-r--r-- | macro.lisp | 65 | ||||
-rw-r--r-- | main.lisp | 43 |
4 files changed, 173 insertions, 77 deletions
@@ -18,26 +18,26 @@ License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |# -;;; List of addressing modes. -(setf +;;; List of addressing modes and their length. +(defparameter *addressing-modes* - '(immediate - absolute - zero-page - implied - indirect-absolute - absolute-indexed-x - absolute-indexed-y - zero-page-indexed-x - zero-page-indexed-y - indexed-indirect - indirect-indexed - relative - accumulator)) + '((immediate 2) + (absolute 3) + (zero-page 2) + (implied 1) + (indirect-absolute 3) + (absolute-indexed-x 3) + (absolute-indexed-y 3) + (zero-page-indexed-x 2) + (zero-page-indexed-y 2) + (indexed-indirect 2) + (indirect-indexed 2) + (relative 2) + (accumulator 1))) ;;; Instructions, with decimal opcode and ;;; addressing modes. -(setf +(defparameter *instructions* ;; Load & Store '((LDA 169 (immediate @@ -214,9 +214,9 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA (caddr (assoc instruction *instructions*))) t) (t nil))) -;; A list with with the respective rules of some +;; A list with with the respective rules of ;; addressing mode syntax. -(setf +(defparameter *addressing-modes-syntax* '((immediate ; #?? ... more complex syntax rules for later (lambda (s) @@ -296,9 +296,3 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA (and (equal (length s) 1) (equal "A" (subseq s 0 1))))))) - -;; Evaluate the second syntax rule on a string -;; temporary -(funcall - (eval (cadr (assoc 'absolute *addressing-modes-syntax*))) - "$A6AF") diff --git a/grammar.lisp b/grammar.lisp index d91317f..f0c0e10 100644 --- a/grammar.lisp +++ b/grammar.lisp @@ -18,9 +18,9 @@ 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 interpreting the purpose of some line. -(setf - *grammar* +;; Rules for the interpretation of lines. +(defparameter + *line-syntax* '( (label (lambda (l) @@ -43,6 +43,87 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA (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." @@ -53,16 +134,3 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA z nil)) (return i) nil)))) - - -(syntax-rule '("LABEL:" "LDA" "$05") *grammar*) - -(syntax-rule '("LDA" "$05") *grammar*) - -(syntax-rule '("AS" "=" "THAT") *grammar*) - -(syntax-rule '("LABEL:") *grammar*) - -(syntax-rule '("hhhh") *grammar*) - -(syntax-rule '(".org" "$FF00") *grammar*) diff --git a/macro.lisp b/macro.lisp new file mode 100644 index 0000000..39070ab --- /dev/null +++ b/macro.lisp @@ -0,0 +1,65 @@ +;; -*- 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 +|# + +#| +To solve the problem of the colliding syntax rules +We can test only the addressin modes we know the opcode to have +This not only solves this problem, it just makes more sense. + +Need to use the existing lists to find keywords to watch out for during compilation. +ESPECIALLY run through the output of macro-list to find collisions +This owuld make it simple +|# + +(defun macro-pass (program-list) + "Translate a programs macros" + (let ((macro-association-list + (let ((return-alist nil)) + (dolist (i program-list) + (if (equal (syntax-rule (cadr i) *line-syntax*) 'macro) + (setf return-alist + (cons (list (first (cadr i)) (car (last (cadr i)))) + return-alist)) + nil)) + return-alist)) + (return-list nil)) + ;; For every line in program list.. + (dolist (i program-list) + ;; ..excluding the macro lines.. + (if (eq (syntax-rule (cadr i) *line-syntax*) 'macro) + nil + ;; ..add to return list this value: + (setf return-list + (cons + ;; For every word in the line, + (let ((append-list nil)) + (dolist (j (cadr i)) + (setf append-list + ;; add it to the output line, and change whatever is a macro. + (cons (if (assoc j macro-association-list :test #'string=) + (cadr (assoc j macro-association-list :test #'string=)) + j) + append-list))) + ;; Return the line number and program. + (cons (car i) + (list (reverse append-list)))) + return-list)))) + ;; Return everything. + (reverse return-list))) @@ -28,41 +28,10 @@ ESPECIALLY run through the output of macro-list to find collisions This owuld make it simple |# -(setf *the-program* - (program "~/clasm-6502/wozmon.s")) +(load "~/clasm-6502/utilities.lisp") + +(load "~/clasm-6502/6502.lisp") + +(load "~/calsm-6502/grammar.lisp") + -(defun macro-pass (program-list) - "Translate a programs macros" - (let ((macro-association-list - (let ((return-alist nil)) - (dolist (i program-list) - (if (equal (syntax-rule (cadr i) *grammar*) 'macro) - (setf return-alist - (cons (list (first (cadr i)) (car (last (cadr i)))) - return-alist)) - nil)) - return-alist)) - (return-list nil)) - ;; For every line in program list.. - (dolist (i program-list) - ;; ..excluding the macro lines.. - (if (eq (syntax-rule (cadr i) *grammar*) 'macro) - nil - ;; ..add to return list this value: - (setf return-list - (cons - ;; For every word in the line, - (let ((append-list nil)) - (dolist (j (cadr i)) - (setf append-list - ;; add it to the output line, and change whatever is a macro. - (cons (if (assoc j macro-association-list :test #'string=) - (cadr (assoc j macro-association-list :test #'string=)) - j) - append-list))) - ;; Return the line number and program. - (cons (car i) - (list (reverse append-list)))) - return-list)))) - ;; Return everything. - (reverse return-list))) |