diff --git a/README.md b/README.md
index f5f5d629..26fb7bff 100644
--- a/README.md
+++ b/README.md
@@ -81,9 +81,9 @@ It is so small I could fit it into a single QR:
-It's 60 bytes.
+It's 58 bytes.
-How little is 60 bytes? Well, this line of text weighs more than 70 bytes.
+How little is 58 bytes? Well, this line of text weighs more than 70 bytes.
And so does this arbitrary sequence of emojis: π©πΌββ€οΈβπβπ¨πΌπ§π½ββοΈπ©πΌββ€οΈβπβπ¨πΌ
@@ -94,12 +94,10 @@ An **empty** C program generated with `gcc -Os -w -xc - <<< "main;"` on linux-x8
```
-c53000b80000cd108b3f
-8d22e54021c30837bbd0
-0778f5e4606bc00ad414
-d5449801c739df73dc30
-1d79d8ad893a7bdc880f
-83eb5079f95b202779d6
+c53000b80000cd108b3f8d22e5402
+1c3300fbbd0077af5e4606bc00ad4
+14d5449801c739dfad10257bd9893
+a74de880f83eb5079f95b88277bd8
```
@@ -107,6 +105,6 @@ d5449801c739df73dc30
||My version|MattKC's version|ibara's version|
|-|-|-|-|
-|Bytes|60|~1400|2024|
+|Bytes|58|~1400|2024|
|QR||||
|Link|https://github.com/donno2048/snake|https://mattkc.com/etc/snakeqr/|https://github.com/ibara/snakeqr|
diff --git a/demo/qr.png b/demo/qr.png
index 429a5c46..66859417 100644
Binary files a/demo/qr.png and b/demo/qr.png differ
diff --git a/demo/snake.zip b/demo/snake.zip
index a3faf9b8..9a6c6b61 100644
Binary files a/demo/snake.zip and b/demo/snake.zip differ
diff --git a/docs/update.py b/docs/update.py
index a889cf4d..eabf8a61 100644
--- a/docs/update.py
+++ b/docs/update.py
@@ -4,8 +4,8 @@
hexdata = open(0).read().replace("\n", "")
-length = len(hexdata) // 2
+length = len(hexdata)
div = next(filter(lambda x: not length % x, range(int(length ** .5), length)))
-open("README.md", "w").write(open(Path(__file__).parent.resolve() / 'template.md').read().format(size = length, hex = "\n".join(findall('..' * div, hexdata)), platform = get_platform(), empty_size = Path("a.out").stat().st_size))
+open("README.md", "w").write(open(Path(__file__).parent.resolve() / 'template.md').read().format(size = length // 2, hex = "\n".join(findall('.' * div, hexdata)), platform = get_platform(), empty_size = Path("a.out").stat().st_size))
diff --git a/snake.asm b/snake.asm
index d3f3ebdd..acd95914 100644
--- a/snake.asm
+++ b/snake.asm
@@ -1,6 +1,6 @@
; register usage during main loop
; DS: 0xB800, segment of screen buffer
-; BX: 0x7D0, screen size (40x25x2 bytes), used in food generation, edge checks and for snake character, also used for screen accesses but constantly reinitialized
+; BX: 0x7D0, screen size (40x25x2 bytes), used in food generation, edge checks, also used for screen accesses but constantly reinitialized
; DI: position of the snake head
; SI: pointer to memory location where the current position of the snake head is stored (actual pointer is BP+SI because it defaults to SS)
lds si, [bx+si] ; SI=0x100 and BX=0x0 at program start in most DOS versions, this initializes DS and SI (machine code at 0x100 is c5 30 00 b8)
@@ -13,10 +13,10 @@ start: ; reset game
.food: ; create new food item
in ax, 0x40 ; read 16 bit timer counter into AX for randomization
and bx, ax ; mask with BX to make divisible by 4 and less than or equal to screen size
- or [bx], dh ; place food item and check if position was empty by applying OR with DH (assumed to be 1)
+ xor [bx], cl ; place food item and check if position was empty by applying XOR with CL (assumed to be 0xFF)
.input: ; handle keyboard input
mov bx, 0x7D0 ; initialize BX
- js .food ; if position was occupied by snake or wall in food generation => try again, if we came from main loop SF=0
+ jp .food ; if position was occupied by snake or wall in food generation => try again, if we came from main loop PF=0
in al, 0x60 ; read scancode from keyboard controller - bit 7 is set in case key was released
imul ax, BYTE 0xA ; we want to map scancodes for arrow up (0x48/0xC8), left (0x4B/0xCB), right (0x4D/0xCD), down (0x50/0xD0) to movement offsets
aam 0x14 ; IMUL (AH is irrelevant here), AAM and AAD with some magic constants maps up => -80, left => -2, right => 2, down => 80
@@ -24,16 +24,15 @@ start: ; reset game
cbw ; but causes weird snake movements though with other keys
add di, ax ; add offset to head position
cmp di, bx ; check if head crossed vertical edge by comparing against screen size in BX
- jae start ; if DI<0 or DI>=BX => game over
- xor [di], bl ; XOR head position with snake character
- jns start ; if it already had snake or wall in it, SF=0 from XOR => game over
lodsw ; load 0x2007 into AX from off-screen screen buffer and advance head pointer
+ adc [di], ah ; ADC head position with 0x20 to set snake character
+ jnp start ; if it already had snake or wall in it or if it crossed a vertical edge, PF=0 from ADC => game over
mov [bp+si], di ; store head position, use BP+SI to default to SS
- jnp .food ; if food was consumed, PF=0 from XOR => generate new food
+ jz .food ; if food was consumed, ZF=1 from ADC => generate new food
.wall: ; draw an invisible wall on the left side
mov [bx], cl ; store wall character
- sub bx, 0x50 ; go one line backwards
+ sub bx, BYTE 0x50 ; go one line backwards
jns .wall ; jump to draw the next wall
pop bx ; no food was consumed so pop tail position into BX
- and [bx], ah ; clear old tail position on screen, AND also clears SF
- jns .input ; loop to keyboard input
+ mov [bx], ah ; clear old tail position on screen
+ jnp .input ; loop to keyboard input, PF=0 from SUB