home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.uni-stuttgart.de/pub/systems/acorn/
/
Acorn.tar
/
Acorn
/
acornet
/
dev
/
xlisp+
/
xlisp+.spk
/
lsp
/
hdwr
< prev
next >
Wrap
Lisp/Scheme
|
1992-10-02
|
9KB
|
312 lines
; CONVERTED FOR 2.0, but untested.
; -*-Lisp-*-
;
; Jwahar R. Bammi
; A simple description of hardware objects using xlisp
; Mix and match instances of the objects to create your
; organization.
; Needs:
; - busses and connection and the Design
; Class that will have the connections as instance vars.
; - Print method for each object, that will display
; the instance variables in an human readable form.
; Some day I will complete it.
;
;
;
; utility functions
; function to calculate 2^n
(defun pow2 (n)
(pow2x n 1))
(defun pow2x (n sum)
(cond((equal n 0) sum)
(t (pow2x (- n 1) (* sum 2)))))
; hardware objects
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;The class areg
(setq areg (send Class :new '(value nbits max_val min_val)))
; methods
; initialization method
; when a new instance is called for the user supplies
; the parameter nbits, from which the max_val & min_val are derived
(send areg :answer :isnew '(n)
'((send self :init n)
self))
(send areg :answer :init '(n)
'((setq value ())
(setq nbits n)
(setq max_val (- (pow2 (- n 1)) 1))
(setq min_val (- (- 0 max_val) 1))))
; load areg
(send areg :answer :load '(val)
'((cond ((> val max_val) (princ (list "The max value a "nbits" bit register can hold is "max_val"\n")))
((< val min_val) (princ (list "The min value a "nbits" bit register can hold is "min_val"\n")))
(t (setq value val)))))
; see areg
(send areg :answer :see '()
'((cond ((null value) (princ "Register does not contain a value\n"))
(t value))))
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; The class creg ( a register that can be cleared and incremented)
; subclass of a reg
(setq creg (send Class :new '() '() areg))
; it inherites all the instance vars & methods of a reg
; in addition to them it has the following methods
(send creg :answer :isnew '(n)
'((send self :init n)
self))
(send creg :answer :init '(n)
'((setq value ())
(setq nbits n)
(setq max_val (- (pow2 n) 1))
(setq min_val 0)))
(send creg :answer :clr '()
'((setq value 0)))
(send creg :answer :inc '()
'((cond ((null value) (princ "Register does not contain a value\n"))
(t (setq value (rem (+ value 1) (+ max_val 1)))))))
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; Register bank
; contains n areg's n_bits each
(setq reg_bank (send Class :new '(regs n_regs curr_reg)))
;methods
(send reg_bank :answer :isnew '(n n_bits)
'((send self :init n n_bits)
self))
(send reg_bank :answer :init '(n n_bits)
'((setq regs ())
(setq n_regs (- n 1))
(send self :initx n n_bits)))
(send reg_bank :answer :initx '(n n_bits)
'((cond ((equal n 0) t)
(t (list (setq regs (cons (send areg :new n_bits) regs))
(send self :initx (setq n (- n 1)) n_bits))))))
(send reg_bank :answer :load '(reg val)
'((cond((> reg n_regs) (princ (list "Only "(+ 1 n_regs)" registers instantiated\n")))
(t (setq curr_reg (nth (+ reg 1) regs))
(curr_reg :load val)))))
(send reg_bank :answer :see '(reg)
'((cond((> reg n_regs) (princ (list "Only "(+ 1 n_regs)" registers instantiated\n")))
(t (setq curr_reg (nth (+ reg 1) regs))
(curr_reg :see)))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; The Class alu
;alu - an n bit alu
(setq alu (send Class :new '(n_bits maxs_val mins_val maxu_val minu_val nf zf vf cf)))
; methods
(send alu :answer :isnew '(n)
'((send self :init n)
self))
(send alu :answer :init '(n)
'((setq n_bits n)
(setq maxu_val (- (pow2 n) 1))
(setq maxs_val (- (pow2 (- n 1)) 1))
(setq mins_val (- (- 0 maxs_val) 1))
(setq minu_val 0)
(setq nf 0)
(setq zf 0)
(setq vf 0)
(setq cf 0)))
(send alu :answer :check_arith '(a b)
'((cond ((and (send self :arith_range a) (send self :arith_range b)) t)
(t ()))))
(send alu :answer :check_logic '(a b)
'((cond ((and (send self :logic_range a) (send self :logic_range b)) t)
(t ()))))
(send alu :answer :arith_range '(a)
'((cond ((< a mins_val) (princ (list "Operand out of Range "a"\n")))
((> a maxs_val) (princ (list "Operand out of range "a"\n")))
(t t))))
(send alu :answer :logic_range '(a)
'((cond ((< (abs a) minu_val) (princ (list "Operand out of Range "a"\n")))
(t t))))
(send alu :answer :set_flags '(a b r)
'((if (equal 0 r) ((setq zf 1)))
(if (< r 0) ((setq nf 1)))
(if (or (and (and (< a 0) (< 0 b)) (>= r 0))
(and (and (>= a 0) (>= b 0)) (< r 0))) ((setq vf 1)))
(if (or (or (and (< a 0) (< b 0)) (and (< a 0) (>= r 0)))
(and (>= r 0) (< b 0))) ((setq cf 1)))))
(send alu :answer :add '(a b &aux result)
'((cond ((null (send self :check_arith a b)) ())
(t (send self :clear_flags)
(setq result (+ a b))
(if (> result maxs_val) ((setq result (+ (- (rem result maxs_val) 1) mins_val))))
(if (< result mins_val) ((setq result (+ (rem result mins_val) (+ maxs_val 1)))))
(send self :set_flags a b result)
result))))
(send alu :answer :or '(a b &aux result)
'((cond ((null (send self :check_logic a b)) ())
(t (send self :clear_flags)
(setq result (bit-ior a b))
(send self :set_flags a b result)
result))))
(send alu :answer :and '(a b &aux result)
'((cond ((null (send self :check_logic a b)) ())
(t (send self :clear_flags)
(setq result (bit-and a b))
(send self :set_flags a b result)
result))))
(send alu :answer :not '(a &aux result)
'((cond ((null (send self :check_logic a 0)) ())
(t (send self :clear_flags)
(setq result (bit-not a))
(send self :set_flags a 0 result)
result))))
(send alu :answer :subtract '(a b)
'((send self '+ a (- 0 b))))
(send alu :answer :passa '(a)
'(a))
(send alu :answer :zero '()
'(0))
(send alu :answer :com '(a)
'((send self :- 0 a)))
(send alu :answer :status '()
'((princ (list "NF "nf"\n"))
(princ (list "ZF "zf"\n"))
(princ (list "CF "cf"\n"))
(princ (list "VF "vf"\n"))))
(send alu :answer :clear_flags '()
'((setq nf 0)
(setq zf 0)
(setq cf 0)
(setq vf 0)))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; The class Memory
;
(setq memory (send Class :new '(nabits ndbits maxu_val maxs_val mins_val max_addr undef memry)))
; methods
(send memory :answer :isnew '(addr_bits data_bits)
'((send self :init addr_bits data_bits)
self))
(send memory :answer :init '(addr_bits data_bits)
'((setq nabits addr_bits)
(setq ndbits data_bits)
(setq maxu_val (- (pow2 data_bits) 1))
(setq max_addr (- (pow2 addr_bits) 1))
(setq maxs_val (- (pow2 (- data_bits 1)) 1))
(setq mins_val (- 0 (pow2 (- data_bits 1))))
(setq undef (+ maxu_val 1))
(setq memry (array :new max_addr undef))))
(send memory :answer :load '(loc val)
'((cond ((> (abs loc) max_addr) (princ (list "Address "loc" out of range\n")))
((< val 0) (princ (list "Cant store "val" in "ndbits" bits\n")))
((> val maxu_val) (princ (list "Cant store "val" in "ndbits" bits\n")))
(t (memry :load loc val)))))
(send memory :answer :write '(loc val)
'((cond ((> (abs loc) max_addr) (princ (list "Address "loc" out of range\n")))
((> val maxs_val) (princ (list "Cant store "val" in "ndbits" bits\n")))
((< val mins_val) (princ (list "Cant store "val" in "ndbits" bits\n")))
(t (memry :load loc val)))))
(send memory :answer :read '(loc &aux val)
'((cond ((> (abs loc) max_addr) (princ (list "Address "loc" out of range\n")))
(t (setq val (memry :see loc))
(cond ((equal undef val) (princ (list "Address "loc" read before write\n")))
(t val))))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; The class array
(setq array (send Class :new '(arry)))
; methods
(send array :answer :isnew '(n val)
'((send self :init n val)
self))
(send array :answer :init '(n val)
'((cond ((< n 0) t)
(t (setq arry (cons val arry))
(send self :init (- n 1) val)))))
(send array :answer :see '(n)
'((nth (+ n 1) arry)))
(send array :answer :load '(n val &aux left right temp)
'((setq left (send self :left_part n arry temp))
(setq right (send self :right_part n arry))
(setq arry (append left (list val)))
(setq arry (append arry right))
val))
(send array :answer :left_part '(n ary left)
'((cond ((equal n 0) (reverse left))
(t (setq left (cons (car ary) left))
(send self :left_part (- n 1) (cdr ary) left)))))
(send array :answer :right_part '(n ary &aux right)
'((cond ((equal n 0) (cdr ary))
(t (send self :right_part (- n 1) (cdr ary))))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;