summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--6502.lisp42
-rw-r--r--grammar.lisp100
-rw-r--r--macro.lisp65
-rw-r--r--main.lisp43
4 files changed, 173 insertions, 77 deletions
diff --git a/6502.lisp b/6502.lisp
index 32d67ba..1115a21 100644
--- a/6502.lisp
+++ b/6502.lisp
@@ -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)))
diff --git a/main.lisp b/main.lisp
index a1acca6..ccc059a 100644
--- a/main.lisp
+++ b/main.lisp
@@ -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)))