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