+
+; reads from ds:si writes to es:di (bug top left corner)
+; knows how many pixels on screen and how many in the lovebug
+blit32:
+ mov cx, 1024 ; 32 x 32 lovebug
+.loop:
+ mov al, [ds:si]
+ cmp al, 64
+ jz .skip_pixel
+ mov [es:di], al
+.skip_pixel:
+ inc si
+ inc di
+
+ dec cx ; dec the num_pixels we want to write
+ jz .end ; all pixels have been written
+ test cx, 1fh ; keep 5 least significant bits, 3 most significant bits 0
+ jnz .loop ; when this is 0 we are in a multiple of 32
+ add di, 320 - 32 ; screen width - bug width
+ jmp .loop
+.end:
+ ret
+
+print_str:
+ ;Int 10/AH=0Eh
+ mov al, [si]
+ test al, al
+ jz .end
+ mov ah, 0eh
+ xor bx, bx
+ int 10h
+ inc si
+ jmp print_str
+.end:
+ ret
+
+print_num:
+ ; converts digits to ascii - print
+ push word 0
+ test ax, ax
+ jnz .conv_loop
+ push word '0'
+ jmp .conv_end
+.conv_loop:
+ test ax, ax
+ jz .conv_end
+ xor dx, dx
+ mov cx, 10
+ div cx ; ax contains cx / 10
+ add dl, '0'
+ push dx
+ jmp .conv_loop
+.conv_end:
+ mov bp, sp
+ mov ax, [ss:bp]
+ test ax, ax
+ jz .print_end
+ mov ah, 0eh
+ xor bx, bx
+ int 10h
+ add sp, 2
+ jmp .conv_end
+.print_end:
+ add sp, 2
+ ret
+
+; random number generator
+; by nuclear
+rand:
+ mov eax, [randval]
+ mul dword [randmul]
+ add eax, 12345
+ and eax, 0x7fffffff
+ mov [randval], eax
+ shr eax, 16
+ ret
+
+randmul dd 1103515245
+randval dd 0ace1h
+
+num_frames dw 0
+str_frames db 'frames: ', 0
+str_newline db 13, 10, 0 ; crlf carriage return line feed newline
+
+; db to write pixels transparent 255
+; @: transparent
+; A: black
+; B: gray
+; C: dark red
+; D: medium red
+; E: red
+lovebug:
+ db '@@@@BAAAB@@@@@BAAB@@@@@BAAAB@@@@'
+ db '@@@@@@@@AAAB@BAAAAB@BAAA@@@@@@@@'
+ db '@@@@@@@@@@@AAAAAAAAAA@@@@@@@@@@@'
+ db '@@@@@@@@@@@@AAAAAAAA@@@@@@@@@@@@'
+ db '@@@@@@@@@@@@AAAAAAAA@@@@@@@@@@@@'
+ db '@@@@@@@@@@@@BAAAAAAB@@@@@@@@@@@@'
+ db '@@@@@@@@@@@@@AAACAA@@@@@@@@@@@@@'
+ db '@@@@@@@@@@CDDEECDEEDDC@@@@@@@@@@'
+ db '@@@@@@@CDDEEEEEDCEEEEEDDC@@@@@@@'
+ db '@@@@@CDEEEEDCDECDEDCDEEEEDC@@@@@'
+ db '@@@@CDDCDEECACEDCECACEEDCDDC@@@@'
+ db '@@@CDECACEEDCDECDEDCDEECACEDC@@@'
+ db '@@@DEEDCDEEEEEEDCEEEEEEDCDEED@@@'
+ db '@@CEEEEEEEEEEEDCDDEEEEEEEEEEEC@@'
+ db '@@DEDCDEEEDCDECACCEDCDEEEDCDED@@'
+ db '@@EECACEEECACEDCDDECACEEECACEE@@'
+ db '@CEEDCDEEEDCDEEDCEEDCDEEEDCDEEC@'
+ db '@DEEEEEEEEEEEEDCCDEEEEEEEEEEEED@'
+ db 'CEEEEEEDCDEEEDCBACDEEEDCDEEEEEEC'
+ db 'CEDCDEECACEEDCAABACDEECACEEDCDEC'
+ db 'DECACEEDCDEDCAABAAACDEDCDEECACED'
+ db 'DEDCDEEEEEDCAAAABAAACDEEEEEDCDED'
+ db 'CEEEEEEEEECAAAABAAAAACEEEEEEEEEC'
+ db 'CEEEEEEEEDAAAAAABAAAAADEEEEEEEEC'
+ db '@DEDCDEEDCAAAAABAAAAAACDEEDCDED@'
+ db '@DECACEDCAAAAAAABAAAAAACDECACED@'
+ db '@DEDCDDCAAAAAAABAAAAAAAACDDCDED@'
+ db '@CEEEECAAAAAAAAABAAAAAAAACEEEEC@'
+ db '@@EEED@AAAAAAAABAAAAAAAAA@DEEE@@'
+ db '@@EEDC@@AAAAAAAABAAAAAAA@@CDEE@@'
+ db '@@DEC@@@@@AAAAABAAAAAA@@@@@CED@@'
+ db '@@@C@@@@@@@@AAAABAAA@@@@@@@@C@@@'
+
+ align 16 ; if the address is not a multiple of 16 add some 0 to become one (because we'll use backbuffer as a segment)
+backbuffer: