% Created 2020-11-24 Tue 18:27 % Intended LaTeX compiler: pdflatex \documentclass[presentation]{beamer} \usepackage[utf8]{inputenc} \usepackage[T1]{fontenc} \usepackage{graphicx} \usepackage{grffile} \usepackage{longtable} \usepackage{wrapfig} \usepackage{rotating} \usepackage[normalem]{ulem} \usepackage{amsmath} \usepackage{textcomp} \usepackage{amssymb} \usepackage{capt-of} \usepackage{hyperref} \usepackage{tabu} \usepackage{minted} \usepackage[english]{babel} \hypersetup{pdfauthor="Vasilij Schneidermann", pdftitle="State of Retro Gaming in Emacs", colorlinks, linkcolor=, urlcolor=blue} \setminted{fontsize=\footnotesize,escapeinside=||} \usetheme{Rochester} \usecolortheme[RGB={87,83,170}]{structure} \author{Vasilij Schneidermann} \date{November 2020} \title{State of Retro Gaming in Emacs} \hypersetup{ pdfauthor={Vasilij Schneidermann}, pdftitle={State of Retro Gaming in Emacs}, pdfkeywords={}, pdfsubject={}, pdfcreator={Emacs 27.1 (Org mode 9.3)}, pdflang={English}} \begin{document} \maketitle \begin{frame}{Outline} \tableofcontents \end{frame} \AtBeginSection{\frame{\sectionpage}} \section{Intro} \label{sec:org8029e79} \begin{frame}[label={sec:org3aeaf07}]{About} \begin{itemize} \item Vasilij Schneidermann, 28 \item Cyber security consultant at msg systems \item mail@vasilij.de \item \url{https://depp.brause.cc/} \item \url{http://emacsninja.com/} \end{itemize} \end{frame} \begin{frame}[label={sec:org48e6e2a}]{Motivation} \begin{itemize} \item Emacs is the ultimate procrastination machine \item Many fun demonstrations: \begin{itemize} \item Order salad online \item Window manager \item IRC bot \item Textual web browser \item Basic games \item 3D maze \item Z-Machine emulator \item Audio/video editor \item Sex toy controller \end{itemize} \item Can we emulate retro games at 60 FPS? \end{itemize} \end{frame} \begin{frame}[label={sec:org6b51754}]{Meet chip8.el} \begin{itemize} \item \url{https://depp.brause.cc/chip8.el} \item Pretty much finished, <1000SLOC \item Supports Super CHIP-8 extensions \item Runs at full speed, games behave OK \end{itemize} \end{frame} \section{Fun facts about \texttt{chip8.el}} \label{sec:org90942bc} \begin{frame}[label={sec:org13cd1a8}]{What the hell is a CHIP-8 anyway?} \begin{itemize} \item It's a VM, not a console \item Designed for easy porting of home computer games \item Not terribly successful \item Small community of enthusiasts writing games for it \item There are even a few demos! \end{itemize} \end{frame} \begin{frame}[label={sec:orgda90987}]{System specs} \begin{itemize} \item CPU: 8-Bit, 16 registers, 36 fixed-size instructions \item RAM: 4KB \item Stack: 16 return addresses \item Resolution: 64 x 32 black/white pixels \item Rendering: Sprites are drawn in XOR mode \item Sound: Monotone buzzer \item Input: Hexadecimal keypad \end{itemize} \end{frame} \begin{frame}[label={sec:org01cd8ba},fragile]{How does it work?} \begin{itemize} \item Runs at an unspecified speed \item Sound and delay timer count down at 60FPS \item Game is loaded up at \texttt{\#x200} into RAM \item Program counter is set to \texttt{\#x200} \item Decode instruction, execute, loop \end{itemize} \end{frame} \begin{frame}[label={sec:orgee1af96}]{Game loop woes} \begin{itemize} \item Game approach: Do stuff, wait, repeat \item Doesn't work well in Emacs due to user input \item Interruptible sleep: Unpredictable \item Un-interruptable sleep: Freezes \item Timers: Inversion of control, allows user input to happen \item Call a timer function at 60FPS, don't do too much in it: \begin{itemize} \item Execute CPU cycle(s) \item Decrement sound/delay registers \item Repaint \end{itemize} \end{itemize} \end{frame} \begin{frame}[label={sec:orgc75970d}]{Mapping the system to Emacs Lisp} \begin{itemize} \item It's all integers and vectors (of integers) \item RAM, registers, return stack, key state, screen, etc. \item Stored in global variables \item No lists are used at all \item Side effect: No consing happens, no GC pauses \end{itemize} \end{frame} \begin{frame}[label={sec:org74f2134},fragile]{Decoding instructions} \begin{itemize} \item All instructions are two bytes \item Arguments are encoded inside them \item \texttt{JP nnn} for example maps to \texttt{\#x1nnn} \item Type extracted by masking with \texttt{\#xF000}, then shifting by 12 bits \item Argument by masking with \texttt{\#x0FFF} (no shift needed) \item Common patterns emerge, like addresses being the last three nibbles \item Big \texttt{cond} dispatching on the type and executing side effects \end{itemize} \end{frame} \begin{frame}[label={sec:org0a9a84e},fragile]{Testing} \begin{itemize} \item Initially: Execute ROM until user hits \texttt{C-g} \item Use debug command to render screen to a buffer \item Initial test with tiny ROMs that just display a static screen \item I added instructions as needed, went through more of them \item Later I wrote a unit test suite as safety net \item Each test initializes the VM, loads up code, executes the \texttt{chip8-cycle} function, checks for side effects \end{itemize} \end{frame} \begin{frame}[label={sec:org0478e31}]{Debugging} \begin{itemize} \item My usual approach of using edebug was ineffective \item Therefore: Logging it is \item I compared my log output with an instrumented version of this emulator: \url{https://git.foldling.org/chick-8.git} \item If the logs diverge, that's where the bug lies \item Future project idea: A CHIP-8 debugger \end{itemize} \end{frame} \begin{frame}[label={sec:org3e4b935}]{Analysis} \begin{itemize} \item Writing a disassembler is simple, but tedious \item Adding analysis functionality is particularly tricky \item Idea: Reuse radare2 framework, add analysis/disasm plugin \item I wrote one in Python, then discovered there is one in core\ldots{} \item I then improved that one to the same level \end{itemize} \end{frame} \begin{frame}[label={sec:org6d457ad}]{Rendering} \begin{itemize} \item By far the trickiest part \item I intentionally decided against using a library \item Creating SVGs: Too expensive \item Creating/mutating strings: Too expensive or complicated \item Changing SVG tiles: Gaps between lines \item Bool vector backed XPM: Caching effects ruin everything \item Plain text with background color: Perfect \item Many optimization attempts until I got there \end{itemize} \end{frame} \begin{frame}[label={sec:orga2b9db8},fragile]{Sound} \begin{itemize} \item You only need a beep, so no difficulties emulating it \item Playing it is hard because Emacs only supports synchronous playback\ldots{} \item Emacs processes are asynchronous, so controlling one works \item \texttt{mplayer} has a slave mode, \texttt{mpv} supports listening on a FIFO for commands \item Proof of concept: \begin{itemize} \item Start paused \texttt{mpv} with a FIFO in loop mode \item Send pause/unpause command to the FIFO \end{itemize} \end{itemize} \end{frame} \section{Outro} \label{sec:org9a4dd86} \begin{frame}[label={sec:org063f42c}]{What next?} \begin{itemize} \item Maybe an Intel 8080 emulator running CP/M \item Maybe experimentation with faster rendering \item More serious stuff in CHICKEN, like NES or GB emulator \end{itemize} \end{frame} \begin{frame}[label={sec:org2679de4}]{Questions?} \end{frame} \end{document}