public SetMode_, ResetMode_, GenTable_, CalcLife_
.486
.model flat
.code
VID_MODE equ 12h
X_SIZE equ 640
Y_SIZE equ 480
X_BYTES equ X_SIZE / 8
;----------------------------------------------------------
; void SetMode(void);
SetMode_ Proc
push eax ;Set the video mode
mov ax,VID_MODE
int 10h
pop eax
ret
SetMode_ EndP
;----------------------------------------------------------
; void ResetMode(void);
ResetMode_ Proc
push eax ;Set text mode
mov ax,3
int 10h
pop eax
ret
ResetMode_ EndP
;----------------------------------------------------------
; void GenTable(void *buf);
GenTable_ Proc
pushad ;Save all registers
mov edi,eax ;EDI = table pointer
xor esi,esi ;Zero ESI (counter)
gt_loop: xor al,al ;AL = 0
mov ebx,esi ;EBX = bits [ 1 ]
and ebx,038A38h
call gt_count ;Count bits
cmp cl,3
sete ah
cmp cl,2
jne gt_test2
test esi,000400h
setnz ah
gt_test2: shl ah,3 ;Add in bit
or al,ah
mov ebx,esi ;EBX = bits [ 2 ]
and ebx,01C51Ch
call gt_count ;Count bits
cmp cl,3
sete ah
cmp cl,2
jne gt_test3
test esi,000200h
setnz ah
gt_test3: shl ah,2 ;Add in bit
or al,ah
mov ebx,esi ;EBX = bits [ 3 ]
and ebx,00E28Eh
call gt_count ;Count bits
cmp cl,3
sete ah
cmp cl,2
jne gt_test4
test esi,000100h
setnz ah
gt_test4: shl ah,1 ;Add in bit
or al,ah
mov ebx,esi ;EBX = bits [ 4 ]
and ebx,007147h
call gt_count ;Count bits
cmp cl,3
sete ah
cmp cl,2
jne gt_lback
test esi,000080h
setnz ah
gt_lback: or al,ah ;Add in bit
stosb ;Store value
inc esi
cmp esi,040000h ;Loop back
jb gt_loop
popad ;Restore registers
ret ;Return
gt_count: mov ecx,ebx ;Collect bit pairs
shr ebx,1
and ecx,55555555h
and ebx,55555555h
add ebx,ecx
mov ecx,ebx ;Collect nibbles
shr ebx,2
and ecx,33333333h
and ebx,33333333h
add ebx,ecx
mov ecx,ebx ;Collect bytes
shr ebx,4
and ecx,0F0F0F0Fh
and ebx,0F0F0F0Fh
add ecx,ebx
add ch,cl ;CL = result
shr ecx,8
add cl,ch
ret ;Return
GenTable_ EndP
;----------------------------------------------------------
; void CalcLife(void *src, void *dest, void *table);
CalcLife_ Proc
pushad ;Save all registers
mov esi,eax ;ESI = source
mov edi,edx ;EDI = dest. - source
sub edi,esi ;EBP = table
mov ebp,ebx
mov ecx,X_BYTES ;ECX = X counter
add esi,ecx ;Start at row 2
cl_oloop: pushad ;Save all registers
mov eax,[esi-X_BYTES-1] ;Load initial values
call cl_shift
mov eax,[esi-1]
call cl_shift ;Clear top byte
mov byte ptr [esi+edi-X_BYTES],0
mov ecx,Y_SIZE - 2 ;ECX = Y size - 2
cl_loop: mov eax,[esi+X_BYTES-1] ;Get next row of bits
bswap eax ;Serialize bits in EAX
shl eax,7
shld ebx,eax,6 ;Shift into EBX and EDX
shl eax,4
shld edx,eax,6
and ebx,03FFFFh ;Mask to fit
and edx,03FFFFh
mov ah,[ebp+ebx] ;Look up values for 2 bytes
mov al,[ebp+edx]
shl ah,4
or al,ah
mov [esi+edi],al ;Write new value
add esi,X_BYTES ;Next row
dec ecx ;Loop back
jnz cl_loop
mov byte ptr [esi+edi],0 ;Clear bottom byte
popad ;Restore registers
inc esi ;Next column
dec ecx ;Loop back
jnz cl_oloop
popad ;Restore registers
ret ;Return
cl_shift: bswap eax ;Serialize bits in EAX
shl eax,7
shld ebx,eax,6 ;Shift into EBX and EDX
shl eax,4
shld edx,eax,6
ret
CalcLife_ EndP
End