summaryrefslogblamecommitdiffstats
path: root/2020/subtitles/emacsconf-2020--27-state-of-retro-gaming-in-emacs-chip8--vasilij-wasamasa-schneidermann-autogen.sbv
blob: c88c3dedafa771bec8ce0eb1295a8435f46d362a (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11
12
13



                                     
                              







                                      
                                   

                       
                                     













                                        
                                       




                            
                               







                                        
                                      

                       
                                




                                     
                                       

























                                        
                                       













                                     
                                        





































                                       
                                

                       
                                       




                                
                               










                                        
                  












































































































































































                                        
                                        





































                                        
                                       




                       
                                        













                                     
               







                                      
                                       



















                                        
                                   



















                                       
                           






















                                        
                                      



































































                                        
                                       

                       
                          







                                     
                                    










                                       
                                       




                                       
                                     



















                                        
                                       
















                                       
                                 

                       
                           

                       
                                   







                                        
                                    










                                        
                              

                       
                                   



















                                        
                                       










                                   
                                     




                                
                                    










                                        
                                        



















                                        
                                      
















                                       
                                      




                                    
                                   







                                      
                                        













                                    
                                      
















                                        
                            

                       
                                 

                       
                                      













                                        
                                        













                                       
                                  







                                 
                                        







                                      
                                        










                                      
                                       




                       
                                    

                       
                             










                                       
                                




                            
                                      




                       
                                    
















                                       
                                 




                       
                                     

                       
                                      












                                       
0:00:00.880,0:00:04.520
hello everyone and welcome to my talk

0:00:02.879,0:00:06.960
state of retrogaming and Emacs

0:00:04.520,0:00:08.639
[Music]

0:00:06.960,0:00:12.000
first of all a little bit about myself

0:00:08.639,0:00:13.599
my name is neilman I'm 28 years old

0:00:12.000,0:00:15.200
I work as a cyber security consultant

0:00:13.599,0:00:17.440
msg systems and

0:00:15.200,0:00:19.359
test other people's web applications and

0:00:17.440,0:00:20.160
review the source code for security

0:00:19.359,0:00:22.960
problems

0:00:20.160,0:00:25.039
you can reach me by email I have my own

0:00:22.960,0:00:26.480
self-hosted git repositories

0:00:25.039,0:00:28.480
and I have a blog where you can

0:00:26.480,0:00:32.160
occasionally find new posts by me on all

0:00:28.480,0:00:34.800
kinds of things not just emix things

0:00:32.160,0:00:36.480
so but the motivation about this one I

0:00:34.800,0:00:38.079
found that Emacs is the ultimate

0:00:36.480,0:00:40.160
procrastination machine and there are

0:00:38.079,0:00:41.200
lots of fun demonstrations I'll go over

0:00:40.160,0:00:44.160
a few of them

0:00:41.200,0:00:46.079
for example someone made a thing to

0:00:44.160,0:00:48.239
order sell it for himself online so it

0:00:46.079,0:00:50.879
doesn't have to walk over to the shop

0:00:48.239,0:00:51.760
there's plenty rc bots there's some game

0:00:50.879,0:00:53.520
things

0:00:51.760,0:00:55.600
there's an emulator for the z machine

0:00:53.520,0:00:57.600
which you can use to play zorg

0:00:55.600,0:00:59.039
and so I asked myself at this point can

0:00:57.600,0:01:01.039
you actually emulate retro games at

0:00:59.039,0:01:02.800
60fps and it looked around a bit

0:01:01.039,0:01:04.479
and found some projects but none that

0:01:02.800,0:01:07.360
were actually able to

0:01:04.479,0:01:08.000
do it at 60fps so I set out to do my own

0:01:07.360,0:01:09.439
one

0:01:08.000,0:01:11.119
and looked out for a console that you

0:01:09.439,0:01:13.439
can actually emulate at that speed

0:01:11.119,0:01:14.690
using emax with its very very limited

0:01:13.439,0:01:16.320
rendering

0:01:14.690,0:01:19.520
[Music]

0:01:16.320,0:01:20.560
and here's the project chip8.el it's

0:01:19.520,0:01:22.880
pretty much finished

0:01:20.560,0:01:24.000
it clocks into under 1000 sourced lines

0:01:22.880,0:01:26.159
of code

0:01:24.000,0:01:28.080
it supports the superchip 8 extensions

0:01:26.159,0:01:30.159
it runs at full speed all games behave

0:01:28.080,0:01:32.320
okay as far as I'm concerned and

0:01:30.159,0:01:34.479
yeah I'm pretty happy with it it's very

0:01:32.320,0:01:37.040
much the hell world of emulation

0:01:34.479,0:01:40.880
and I might maybe do some other

0:01:37.040,0:01:43.360
emulation projects in the future

0:01:40.880,0:01:45.439
now for the section which is the longest

0:01:43.360,0:01:46.320
bunch of fun facts about ship a dot el

0:01:45.439,0:01:49.759
which I've learned

0:01:46.320,0:01:52.240
during this project so

0:01:49.759,0:01:54.640
what the hell is debate anyway first of

0:01:52.240,0:01:56.799
all unlike many other emulation game

0:01:54.640,0:01:58.560
things it's not a console but a vm

0:01:56.799,0:02:00.000
it was designed for easy parting of home

0:01:58.560,0:02:02.560
computer games

0:02:00.000,0:02:03.680
it wasn't terribly successful and but

0:02:02.560,0:02:04.320
there's still a small community of

0:02:03.680,0:02:06.079
enthusiasts

0:02:04.320,0:02:09.119
writing games for it and there are even

0:02:06.079,0:02:11.920
a few demos

0:02:09.119,0:02:14.720
this vm has system specs it has a very

0:02:11.920,0:02:14.959
very simple 8-bit cpu with 16 registers

0:02:14.720,0:02:17.760
and

0:02:14.959,0:02:18.160
36 fixed size instructions you have a

0:02:17.760,0:02:20.560
whole

0:02:18.160,0:02:22.080
4 kilobyte of ram you have a stack with

0:02:20.560,0:02:24.480
16 return addresses

0:02:22.080,0:02:25.760
the resolution is 64 by 32 black white

0:02:24.480,0:02:28.000
pixels

0:02:25.760,0:02:29.440
rendering is done by drawing sprites

0:02:28.000,0:02:30.160
these are drawn in excel mode meaning

0:02:29.440,0:02:32.239
that if you

0:02:30.160,0:02:33.840
draw a sprite and set a bit it just

0:02:32.239,0:02:35.040
flips over from black to white or white

0:02:33.840,0:02:36.560
to black

0:02:35.040,0:02:38.239
first one you have a modern buzz that

0:02:36.560,0:02:40.640
can just beep at one

0:02:38.239,0:02:43.120
frequency and most unusually there's a

0:02:40.640,0:02:45.360
hexadecimal keypad as input

0:02:43.120,0:02:48.160
so the keys are basically zero to nine

0:02:45.360,0:02:48.160
and a to f

0:02:48.480,0:02:52.400
so how does this whole thing work it

0:02:50.879,0:02:53.599
runs an unspecified speed

0:02:52.400,0:02:54.879
you'll probably have to do some fine

0:02:53.599,0:02:56.080
tune you find the speed you're happy

0:02:54.879,0:02:58.560
with

0:02:56.080,0:03:01.120
sound and delay timers exist they count

0:02:58.560,0:03:02.879
down at 60fps down to zero

0:03:01.120,0:03:05.120
this is done so that you can play a

0:03:02.879,0:03:06.640
sound at some specific time

0:03:05.120,0:03:08.640
the game itself is loaded with a fixed

0:03:06.640,0:03:10.480
offset into ram the program account is

0:03:08.640,0:03:11.920
set to exactly that offset

0:03:10.480,0:03:13.840
and from there it enters the game loop

0:03:11.920,0:03:15.519
where decodes and instruction executes

0:03:13.840,0:03:18.130
it for the side effects and just

0:03:15.519,0:03:19.599
loops and does this at infinitum

0:03:18.130,0:03:21.920
[Music]

0:03:19.599,0:03:23.920
so the game was the first thing where

0:03:21.920,0:03:24.239
into problems the usual game approach is

0:03:23.920,0:03:26.640
to

0:03:24.239,0:03:28.239
do stuff figure out how long to eight

0:03:26.640,0:03:30.640
wait for exactly that much and

0:03:28.239,0:03:31.680
repeat this doesn't work well in imax at

0:03:30.640,0:03:34.959
all because well

0:03:31.680,0:03:37.280
user input basically and

0:03:34.959,0:03:39.040
Emacs is designed to just do whatever it

0:03:37.280,0:03:40.080
needs to do whenever you enter use input

0:03:39.040,0:03:42.799
instead of

0:03:40.080,0:03:43.440
doing things at one specific time if you

0:03:42.799,0:03:45.040
try to do

0:03:43.440,0:03:46.640
interruptable sleep well you get

0:03:45.040,0:03:49.440
unpredictable behavior

0:03:46.640,0:03:50.959
for example can be the timer doesn't run

0:03:49.440,0:03:52.560
at all at next time because you've

0:03:50.959,0:03:54.400
accidentally cancelled it

0:03:52.560,0:03:55.760
if you do uninterruptable sleep it's

0:03:54.400,0:03:56.720
freezes instead which isn't what you

0:03:55.760,0:03:59.360
want either

0:03:56.720,0:04:00.560
so I went for timers which forced me to

0:03:59.360,0:04:02.159
do inversion of control

0:04:00.560,0:04:04.080
meaning that I have to write code in the

0:04:02.159,0:04:06.159
style where it's just call it

0:04:04.080,0:04:07.200
time and this allows this input to

0:04:06.159,0:04:09.120
happen and to

0:04:07.200,0:04:11.040
for things to progress at roughly the

0:04:09.120,0:04:12.879
speed I want to

0:04:11.040,0:04:14.159
so there's the skydiver function which

0:04:12.879,0:04:16.000
is called a 60fps

0:04:14.159,0:04:17.359
and I have to be very careful to not do

0:04:16.000,0:04:20.479
too much in it

0:04:17.359,0:04:22.960
and say this function execute cpu cycles

0:04:20.479,0:04:23.680
decrypt the sound delay registers and

0:04:22.960,0:04:27.759
redraw

0:04:23.680,0:04:28.800
the screen so to map this whole system

0:04:27.759,0:04:31.199
to mx lisp

0:04:28.800,0:04:33.120
I've used just integers and vectors

0:04:31.199,0:04:35.040
which contain even more integers

0:04:33.120,0:04:37.759
this is used for the ram registers

0:04:35.040,0:04:39.120
return stack key state screen and so on

0:04:37.759,0:04:41.520
and so forth basically

0:04:39.120,0:04:42.800
what you would do if you were writing c

0:04:41.520,0:04:44.560
all of this is stored in global

0:04:42.800,0:04:46.479
variables I'm not using any

0:04:44.560,0:04:48.400
lists at all and as a side effect

0:04:46.479,0:04:50.320
there's no constant going on at all

0:04:48.400,0:04:51.120
there are no extra objects created which

0:04:50.320,0:04:53.919
would trigger

0:04:51.120,0:04:55.840
garbage collection pulses this getting

0:04:53.919,0:04:56.720
this red was rather tricky actually and

0:04:55.840,0:04:58.560
there were some

0:04:56.720,0:05:01.680
in garbage collection problems which I

0:04:58.560,0:05:01.680
had to resolve over time

0:05:01.759,0:05:05.520
so the coding instructions for this you

0:05:04.320,0:05:06.800
have to know that all instructions are

0:05:05.520,0:05:08.880
two bytes long

0:05:06.800,0:05:10.240
and the arguments encoded inside them

0:05:08.880,0:05:11.440
for example the jump to address

0:05:10.240,0:05:15.120
instruction

0:05:11.440,0:05:18.400
is encoded as one and three hex digits

0:05:15.120,0:05:20.800
the type is extracted masking with f000

0:05:18.400,0:05:21.680
and then shifting it by 12 bits mask

0:05:20.800,0:05:24.000
means the hd

0:05:21.680,0:05:25.440
performance binary end you can do the

0:05:24.000,0:05:26.639
same with the argument basement with

0:05:25.440,0:05:29.520
zero fff

0:05:26.639,0:05:31.039
and no shift if you do this long enough

0:05:29.520,0:05:32.639
you'll find common patterns for example

0:05:31.039,0:05:35.280
addresses are always encoded like this

0:05:32.639,0:05:36.880
using the last three nibbles in the code

0:05:35.280,0:05:38.400
you'll find a big count which dispatches

0:05:36.880,0:05:40.070
on the type and executes it for the side

0:05:38.400,0:05:41.440
effects

0:05:40.070,0:05:43.440
[Music]

0:05:41.440,0:05:45.919
for testing I've initially just accused

0:05:43.440,0:05:47.280
the rom until I fit ctrl g

0:05:45.919,0:05:49.039
and then use the debug command to run

0:05:47.280,0:05:51.360
the screen to a buffer

0:05:49.039,0:05:52.320
later on I found tiny roms that just

0:05:51.360,0:05:55.680
display a static

0:05:52.320,0:05:57.280
test screen for example logo and looked

0:05:55.680,0:05:59.199
whether it looked right

0:05:57.280,0:06:00.960
I added instructions as needed and went

0:05:59.199,0:06:03.360
through more and more and more roms and

0:06:00.960,0:06:05.199
later I wrote in unit test suite as a

0:06:03.360,0:06:06.000
safety net and this unit test suite it

0:06:05.199,0:06:08.400
just

0:06:06.000,0:06:10.080
sets up an empty emulator state executes

0:06:08.400,0:06:10.400
some instructions and then looks whether

0:06:10.080,0:06:13.840
the

0:06:10.400,0:06:13.840
expected side effects have happened

0:06:14.880,0:06:19.120
for debugging I usually use e-debug but

0:06:17.120,0:06:20.880
this was super ineffective because well

0:06:19.120,0:06:22.960
you don't really want to step through

0:06:20.880,0:06:24.960
big cons doing side effects for every

0:06:22.960,0:06:26.880
single cycle when it can take like 100

0:06:24.960,0:06:29.680
cycles for things to happen

0:06:26.880,0:06:31.360
therefore I've set up logging and

0:06:29.680,0:06:32.720
whenever I locked something

0:06:31.360,0:06:33.919
and couldn't figure out the error I

0:06:32.720,0:06:37.039
compared my lock output with

0:06:33.919,0:06:39.199
instrumented version of another emulator

0:06:37.039,0:06:40.880
and if the locks diverge then I have

0:06:39.199,0:06:42.720
figured out where the bug lies and could

0:06:40.880,0:06:44.479
look deeper into it

0:06:42.720,0:06:46.639
future project idea might be a chip 8

0:06:44.479,0:06:50.720
debugger but I doubt I'll ever

0:06:46.639,0:06:52.639
go into it for analysis I initially

0:06:50.720,0:06:54.400
wrote a disassembler which is a very

0:06:52.639,0:06:56.160
simple thing but super tedious

0:06:54.400,0:06:57.599
especially if you wanted to add advanced

0:06:56.160,0:06:59.120
functionality for example analysis or

0:06:57.599,0:07:00.000
thinking of what part is data what had

0:06:59.120,0:07:01.840
this code

0:07:00.000,0:07:03.360
and I had this great idea for using the

0:07:01.840,0:07:05.120
radari 2 framework

0:07:03.360,0:07:06.479
and adding analysis and disassembly

0:07:05.120,0:07:08.400
plug-in for it

0:07:06.479,0:07:10.319
so I looked into this found okay here

0:07:08.400,0:07:12.160
where you can write plugins in c

0:07:10.319,0:07:13.520
but also in python so I wrote one in

0:07:12.160,0:07:15.039
python and then the scout there's

0:07:13.520,0:07:17.440
actually existing one in core which you

0:07:15.039,0:07:19.599
have to enable explicitly by passing its

0:07:17.440,0:07:21.840
argument so I've tried it and found it's

0:07:19.599,0:07:23.680
not exactly as good as my own one so

0:07:21.840,0:07:26.610
improved this one and submitted pull

0:07:23.680,0:07:28.080
requests until it was at the same level

0:07:26.610,0:07:30.160
[Music]

0:07:28.080,0:07:31.360
rendering was the trickiest part of this

0:07:30.160,0:07:34.319
whole thing because

0:07:31.360,0:07:35.759
well I decided against using a library

0:07:34.319,0:07:37.120
not like there would have been any

0:07:35.759,0:07:39.599
usable library for this

0:07:37.120,0:07:41.680
my usual approach of accelerating svg

0:07:39.599,0:07:45.120
file was too expensive it just created

0:07:41.680,0:07:47.360
too much garbage and took too long time

0:07:45.120,0:07:49.599
I then tried creating mutating strings

0:07:47.360,0:07:52.639
this was either either too expensive

0:07:49.599,0:07:55.039
just like svgs or too complicated I

0:07:52.639,0:07:57.280
tried changing svg tiles which created

0:07:55.039,0:07:59.520
gaps between the lines

0:07:57.280,0:08:00.720
then I tried to create an xpm file which

0:07:59.520,0:08:02.400
was backed by a bull vector

0:08:00.720,0:08:04.400
administrating this bull vector

0:08:02.400,0:08:06.879
but the image caching effect made it

0:08:04.400,0:08:10.000
just every nth frame to appear which

0:08:06.879,0:08:11.440
wasn't good either then I had the idea

0:08:10.000,0:08:13.280
to just use plain text

0:08:11.440,0:08:14.800
and paint the individual characters with

0:08:13.280,0:08:17.120
a different background color this

0:08:14.800,0:08:18.479
this had perfect perfect performance

0:08:17.120,0:08:20.000
there were many optimization attempts

0:08:18.479,0:08:21.840
until I got there and it was

0:08:20.000,0:08:23.199
very very stressful I wasn't sure

0:08:21.840,0:08:26.160
whether I would ever get to accept the

0:08:23.199,0:08:28.560
performance at all

0:08:26.160,0:08:30.319
for sound you only need to a single beep

0:08:28.560,0:08:31.280
so technically it shouldn't be difficult

0:08:30.319,0:08:33.519
to emulate it

0:08:31.280,0:08:34.880
however doing this is hard because Emacs

0:08:33.519,0:08:37.200
officially only supports synchronous

0:08:34.880,0:08:39.039
playback of sounds

0:08:37.200,0:08:41.360
but there's also emax process which you

0:08:39.039,0:08:43.519
can launch in asynchronous way

0:08:41.360,0:08:45.279
so I looked into it and found that

0:08:43.519,0:08:46.640
employee has a slave mode and mpv

0:08:45.279,0:08:50.880
supports listing on the

0:08:46.640,0:08:54.000
fifo for commands so I've created a pipe

0:08:50.880,0:08:55.519
started a past mpv in loop mode and

0:08:54.000,0:08:58.000
always send in pause and pause command

0:08:55.519,0:09:01.839
to the fifo and that way I could control

0:08:58.000,0:09:01.839
when to start beeping and stop beeping

0:09:02.640,0:09:07.200
so yeah that's it so far was a very

0:09:05.760,0:09:09.279
educational experience

0:09:07.200,0:09:10.320
I have tried out a bunch of games which

0:09:09.279,0:09:12.640
were

0:09:10.320,0:09:14.320
well I almost say the worst ports of

0:09:12.640,0:09:15.839
classic games I've ever tried

0:09:14.320,0:09:18.320
it wasn't terribly fun to play them but

0:09:15.839,0:09:21.760
was fun to improve the emulator until

0:09:18.320,0:09:23.279
well things worked good enough

0:09:21.760,0:09:25.120
and I've learned a lot about how

0:09:23.279,0:09:27.760
computers work at this level

0:09:25.120,0:09:28.880
so maybe maybe I'll in the future make

0:09:27.760,0:09:31.920
another emulator

0:09:28.880,0:09:34.000
but uh I'm not sure whether anything

0:09:31.920,0:09:36.560
more advanced like intel 8080 emulator

0:09:34.000,0:09:37.839
will actually run mix fast enough

0:09:36.560,0:09:39.200
but it's still an interesting idea

0:09:37.839,0:09:39.600
because then you could actually have an

0:09:39.200,0:09:41.680
os

0:09:39.600,0:09:43.120
inside Emacs and fulfill that one

0:09:41.680,0:09:45.440
specific meme

0:09:43.120,0:09:47.279
but if I try to do most serious stuff

0:09:45.440,0:09:48.000
I'll probably use chicken scheme which

0:09:47.279,0:09:49.920
is my

0:09:48.000,0:09:53.279
preferred language for serious projects

0:09:49.920,0:09:57.839
and writing neso gamer emulator

0:09:53.279,0:09:57.839
and that's it thank you