Outline lightning talk.
authorRichard W.M. Jones <rjones@redhat.com>
Sat, 26 Oct 2019 11:49:22 +0000 (12:49 +0100)
committerRichard W.M. Jones <rjones@redhat.com>
Sat, 26 Oct 2019 12:27:22 +0000 (13:27 +0100)
21 files changed:
2019-lightning-talk/.gitignore [new file with mode: 0644]
2019-lightning-talk/6400-boot.d/.exists [new file with mode: 0644]
2019-lightning-talk/6400-boot.term [new file with mode: 0755]
2019-lightning-talk/6600-assemble.sh [new file with mode: 0755]
2019-lightning-talk/6600-next [new file with mode: 0755]
2019-lightning-talk/6800-next [new file with mode: 0755]
2019-lightning-talk/6800-reflection.sh [new file with mode: 0755]
2019-lightning-talk/9000-final.html [new file with mode: 0644]
2019-lightning-talk/9001-final.html [new file with mode: 0644]
2019-lightning-talk/9002-final.html [new file with mode: 0644]
2019-lightning-talk/9003-final.html [new file with mode: 0644]
2019-lightning-talk/assemble.sh [new file with mode: 0755]
2019-lightning-talk/bashrc [new file with mode: 0644]
2019-lightning-talk/code.js [new file with mode: 0644]
2019-lightning-talk/functions [new file with mode: 0644]
2019-lightning-talk/hello.asm [new file with mode: 0644]
2019-lightning-talk/pyrit.asm [new file with mode: 0644]
2019-lightning-talk/redhat.png [new file with mode: 0644]
2019-lightning-talk/restore [new file with mode: 0755]
2019-lightning-talk/run [new file with mode: 0755]
2019-lightning-talk/style.css [new file with mode: 0644]

diff --git a/2019-lightning-talk/.gitignore b/2019-lightning-talk/.gitignore
new file mode 100644 (file)
index 0000000..775e73a
--- /dev/null
@@ -0,0 +1,8 @@
+/bindings
+/history
+/6200-vddk.d/fedora.vmdk
+/6200-vddk.d/fedora.vmdk.xz
+/6200-vddk.d/fedora.vmdk.lck
+/6200-vddk.d/mp
+/6400-boot.d/qemu.sh
+/6400-boot.d/root
diff --git a/2019-lightning-talk/6400-boot.d/.exists b/2019-lightning-talk/6400-boot.d/.exists
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/2019-lightning-talk/6400-boot.term b/2019-lightning-talk/6400-boot.term
new file mode 100755 (executable)
index 0000000..ab4ecb4
--- /dev/null
@@ -0,0 +1,26 @@
+#!/bin/bash -
+
+source functions
+
+# Title.
+export title="Tiny VMs"
+
+kernel="$(ls -1vr /boot/vmlinuz-* | head -1)"
+echo "qemu-kvm -display none -kernel $kernel -drive file=nbd:unix:\$unixsocket,snapshot=on -append 'console=ttyS0 root=/dev/sda1 rw' -serial stdio" > 6400-boot.d/qemu.sh
+chmod +x 6400-boot.d/qemu.sh
+
+# History.
+remember 'mkdir -p root/dev root/sbin root/bin root/usr/sbin root/usr/bin'
+remember 'sudo mknod root/dev/console c 5 1'
+remember 'cp /sbin/busybox root/sbin/'
+remember 'ln root/sbin/busybox root/bin/ls'
+remember 'ln root/sbin/busybox root/bin/sh'
+remember 'ln root/sbin/busybox root/bin/init'
+remember 'ls -lR root'
+remember "nbdkit -U - linuxdisk root --run 'export unixsocket; ./qemu.sh'"
+
+./restore
+pushd 6400-boot.d >/dev/null
+terminal
+popd >/dev/null
+./restore
diff --git a/2019-lightning-talk/6600-assemble.sh b/2019-lightning-talk/6600-assemble.sh
new file mode 100755 (executable)
index 0000000..cbc7376
--- /dev/null
@@ -0,0 +1,3 @@
+#!/bin/bash -
+
+xfce4-terminal --disable-server -x ./6600-next
diff --git a/2019-lightning-talk/6600-next b/2019-lightning-talk/6600-next
new file mode 100755 (executable)
index 0000000..92b07ec
--- /dev/null
@@ -0,0 +1,19 @@
+#!/bin/bash -
+
+source functions
+
+# Title.
+export title="Assemble!"
+
+# History.
+remember 'less assemble.sh'
+remember 'emacs -nw hello.asm'
+remember "nbdkit sh assemble.sh file=hello.asm --run 'qemu-system-i386 -hda \$nbd'"
+remember 'less pyrit.asm'
+remember "nbdkit sh assemble.sh file=pyrit.asm --run 'qemu-system-i386 -hda \$nbd'"
+
+banner "Demo Credit: Pyrit by Jan Kadlec (Řrřola) "
+banner "https://www.pouet.net/prod.php?which=78045"
+echo
+
+terminal
diff --git a/2019-lightning-talk/6800-next b/2019-lightning-talk/6800-next
new file mode 100755 (executable)
index 0000000..478e115
--- /dev/null
@@ -0,0 +1,22 @@
+#!/bin/bash -
+
+source functions
+
+# Title.
+export title="Reflection"
+
+# History.
+remember 'nbdkit info base64exportname'
+
+for program in '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'
+do
+    remember "qemu-system-i386 -drive snapshot=on,file.driver=nbd,file.host=localhost,file.port=10809,file.export=$program"
+done
+
+banner "Demo Credit: Oscar Toledo Gutierrez"
+banner "https://github.com/nanochess       "
+echo
+
+terminal
diff --git a/2019-lightning-talk/6800-reflection.sh b/2019-lightning-talk/6800-reflection.sh
new file mode 100755 (executable)
index 0000000..29fe3da
--- /dev/null
@@ -0,0 +1,3 @@
+#!/bin/bash -
+
+xfce4-terminal --disable-server -x ./6800-next
diff --git a/2019-lightning-talk/9000-final.html b/2019-lightning-talk/9000-final.html
new file mode 100644 (file)
index 0000000..b53d996
--- /dev/null
@@ -0,0 +1,6 @@
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
+<link rel="stylesheet" href="style.css" type="text/css"/>
+<script src="code.js" type="text/javascript"></script>
+
+<h1>What did we learn?</h1>
+
diff --git a/2019-lightning-talk/9001-final.html b/2019-lightning-talk/9001-final.html
new file mode 100644 (file)
index 0000000..901a344
--- /dev/null
@@ -0,0 +1,9 @@
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
+<link rel="stylesheet" href="style.css" type="text/css"/>
+<script src="code.js" type="text/javascript"></script>
+
+<h1>What did we learn?</h1>
+
+<ul>
+<li> 512 bytes ought to be enough for anybody
+</ul>
diff --git a/2019-lightning-talk/9002-final.html b/2019-lightning-talk/9002-final.html
new file mode 100644 (file)
index 0000000..1f02187
--- /dev/null
@@ -0,0 +1,10 @@
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
+<link rel="stylesheet" href="style.css" type="text/css"/>
+<script src="code.js" type="text/javascript"></script>
+
+<h1>What did we learn?</h1>
+
+<ul>
+<li> 512 bytes ought to be enough for anybody
+<li> Any problem can be solved with a little bit more shell script
+</ul>
diff --git a/2019-lightning-talk/9003-final.html b/2019-lightning-talk/9003-final.html
new file mode 100644 (file)
index 0000000..63bff26
--- /dev/null
@@ -0,0 +1,12 @@
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
+<link rel="stylesheet" href="style.css" type="text/css"/>
+<script src="code.js" type="text/javascript"></script>
+
+<h1>What did we learn?</h1>
+
+<ul>
+<li> 512 bytes ought to be enough for anybody
+<li> Any problem can be solved with a little bit more shell script
+<li> <code>qemu -hda</code> is a vitally important option
+  that must never be removed
+</ul>
diff --git a/2019-lightning-talk/assemble.sh b/2019-lightning-talk/assemble.sh
new file mode 100755 (executable)
index 0000000..699d5b9
--- /dev/null
@@ -0,0 +1,26 @@
+#!/bin/bash -
+
+f=$tmpdir/source.asm
+s=$tmpdir/final.asm
+b=$tmpdir/binary
+
+case "$1" in
+    config)
+        if [ "$2" = "file" ]; then
+            ln -sf "$(realpath "$3")" $f
+        else
+            echo "unknown parameter $2=$2" >&2
+            exit 1
+        fi ;;
+    config_complete)
+        echo 'org 07c00h' > $s
+        cat $f >> $s
+        echo 'times 510-($-$$) db 0' >> $s
+        echo 'db 055h,0aah' >> $s
+        nasm -f bin $s -o $b ;;
+    get_size) echo 512 ;;
+    pread) dd if=$b skip=$4 count=$3 iflag=count_bytes,skip_bytes ;;
+    can_write) ;;
+    pwrite) exit 1 ;;
+    *) exit 2 ;;
+esac
diff --git a/2019-lightning-talk/bashrc b/2019-lightning-talk/bashrc
new file mode 100644 (file)
index 0000000..a52a5e9
--- /dev/null
@@ -0,0 +1,21 @@
+# -*- shell-script -*-
+
+# Colour ls.
+if [ -f /etc/profile.d/colorls.sh ]; then . /etc/profile.d/colorls.sh; fi
+
+# Fancy prompt colours (see
+# https://wiki.archlinux.org/index.php/Color_Bash_Prompt)
+titlecol=$'\e[1;37;41m'    ;# colour for the title
+promptcol=$'\e[0;32m'      ;# colour for the prompt
+commandcol=$'\e[1;31m'     ;# colour for the typed command
+outputcol=$'\e[0m'         ;# colour for command output
+
+export PS1="\n\[$promptcol\]\$ \[$commandcol\]"
+
+trap 'echo -ne "$outputcol"' DEBUG
+
+# Load key bindings (if any).
+bind -f $talkdir/bindings
+
+# Same as the banner function, but we cannot reuse it.
+printf "%s   %s   %s\\n" $titlecol "$title" $outputcol
diff --git a/2019-lightning-talk/code.js b/2019-lightning-talk/code.js
new file mode 100644 (file)
index 0000000..ccbe20a
--- /dev/null
@@ -0,0 +1,72 @@
+function plugins ()
+{
+    document.write ("\
+<div class=\"plugins\"> \
+<p id=\"caption\">plugins available in nbdkit 1.15.6</p> \
+<ul> \
+<li id=\"plugin-curl\"> curl \
+<li id=\"plugin-data\"> data \
+<li id=\"plugin-ext2\"> ext2 \
+<li id=\"plugin-file\"> file \
+<li id=\"plugin-floppy\"> floppy \
+<li id=\"plugin-full\"> full \
+<li id=\"plugin-guestfs\"> guestfs \
+<li id=\"plugin-gzip\"> gzip \
+<li id=\"plugin-info\"> info \
+<li id=\"plugin-iso\"> iso \
+<li id=\"plugin-libvirt\"> libvirt \
+<li id=\"plugin-linuxdisk\"> linuxdisk \
+<li id=\"plugin-lua\"> lua \
+<li id=\"plugin-memory\"> memory \
+<li id=\"plugin-nbd\"> nbd \
+<li id=\"plugin-null\"> null \
+<li id=\"plugin-ocaml\"> ocaml \
+<li id=\"plugin-partitioning\"> partitioning \
+<li id=\"plugin-pattern\"> pattern \
+<li id=\"plugin-perl\"> perl \
+<li id=\"plugin-python\"> python \
+<li id=\"plugin-random\"> random \
+<li id=\"plugin-ruby\"> ruby \
+<li id=\"plugin-rust\"> rust \
+<li id=\"plugin-sh\"> sh \
+<li id=\"plugin-split\"> split \
+<li id=\"plugin-streaming\"> streaming \
+<li id=\"plugin-tar\"> tar \
+<li id=\"plugin-tcl\"> tcl \
+<li id=\"plugin-vddk\"> vddk \
+<li id=\"plugin-zero\"> zero \
+</ul> \
+</div> \
+");
+}
+
+function filters (layer)
+{
+    document.write ("\
+<div class=\"filters\"> \
+<p class=\"filtercaption\">filters available in nbdkit 1.15.6</p> \
+<ul> \
+<li id=\"filter" + layer + "-blocksize\"> blocksize \
+<li id=\"filter" + layer + "-cache\"> cache \
+<li id=\"filter" + layer + "-cacheextents\"> cacheextents \
+<li id=\"filter" + layer + "-cow\"> cow \
+<li id=\"filter" + layer + "-delay\"> delay \
+<li id=\"filter" + layer + "-error\"> error \
+<li id=\"filter" + layer + "-fua\"> fua \
+<li id=\"filter" + layer + "-log\"> log \
+<li id=\"filter" + layer + "-nocache\"> nocache \
+<li id=\"filter" + layer + "-noextents\"> noextents \
+<li id=\"filter" + layer + "-noparallel\"> noparallel \
+<li id=\"filter" + layer + "-nozero\"> nozero \
+<li id=\"filter" + layer + "-offset\"> offset \
+<li id=\"filter" + layer + "-partition\"> partition \
+<li id=\"filter" + layer + "-rate\"> rate \
+<li id=\"filter" + layer + "-readahead\"> readahead \
+<li id=\"filter" + layer + "-retry\"> retry \
+<li id=\"filter" + layer + "-stats\"> stats \
+<li id=\"filter" + layer + "-truncate\"> truncate \
+<li id=\"filter" + layer + "-xz\"> xz \
+</ul> \
+</div> \
+");
+}
diff --git a/2019-lightning-talk/functions b/2019-lightning-talk/functions
new file mode 100644 (file)
index 0000000..94948e2
--- /dev/null
@@ -0,0 +1,46 @@
+# -*- shell-script -*-
+# This creates some standard functions.  See also $talkdir/bashrc
+# which runs in the same bash context as the terminal.
+
+# Place any local environment variables and settings in "local".
+if [ -f local ]; then source local; fi
+
+# Environment variables.
+export HISTFILE=$talkdir/history
+export PATH=$talkdir:$PATH
+export EDITOR="emacs -nw"
+
+# remember <command> <args ...>
+#
+# This function does two things: (1) It adds the command and arguments
+# to the shell history, so that commands can be recalled using up
+# arrow or reverse search.  (2) It makes a function key recall the
+# command.  The first command is assigned to F2, the second to F3 and
+# so forth.
+
+rm -f $HISTFILE
+touch $HISTFILE
+rm -f $talkdir/bindings
+touch bindings
+
+fnum=2
+keys=(- OP OQ OR OS '[15~' '[17~' '[18~' '[19~' '[20~' '[21~')
+
+remember ()
+{
+    echo "$@" >> $HISTFILE
+    echo "$@" | sed -e 's/"/\\"/g; s/$/"/' \
+        -e 's/^/"\\e'"${keys[$fnum]}"'":"\\C-k \\C-u/' >> $talkdir/bindings
+    ((fnum++))
+}
+
+terminal ()
+{
+    chmod -w $HISTFILE
+    /bin/bash --rcfile $talkdir/bashrc "$@"
+}
+
+banner ()
+{
+    printf "%s   %s   %s\\n" $'\e[1;37;41m' "$1" $'\e[0m'
+}
diff --git a/2019-lightning-talk/hello.asm b/2019-lightning-talk/hello.asm
new file mode 100644 (file)
index 0000000..258d5ed
--- /dev/null
@@ -0,0 +1,14 @@
+        mov ah,0        ;  clear screen
+        mov al,3
+        int 0x10
+        mov ah,0x13 ; print string
+        mov bl,0xa
+        mov al,1
+        mov cx,len
+        mov dh,0
+        mov dl,0
+        mov bp,hello
+        int 0x10
+        hlt
+hello:  db "*** Hello KVM Forum ***",0xd,0xa
+len:    equ $-hello
diff --git a/2019-lightning-talk/pyrit.asm b/2019-lightning-talk/pyrit.asm
new file mode 100644 (file)
index 0000000..0288bb0
--- /dev/null
@@ -0,0 +1,272 @@
+; Pyrit
+
+; a 256-byte intro by Rrrola <rrrola@gmail.com>
+
+; greets to everyone who's computer is too fast :)
+
+; This is loosely based on my intro 'Gem' (shown on Demobit),
+; but the code is much better.
+
+; Vector3: X right, Y down, Z forward.
+; On the FP stack it looks like {Y X Z} (Y is often used in comparisons).
+; In memory it looks like {Z X Y}, which saves a displacement byte.
+; (u'v) is the dot product: ux*vx + uy*vy + uz*vz.
+
+        xor ax,ax
+        xor bx,bx
+        mov cx,0ffh
+        mov di,-2
+;        mov ss,dx
+        mov sp,di
+        mov si,100h
+        mov bp,091ch
+
+; assume al=0 bx=0 sp=di=-2 si=0100h bp=09??h
+
+;Set video mode and earth+sky palette
+  dec di       ; u16[100h] = -20401, u16[10Ch] = -30515
+  mov al,13h
+  dec di       ; initial pixel_adr@di = -4
+
+P:shr cl,1     ; B@cl = 0..8..31,31..0
+
+  int 10h      ; set video mode / color: bx=index dh=R ch=G cl=B
+
+  movsx cx,bl  ; 0..127,128..255 (palette index)
+  xor ch,cl    ; 0..127,127..0
+  mov cl,ch
+  mov ax,cx
+  mul ax       ; R@dh = 0..16..63,63..16..0
+
+  shr cx,1     ; G@ch = 0..63,63..0
+
+  inc bl       ; keep default color 0
+  js Q         ; R@dh = 0..63,63..16..0
+  xchg cl,dh   ; B@cl = 0..16..63,63..0
+Q:mov ax,1010h
+  jnz P        ;bx=0 cx=0
+
+        ; Constants expected at a fixed address below.
+        mov ax,0b04fh
+        mov word[100h],ax
+        mov ax,04f13h
+        mov word[102h],ax
+        mov ax,0e9d0h
+        mov word[104h],ax
+        mov ax,010cdh
+        mov word[106h],ax
+        mov ax,0be0fh
+        mov word[108h],ax
+        mov ax,030cbh
+        mov word[10ah],ax
+        mov ax,088cdh
+        mov word[10ch],ax
+        mov ax,089e9h
+        mov word[10eh],ax
+
+;Each frame: Generate normals to p0..p11=[bp+200h,300h,...].
+M:mov ax,0x4731 ; highest 9 bits: float32 exponent 1/256 (for T)
+                ; lower byte = 2*number of rotations+1
+                ; lowest 4 bits must be 0x1 for 'test cl,al'
+  mov dx,0xA000-10-20-20-4
+  mov es,dx    ; dx:bx = YX:XX = 0x9fca:0
+  pusha  ; adr:   -18 -16 -14 -12 -10  -8  -6  -4  -2
+         ; stack:  di  si  bp  sp  bx  dx  cx  ax   0
+         ; data:   -4 100 9??  -2  0  9fca {T/256}
+  mov cx,12
+G:add bp,si    ; i@cx = 12...1; bp points to p[12-i]; carry=0
+  pusha
+
+;Generate 12 planes with unit normals.
+
+;  fld1         ; platonic dodecahedron: exact is atan((1+sqrt5)/2)=1.017rad
+  fld dword[di-2]    ;|t=T/256: morphing shape: cube, platonic12, rhombic12
+
+  fsincos
+
+  fldz               ;|a=0 b c (a*a+b*b+c*c = 1)
+;  fldlg2 ;irregular shape
+
+N:test cl,al ;=1     ;|a b c
+  jnz K
+  fchs
+K:fstp st3           ;|b c +-a (scramble so that all 12 planes are generated)
+  loop N  ;cl=0      ;|z x y
+
+;Do a bunch of slow rotations. z x y -> cx-sy cy+sx z
+
+R:fstp st3           ;|x y z
+Z:fld st1            ;|y x y z                     ;|x sy x cy z
+  fld dword[di-2]    ;|t=T/256
+  fsincos            ;|c=cos(t) s=sin(t) y x y z   ;|c s x sy x cy z
+  fmulp st4          ;|s y x cy z                  ;|s x sy cx cy z
+  fmulp              ;|sy x cy z                   ;|sx sy cx cy z
+  add al,0x7F ; loop 2x
+  jo Z
+  faddp st3          ;|sy cx cy+sx z
+  fsubp              ;|new.z=cx-sy .x=cy+sx .y=z
+  jc R       ; loop 24x
+
+S:fstp dword[bp+si] ;[bp+100]=.z [bp+104]=.x [bp+108]=.y
+  sub si,di
+  jpo S
+
+  popa
+  loop G
+  popa
+
+; the visible pixels are A0000..AF9FF, I want X=0 Y=0 in the center
+;Each pixel: cx=T dx:bx=YX:XX(init=9fca:0) di=adr(init=-4)
+X:inc dx       ; part of "dx:bx += 0x0000CCCD"
+X2:
+  stosb
+
+  pusha        ; adr:     -18 -16 -14 -12 -10  -8  -6  -4  -2
+  fninit       ; stack:    di  si  bp  sp  bx  dx  cx  ax   0
+  mov bx,es    ; s16:  pixadr 100 9??  -2  ..X..Y  T result
+  mov di,-4 ;di = address of pushed ax
+
+;Compute ray direction.
+  fild word[BIG] ; store 28799 as a double, read as two floats
+  fst qword[bx]     ; t_front@float[bx] = 0, t_back@float[bx+4] = 6.879
+  fild word[di+4-9]
+  fild word[di+4-8]  ;|y=Y x=X z=BIG
+
+;Intersect the pyrite.
+  call GEM
+  popa         ; color -> pushed ax
+;  mov al,dl    ; show only palette
+
+;; Faster, but lower quality: draw each pixel twice.
+;  stosb
+;  add bx,0xCCCD; dx:bx = YXX += 0000CCCD
+;  adc dx,0
+
+  add bx,0xCCCD; dx:bx = YXX += 0000CCCD
+  jnc X2
+  jnz X        ; do 65536 pixels
+
+  in al,60h
+  dec ax  ; ah=0 (checkboard uses positive color indices)
+  loopnz M        ; T--
+;  ret          ; fallthrough
+
+GEM:
+;Hit the pyrite.
+  xchg ax,cx   ; ax = T
+
+; Faster (+4 or +8 bytes): test the shape only in the center of the screen
+  add dh,dh
+  jo B
+  add dl,dl
+  jo B
+
+;Ray-plane intersection.
+;Find the front plane with maximum t and back plane with minimum t.
+; tf@[bx],    tb@[bx+4]      ray parameter t
+; pf@[bx+si], pb@[bx+4+si]   pointer to plane
+  mov cx,12  ; i@cx = 12...1
+I:add bp,si    ; bp points to p[i]
+  fldlg2             ;|pd=0.301 y x z
+  fadd dword[bp+si]  ;|N=pd-(ro'p[i]) y x z  ; ro = 0 0 -1
+
+  push si      ; Dot product:
+D:fld dword[bp+si]   ;|p[i].z ...
+  fmul st4           ;|rd.z*p[i].z ...
+  sub si,di    ; 100 104 108
+  jpo D              ;|(rd*p[i]).y .x .z N rd.y .x .z
+  pop si
+  faddp
+  faddp              ;|D=(rd'p[i]) N y x z
+
+;If we hit the plane from the front (D<0), update tf. Otherwise update tb.
+  push bx
+  fst dword[bp+di]; -> p[i].dot_rd (will be read later)
+  test [bp+di+2],sp ; sf=1 if we're in front of the plane
+  js FRONT
+  sub bx,di    ; bx = address of tf?tb
+FRONT:         ; D<0:  if tf*D < N { tf=N/D; pf=current; }  maximalize tf
+  fld st0      ; D>=0: if tb*D < N { tb=N/D; pb=current; }  minimalize tb
+  fmul dword[bx]     ;|(tf?tb)*D D N y x z
+
+;;DosBOX-compatible FPU comparison, +5 bytes (+3 but we need ax)
+;  push ax
+;  fcomp st2          ;|D N y x z
+;  fnstsw ax
+;  sahf         ; cf = (tf?tb)*D < N
+;  pop ax
+;  jc NEXT
+
+  fcomip st2
+  jc NEXT
+
+;another alternative, +6 bytes
+;  fsub st2
+;  fstp dword[bp-8]
+;  test [bp-6],sp ; sf=1 if <0
+;  js NEXT
+
+
+  fdivr st1          ;|t=N/D N y x z
+  fst dword[bx] ; -> tf?tb
+  mov [bx+si],bp ; pf?pb = current
+NEXT:
+  fcompp
+  pop bx             ;|y x z
+
+  mov dx,[bx+6]
+  cmp dx,[bx+2]  ; if tf>tb { no_hit: early exit }
+  jng B     ;si=100   ;|y x z
+
+  loop I
+
+;Reflect: reflect(i,n) = i - 2*n*(i'n)
+  mov bx,[bx+si] ; pf
+Y:fld dword[bx+di]   ;|(rd'pf) rd.y .x .z  ; reads pf->dot_rd
+  fmul dword[bx+si]  ;|(rd'pf)*pf.z rd.y .x .z
+  fadd st0           ;|2*(rd'pf)*pf.z rd.y .x .z
+  fsubr st3          ;|R.z=rd.z-2*(rd'pf)*pf.z rd.y .x .z
+  sub si,di   ;100 104 108
+  jpo Y     ;si=10C  ;|(R=i-2*n(i'n)).y R.x R.z rd.y .x .z
+
+;Environment map: chessboard below, sky gradient above.
+B:
+; Subtle highlight on the pyrite.
+  fld st0
+  fimul word[C]  ; 16993 (background) or 20036 (pyrit)
+  fistp dword[di]     ;|y x z
+  sar dword[di],22    ; if y>=-0.5 { chessboard } else { sky }
+  js E             ; the sky is just y (= y^2 after gamma)
+
+; Everything the same brightness. (-6 bytes)
+;  fist word[di]      ;|y x z
+;  sar word[di],8  ; if y>=-0.5 { chessboard } else { sky }
+;  js E            ; the sky is just y (= y^2 after gamma)
+
+; Dark background version.
+;  fist word[di]      ;|y x z
+;  shld cx,si,16-3
+;  xor cl,9        ; hit?8:9 - make the background darker
+;  sar word[di],cl ; if y>=-0.5 { chessboard } else { sky }
+;  js E            ; the sky is just y (= y^2 after gamma)
+
+  fidivr word[si]    ;|C/y x z (C = hit?-30515:-20401)
+  fmul st1,st0
+  fmul st2           ;|u=z*C/y v=x*C/y z
+
+  fistp dword[bp+di]
+  sub al,[bp+di+1]
+  fistp dword[bp+di]
+  xor al,[bp+di+1] ; xortex@ax = (T-u) XOR v
+
+;  aam -32-24     ; more interesting floor texture
+  and al,9<<3
+  add al,10<<3    ; tex = (xortex AND 0b1001) + 10 [10|11|18|19]
+  mul byte[di]
+  mov [di],ah     ; pushed al = tex*y
+
+E:ret
+
+BIG     dw 28799
+C       dw 16993
+C2      dw 20036
diff --git a/2019-lightning-talk/redhat.png b/2019-lightning-talk/redhat.png
new file mode 100644 (file)
index 0000000..c955eb0
Binary files /dev/null and b/2019-lightning-talk/redhat.png differ
diff --git a/2019-lightning-talk/restore b/2019-lightning-talk/restore
new file mode 100755 (executable)
index 0000000..620e30e
--- /dev/null
@@ -0,0 +1,18 @@
+#!/bin/bash -
+
+# Safety-valve for unwary users...
+if [ "$LOGNAME" != "rjones" ] && [ "$LOGNAME" != "eblake" ]; then
+    exit 1
+fi
+
+if [ "$talkdir" = "" ]; then exit 1; fi
+
+fusermount -u $talkdir/6200-vddk.d/mp >& /dev/null
+
+if [ -d "$talkdir/6400-boot.d/root" ]; then
+    sudo rm -rf $talkdir/6400-boot.d/root
+fi
+
+sleep 0.5; killall nbdkit >& /dev/null
+
+exit 0
diff --git a/2019-lightning-talk/run b/2019-lightning-talk/run
new file mode 100755 (executable)
index 0000000..d771700
--- /dev/null
@@ -0,0 +1,25 @@
+#!/bin/bash -
+# Run the talk.
+
+set -e
+
+# Avoid GNOME keyring stupidity
+export GNOME_KEYRING_CONTROL=
+export GNOME_KEYRING_PID=
+
+# No proxy.
+#unset http_proxy
+#unset https_proxy
+#unset ftp_proxy
+
+# Clean up after previous run.
+talkdir=$PWD ./restore
+
+# Precreate any files necessary.
+#(nothing)
+
+# Run techtalk.  The demos require nbdkit 1.15.6, libnbd 1.1.5, and qemu 4.2,
+# which are not present in Fedora 30, so point to self-built versions.
+export PATH=$HOME/d/nbdkit:$HOME/d/qemu:$PATH
+$HOME/d/libnbd/run techtalk-pse
+#~/d/techtalk-pse/techtalk-pse
diff --git a/2019-lightning-talk/style.css b/2019-lightning-talk/style.css
new file mode 100644 (file)
index 0000000..e33ca15
--- /dev/null
@@ -0,0 +1,272 @@
+/* Red Hat red is rgb(238,0,0). */
+
+body {
+    background: url(redhat.png) no-repeat;
+    background-position: 98% 6px;
+    background-size: auto 48px;
+    /* font-size: 28pt; */ /* For max */
+    font-size: 20pt; /* For 1024x768 */
+    font-family: Red Hat Text, liberation, helvetica;
+    /* font-family: helvetica; */
+
+    /* Can be used to scale the whole document. */
+    /*transform: translate(-10%,-10%) scale(0.75,0.75);*/
+}
+
+body td, body th { /* why?? */
+    font-size: 24pt;
+    padding-bottom: 8px;
+}
+
+h1 {
+    color: rgb(238,0,0);
+    /*font-size: 48px;*/
+    font-size: 40px;
+    top: 8;
+    left: 0;
+    border-bottom: 2px solid rgb(238,0,0);
+}
+
+h2 {
+    color: rgb(238,0,0);
+    font-size: 32px;
+    font-style: italic;
+    border-bottom: 2px solid rgb(238,0,0);
+}
+
+b {
+    color: rgb(238,0,0);
+}
+
+/* Title page. */
+div#titlepage {
+    margin-top: 100px;
+    width: 80%;
+    margin-left: 10%;
+}
+
+div#titlepage p.title {
+    color: rgb(238,0,0);
+    font-weight: bold;
+    font-size: 48px;
+    text-align: left;
+}
+
+div#titlepage p.author {
+    font-size: 36px;
+    text-align: left;
+}
+
+div#titlepage p.abstract {
+    font-size: 28px;
+    text-align: left;
+}
+
+/* Code */
+pre.code {
+    margin-left: 1em;
+    background: #eee;
+}
+
+code {
+    color: rgb(238,0,0);
+}
+
+/* Bullet points */
+li {
+    padding-bottom: 16px;
+}
+
+/* Plugins box. */
+div.plugins {
+    background: #f8f8ff;
+    border: 1px solid rgb(238,0,0);
+    border-radius: 15px;
+    margin-left: auto;
+    margin-right: auto;
+    width: 800px;
+    height: 400px;
+    /* Position relative is needed so that items may be
+       positioned inside. */
+    position: relative;
+}
+
+div.plugins p#caption {
+    position: absolute;
+    bottom: -5px; right: 5px;
+    color: rgb(238,0,0);
+    text-align: right;
+    font-size: 16px;
+    font-weight: bold;
+}
+
+div.plugins ul {
+    position: absolute;
+    top: 10%;
+    width: 700px;
+    height: 380px;
+    column-count: 4;
+    list-style-type: none;
+    margin: 0;
+}
+
+div.plugins ul li {
+    padding: 0px;
+    margin: 5px;
+}
+
+div.plugins ul li.highlighted {
+    border: 1px solid rgb(238,0,0);
+    background: #fff;
+    padding-left: 10px;
+    color: rgb(238,0,0);
+    border-radius: 20px;
+    font-weight: bold;
+}
+
+/* Filters box. */
+div.filters {
+    background: #f8fff8;
+    border: 1px solid rgb(238,0,0);
+    border-radius: 15px;
+    margin-left: auto;
+    margin-right: auto;
+    width: 800px;
+    height: 280px;
+    /* Position relative is needed so that items may be
+       positioned inside. */
+    position: relative;
+}
+
+div.filters p.filtercaption {
+    position: absolute;
+    bottom: -5px; right: 5px;
+    color: rgb(238,0,0);
+    text-align: right;
+    font-size: 16px;
+    font-weight: bold;
+}
+
+div.filters ul {
+    position: absolute;
+    top: 10%;
+    width: 700px;
+    height: 260px;
+    column-count: 4;
+    list-style-type: none;
+    margin: 0;
+}
+
+div.filters ul li {
+    padding: 0px;
+    margin: 5px;
+}
+
+div.filters ul li.highlighted {
+    border: 1px solid rgb(238,0,0);
+    background: #fff;
+    padding-left: 10px;
+    color: rgb(238,0,0);
+    border-radius: 20px;
+    font-weight: bold;
+}
+
+/* Colored highlighting */
+div.plugins ul li.bg_r,
+div.filters ul li.bg_r {
+    background: #b00;
+    color: white;
+}
+
+div.plugins ul li.bg_g,
+div.filters ul li.bg_g {
+    background: #0b0;
+    color: white;
+}
+
+div.plugins ul li.bg_b,
+div.filters ul li.bg_b {
+    background: #00b;
+    color: white;
+}
+
+/* For images which must be centered on the page. */
+div.allcenter {
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    height: 50vw;
+}
+
+div.all-center img {
+}
+
+/* Outlined text. */
+.outline {
+    text-shadow: 2px 2px 0 rgb(238,0,0),
+                 -2px 2px 0 rgb(238,0,0),
+                 2px -2px 0 rgb(238,0,0),
+                 -2px -2px 0 rgb(238,0,0),
+                 0px 2px 0 rgb(238,0,0),
+                 0px -2px 0 rgb(238,0,0),
+                 -2px 0px 0 rgb(238,0,0),
+                 2px 0px 0 rgb(238,0,0),
+                 4px 4px 0 rgb(238,0,0),
+                 -4px 4px 0 rgb(238,0,0),
+                 4px -4px 0 rgb(238,0,0),
+                 -4px -4px 0 rgb(238,0,0),
+
+                 0px 4px 0 rgb(238,0,0),
+                 0px -4px 0 rgb(238,0,0),
+                 -4px 0px 0 rgb(238,0,0),
+                 4px 0px 0 rgb(238,0,0),
+                 2px 4px 0 rgb(238,0,0),
+                 -2px 4px 0 rgb(238,0,0),
+                 2px -4px 0 rgb(238,0,0),
+                 -2px -4px 0 rgb(238,0,0),
+                 4px 2px 0 rgb(238,0,0),
+                 -4px 2px 0 rgb(238,0,0),
+                 4px -2px 0 rgb(238,0,0),
+                 -4px -2px 0 rgb(238,0,0),
+
+                 4px 4px 0 rgb(255,128,128),
+                 -4px 4px 0 rgb(255,128,128),
+                 4px -4px 0 rgb(255,128,128),
+                 -4px -4px 0 rgb(255,128,128),
+                 0px 4px 0 rgb(255,128,128),
+                 0px -4px 0 rgb(255,128,128),
+                 -4px 0px 0 rgb(255,128,128),
+                 4px 0px 0 rgb(255,128,128),
+                 8px 8px 0 rgb(255,128,128),
+                 -8px 8px 0 rgb(255,128,128),
+                 8px -8px 0 rgb(255,128,128),
+                 -8px -8px 0 rgb(255,128,128),
+
+                 0px 8px 0 rgb(255,128,128),
+                 0px -8px 0 rgb(255,128,128),
+                 -8px 0px 0 rgb(255,128,128),
+                 8px 0px 0 rgb(255,128,128),
+                 4px 8px 0 rgb(255,128,128),
+                 -4px 8px 0 rgb(255,128,128),
+                 4px -8px 0 rgb(255,128,128),
+                 -4px -8px 0 rgb(255,128,128),
+                 8px 4px 0 rgb(255,128,128),
+                 -8px 4px 0 rgb(255,128,128),
+                 8px -4px 0 rgb(255,128,128),
+                 -8px -4px 0 rgb(255,128,128);
+}
+
+/* Warning symbol. */
+span.warning {
+    background-color: yellow;
+    font-weight: bold;
+}
+
+/* Attribution for artwork etc. */
+p.attribution {
+    position: absolute;
+    right: 10px;
+    bottom: 10px;
+    text-align: right;
+    font-size: 10pt;
+}