
CHIP-8 in Common Lisp - tosh
http://stevelosh.com/blog/2016/12/chip8-graphics/?m=1
======
flambard
Cool. I made a so called dynamically recompiling (dynarec) CHIP-8 emulator in
Lisp myself, but never got around to implementing the actual graphics, input,
and sound.

[https://github.com/flambard/chip-8-dynarec](https://github.com/flambard/chip-8-dynarec)

Perhaps my project will be completed after all.. :-)

------
veddox
Very interesting read! But could somebody explain why the following piece of
code is needed? And why is it defined inline?

    
    
      (defun-inline (setf vref) (new-value chip x y)
         (setf (aref (chip-video chip) (+ (* +screen-width+ y) x))
            new-value))

~~~
Nokinside
vref and (setf vref) define getter and setter functions for manipulating pixel
arrays. Since these functions are used a lot, it makes sense to allow compiler
to inline them for maximum speed.

Normally function must be accessed trough the symbol and it can be redefined
on the fly.

~~~
veddox
I understand what they do, and I appreciate that it helps performance to
inline them. What I don't understand is the (setf vref) syntax. I thought that
after a defun statement you had to have a symbol, not an S-expression?
Something like so:

    
    
        (defun-inline set-vref (new-value chip x y)
           ...)
    

And how would you actually call the original function to set a pixel? (I'm not
very familiar with inlines, maybe that's my problem here.)

~~~
juki
Common lisp has this universal setter-macro, SETF, which can be used to set
values to all sorts of _places_.

In this case you would use

    
    
        (setf (vref chip x y) new-value)
    

to call the function (just like with AREF above). Using SETF has the advantage
that you can define "modify macros" that read and write a _place_. For
example,

    
    
        (incf (vref chip x y) delta)
    

would increment the place by DELTA. Or

    
    
        (rotatef (vref chip x1 y1)
                 (vref chip x2 y2))
    

would swap two pixels.

------
flavio81
This is one of the coolest things i've ever seen!

It's a rare treat to see low level programming in Common Lisp!!

+100 for Steve Losh!

~~~
PuercoPop
For more low-level Lisp see

[https://github.com/kingcons/cl-6502/blob/master/README.md](https://github.com/kingcons/cl-6502/blob/master/README.md)

And the corresponding book

[http://redlinernotes.com/docs/cl-6502.pdf](http://redlinernotes.com/docs/cl-6502.pdf)

------
0xcde4c3db
> Also note that the program counter starts at address #x200, because that’s
> where the ROM data eventually gets loaded into the CHIP-8 memory.

If I understand correctly, that's because 0-1FF was ROM (including the
interpreter itself) on the original machine, and you typed CHIP-8 programs
into RAM.

~~~
Retr0spectrum
Yes, traditionally the interpreter was located there. However, there is no
"original machine". CHIP-8 was originally designed as a virtual machine for
portability, similar to Java.

[https://en.wikipedia.org/wiki/CHIP-8](https://en.wikipedia.org/wiki/CHIP-8)

~~~
0xcde4c3db
Yes; I mean the machines on which the original interpreter ran, not that
CHIP-8 itself was originally released in a hardware implementation.

------
meitham
So here, Steve Losh, one of the best Vimmers out there, is also an excellent
Lisper! It would be interesting to hear his views on Emacs since he
transitioned to Clojure. I am curious to know whether he uses Vim for
Clojure/Lisp development.

~~~
stevelosh
I moved from Clojure to Common Lisp a few years ago.

I still use (Neo)Vim, using VLIME for Common Lisp interaction:
[https://github.com/l04m33/vlime](https://github.com/l04m33/vlime) It works
great.

~~~
meitham
I missed your response, really hard to see responses in comments on #HN. I'm
now curious why you moved from clojure to CLISP! I thought most people move
the other way around!

