add -raw mode for vm.scm
This commit is contained in:
parent
e63f77f98e
commit
1debdb2ba8
95
vm.scm
95
vm.scm
|
@ -7,15 +7,18 @@
|
|||
;; === implementation-dependent functions; uncomment one stanza
|
||||
|
||||
;; chicken scheme
|
||||
(import (chicken bitwise) (chicken process-context) (chicken time posix))
|
||||
(define (get-u8 port)
|
||||
(let ((c (read-char port))) (if (eof-object? c) c (char->integer c))))
|
||||
(import (chicken bitwise))
|
||||
(import (chicken file))
|
||||
(import (chicken process))
|
||||
(import (chicken process-context))
|
||||
(import (chicken time posix))
|
||||
(import (chicken io))
|
||||
(define (get-u8 port) (read-byte port))
|
||||
(define (open-rom path) (open-input-file path #:binary))
|
||||
(define (get-date-time)
|
||||
(let* ((v (seconds->local-time))
|
||||
(y (vector-ref v 5)))
|
||||
(vector-set! v 5 (+ y 1900))
|
||||
v))
|
||||
(vector-set! v 5 (+ y 1900)) v))
|
||||
|
||||
;; ;; guile, invoke with guile vm.scm ROM ...
|
||||
;; (use-modules (srfi srfi-60) (ice-9 binary-ports))
|
||||
|
@ -69,6 +72,8 @@
|
|||
(define rst (cons 0 (make-vector 256 0)))
|
||||
(define pc 256)
|
||||
(define done #f)
|
||||
(define raw-tty #f)
|
||||
(define saved-tty '())
|
||||
|
||||
;; instruction modes
|
||||
(define _2 #f)
|
||||
|
@ -245,8 +250,8 @@
|
|||
((= 4 port) (set-car! wst byte))
|
||||
((= 5 port) (set-car! rst byte))
|
||||
((= 14 port) (u:debug))
|
||||
((= 24 port) (write-char (integer->char byte) (current-output-port)))
|
||||
((= 25 port) (write-char (integer->char byte) (current-error-port)))
|
||||
((= 24 port) (write-byte byte (current-output-port)))
|
||||
((= 25 port) (write-byte byte (current-error-port)))
|
||||
(* '())))
|
||||
|
||||
(define (u:debug)
|
||||
|
@ -345,26 +350,28 @@
|
|||
(fn)
|
||||
(u:eval))))
|
||||
|
||||
(define (u:exit n) (u:restore-tty) (exit n))
|
||||
|
||||
(define (u:run addr)
|
||||
(set! done #f)
|
||||
(set! pc addr)
|
||||
(u:eval)
|
||||
(let ((n (vector-ref dev 15)))
|
||||
(if (= n 0) '()
|
||||
(exit (bitwise-and n 127)))))
|
||||
(u:exit (bitwise-and n 127)))))
|
||||
|
||||
(define (u:read-args args)
|
||||
(if (null? args)
|
||||
(u:send-input #\newline 4)
|
||||
(u:send-input 10 4)
|
||||
(begin
|
||||
(u:read-arg (string->list (car args)))
|
||||
(if (null? (cdr args)) '() (u:send-input #\newline 3))
|
||||
(if (null? (cdr args)) '() (u:send-input 10 3))
|
||||
(u:read-args (cdr args)))))
|
||||
|
||||
(define (u:read-arg chars)
|
||||
(if (null? chars) '()
|
||||
(begin
|
||||
(u:send-input (car chars) 2)
|
||||
(u:send-input (char->integer (car chars)) 2)
|
||||
(u:read-arg (cdr chars)))))
|
||||
|
||||
;; send a character of console input with type
|
||||
|
@ -373,22 +380,22 @@
|
|||
;; - 2 argument data
|
||||
;; - 3 spacer between arguments
|
||||
;; - 4 spacer after arguments, or end of stdin
|
||||
(define (u:send-input c type)
|
||||
(define (u:send-input n type)
|
||||
(let* ((hi (vector-ref dev 16))
|
||||
(lo (vector-ref dev 17))
|
||||
(addr (hilo->u16 hi lo)))
|
||||
(if (= 0 addr) '()
|
||||
(begin
|
||||
(vector-set! dev 18 (u8 (char->integer c)))
|
||||
(vector-set! dev 18 (u8 n))
|
||||
(vector-set! dev 23 (u8 type))
|
||||
(u:run addr)))))
|
||||
|
||||
(define (u:read-stdin port)
|
||||
(let ((c (read-char port)))
|
||||
(if (eof-object? c)
|
||||
(u:send-input #\newline 4)
|
||||
(let ((byte (read-byte port)))
|
||||
(if (eof-object? byte)
|
||||
(u:send-input 10 4)
|
||||
(begin
|
||||
(u:send-input c 1)
|
||||
(u:send-input byte 1)
|
||||
(u:read-stdin port)))))
|
||||
|
||||
;; load a ROM from a file, byte-by-byte
|
||||
|
@ -399,16 +406,44 @@
|
|||
(begin (vector-set! mem addr (u8 byte))
|
||||
(u:load-rom rom (+ addr 1))))))
|
||||
|
||||
(let ((prog-args (command-line-arguments)))
|
||||
(if (null? prog-args)
|
||||
(begin (display "usage: ./vm ROM [ARGS...]\n") (exit))
|
||||
(let* ((rom-path (car prog-args))
|
||||
(rom-args (cdr prog-args))
|
||||
(rom (open-rom rom-path))
|
||||
(start 256))
|
||||
(vector-set! dev 23 (if (null? rom-args) 0 1))
|
||||
(u:load-rom rom start)
|
||||
(u:run start)
|
||||
(if (null? rom-args) '() (u:read-args rom-args))
|
||||
(u:read-stdin (current-input-port))
|
||||
(exit 0))))
|
||||
(define (u:read-cmd cmd)
|
||||
(with-input-from-pipe cmd (lambda () (read-string #f (current-input-port)))))
|
||||
|
||||
(define (u:usage)
|
||||
(display "usage: ./vm [-raw] ROM [ARGS...]\n")
|
||||
(exit))
|
||||
|
||||
(define (u:parse-args args)
|
||||
(if (null? args) (u:usage))
|
||||
(if (equal? (car args) "-raw")
|
||||
(begin (set! raw-tty #t)
|
||||
(u:parse-args (cdr args)))
|
||||
args))
|
||||
|
||||
(define (u:check-rom path)
|
||||
(if (and (file-exists? path) (file-readable? path)) '()
|
||||
(begin (display "ERROR: cannot open ROM '")
|
||||
(display path)
|
||||
(display "'\n")
|
||||
(u:usage))))
|
||||
|
||||
(define (u:set-tty)
|
||||
(if raw-tty (begin (set! saved-tty (u:read-cmd "stty -g"))
|
||||
(system* "stty raw -echo"))))
|
||||
|
||||
(define (u:restore-tty)
|
||||
(if raw-tty (system* (string-append "stty " saved-tty))))
|
||||
|
||||
(let* ((prog-args (u:parse-args (command-line-arguments)))
|
||||
(_ (u:set-tty))
|
||||
(rom-path (car prog-args))
|
||||
(rom-args (cdr prog-args))
|
||||
(_ (u:check-rom rom-path))
|
||||
(rom (open-rom rom-path))
|
||||
(start 256))
|
||||
(vector-set! dev 23 (if (null? rom-args) 0 1))
|
||||
(u:load-rom rom start)
|
||||
(u:run start)
|
||||
(if (null? rom-args) '() (u:read-args rom-args))
|
||||
(u:read-stdin (current-input-port))
|
||||
(u:exit 0))
|
||||
|
|
Loading…
Reference in New Issue