Copy Link
Add to Bookmark
Report
Xine - issue #3 - Phile 310
/-----------------------------\
| Xine - issue #3 - Phile 310 |
\-----------------------------/
;
; -* Mini Conway game of life emulator *-
;
; Writed and commented by [StarZer0/ikx] a drunk night
;
; Double 64 ko segment to fix up speed
; Vga sync mutation , just to be visible for eye
; Lif file format 1.05 detected & suported
; Support Ascii lif format
; Use ESC to quit the game
;
;
.model tiny
.code
.286
org 100h
start:
call allocate ; allocate 64k segment
mov word ptr cs:[binbuffer],ax ; save value placed in ax
call clearzone
call allocate ; allocate 64k segment
mov word ptr cs:[segbuffer],ax ; save value placed in ax
call clearzone
call analyse ; analyse the command line
; open the file and put it
; on the buffer , display comment
xor ax,ax
int 16h ; wait for a keyboard reaction
mov ax,0013h
int 10h ; Video Function CalL
call segtobin ; display the file to screen
call bintovid
xor ax,ax
int 16h ; wait for keyboard reaction
rendergen:
mov ax,word ptr cs:[binbuffer]
call clearzone ; clear teh binary buffer
push word ptr cs:[segbuffer]
push word ptr cs:[binbuffer]
pop es
pop ds
call nextgeneration ; render next generation state
; result placed in bin
call bintoseg ; copy binary into seg
call bintovid ; copy bin to video
xor ax,ax
inc ah
int 16h ; test if ax = ESC
jz rendergen ;if so quit , else the continue
xor ax,ax
int 16h
cmp al,27
jne rendergen
mov ah,03h ; restore video format 80x25x16
int 10h
finish: call delocate ; restore segments
call delocate
ret ; quit!
segtobin:
push es ; push datas on the segbuffer
push ds ; on the binbuffer
push word ptr cs:[segbuffer]
pop ds
push word ptr cs:[binbuffer]
pop es
jmp repzit
bintoseg: ; put datas on the bin buffer
; into the segbuffer
push es
push ds
push word ptr cs:[binbuffer]
pop ds
push word ptr cs:[segbuffer]
pop es
jmp repzit
bintovid: ; put datas in the bin buffer
; into Bios video (0A000h)
push es
push ds
push 0A000h
pop es
push word ptr cs:[binbuffer]
pop ds
repzit: mov cx,64000 ; the copier
xor si,si
xor di,di
repz movsb
pop ds
pop es
ret
nextgeneration: ; rendering next generation
xor ax,ax
mov cx ,0ffffh
cxsaver:
push cx
call rendersquare ; render for the entire segment
pop cx
inc si
loop cxsaver
ret
rendersquare: ; here we render if the case
; died or rest alive
mov cx,3 ; we render 9 square , 3 upper
xor bx,bx ; 3 center , 3 low
push si ; -1
sub si,320+1
mytype:
add bl,byte ptr ds:[si]
inc si
add bl,byte ptr ds:[si]
inc si
add bl,byte ptr ds:[si]
inc si
add si,320-3
loop mytype ; render 3 times successive 3 block
pop si
sub bl,byte ptr ds:[si] ; sub the center block
cmp bl,02h
je restquare ; rest in life
cmp bl,03h
jne setasdeath ; if different then die
mov byte ptr es:[si],01h ; set alive
ret
restquare: ;
mov al,byte ptr ds:[si] ; change nothing
mov byte ptr es:[si],al
ret
setasdeath:
mov byte ptr es:[si],0 ; kill the life
ret
clearzone: ; put a max of zero into the
; ax segment
push es
mov es,ax
xor di,di
xor ax,ax
mov cx,0ffffh
repz stosw
pop es
ret
allocate: ; memory allocator , 64k seg
push cs
push cs
mov ah,4ah
mov bx,0ffffh
int 21h
mov ah,4ah
sub bx,0ffffh/16+2
int 21h
mov ah,48h
mov bx,0ffffh/16+1
int 21h
pop es
pop ds
ret
delocate: ; delocate
mov ah,49h
int 21h
ret
analyse:
mov si,82h
mov cx,13 ;
cmp byte ptr [si-1],0dh ; if no command line
jne analyseloop
mov bp,offset trademark ; display trademark
mov cx,endoftrade-trademark ; and quit
call display0
pop ax
jmp finish
analyseloop: ; put a zero after the file
; in the command line
cmp byte ptr [si],0dh
jz endanalyseloop
inc si
loop analyseloop
endanalyseloop:
mov byte ptr [si],0
mov ax,3d00h ; open this file
xor cx,cx
push cs
pop ds
mov dx,82h
int 21h
xchg ax,bx
jnc noproblem ; if error then display msg &
; quit
mov bp,offset filenoexist
mov cx,endoffile-filenoexist
call display0
pop ax
jmp finish
noproblem:
mov ax,4202h ; go to the end
xor cx,cx
xor dx,dx
int 21h
push ax ; save file size
push ax
mov ax,4200h ; go to the begin
xor cx,cx
xor dx,dx
int 21h
mov ah,3fh ; read cx bytes in the files
pop cx
mov dx,offset filebuffer
int 21h
mov ah,3eh ; close the file
int 21h
mov si,offset filebuffer ; si =
cmp word ptr [si],'L#' ; set if the file begin '#L'
je lifanalyzor ; then lif file detected
mov si,offset filebuffer ; analyse the file
mov di,(320*50)+160
pop cx ; cx = size
xor bp,bp
push ds
push word ptr cs:[segbuffer]
pop ds
analyseloop2:
mov ah,byte ptr cs:[si]
cmp ah,0ah ; detect if end of line
jne analyseloop2bis ; if so then goto at the next
; line
sub di,bp
add di,320
xor bp,bp
analyseloop2bis:
cmp ah,48 ;
jb dontputit ; if not 0 and 1 then skip it
cmp ah,49 ;
ja dontputit
sub ah,30h ; ah = 1 or 0
mov byte ptr ds:[di],ah ; put it into the buffer
inc bp
inc di
dontputit:
inc si
loop analyseloop2
pop ds ; restore ds
ret ; and return
lifanalyzor:
mov si,offset filebuffer
pop cx
inc cx
call verifyversion ; verify if compatible version
midlooping:
cmp word ptr [si],'C#' ; detect if comment line
je putcommentonlife
cmp word ptr [si],'D#'
je putcommentonlife ; detect if comment line
cmp word ptr [si],'R#' ; detect if new rules
je setrules ; never used
cmp word ptr [si],'N#' ; Normal conway rules
je setconwayrules ; never used
cmp word ptr [si],'P#' ; start of datas
je putdatas
inc si
loop midlooping
invalidLif:
jmp finish_and_display ; display error message
putcommentonlife:
push cx
call getendofline ; get end of line (0A0Bh)
; bx return length
push si
add si,2
push bx
push bx
mov ah,03h ; print the comment
xor bx,bx
int 10h
mov ax,1301h
mov bx,7
pop cx
sub cx,2 ; skip the #D or #C
mov bp,si
int 10h
pop bx
pop si
add si,bx ; go to next si
pop cx ; and sub cx
sub cx,bx
jmp midlooping ; continue loop
putdatas:
call analysedatas ; continue alayzing
ret
setrules: ; analyze rules
push cx
call getendofline
push bx
push si
xor bx,bx
mov cx,8
thiscx0:
mov ah,byte ptr [si+bx+3]
cmp ah,'/'
je nixloop
sub ah,30h
mov byte ptr [settable1+bx],ah ; put rest in life
inc bx ; rules into settable
loop thiscx0
nixloop:
add si,bx
mov cx,8
thiscx1:
mov ah,byte ptr [si+bx+1] ; put born rules into
cmp ah,0dh ; settable2
je endofnix
sub ah,30h
mov byte ptr [settable2+bx],ah
inc bx
loop thiscx1
endofnix:
add si,bx
pop si
pop bx
pop cx
add si,bx ; goto next line
sub cx,bx ; continue looping
jmp midlooping
setconwayrules:
mov byte ptr [conwayflag],1 ; set switch on
add si,4
sub cx,4
jmp midlooping ; and continue looping
verifyversion: ; verify if version = 1.05
push cx
cmp byte ptr [si+6],'1'
ja invalid_version
mov ax,word ptr [si+6+2]
sub ax,3030h
xchg ah,al
cmp ax,05h
ja invalid_version
call getendofline
add si,bx
pop cx
sub cx,bx
ret
invalid_version:
pop ax
jmp invalidlif
getendofline: ; we scan the string for an
; 0D0Ah
push si
push cx
mov cx,80
xor bx,bx
founded:
cmp word ptr [si],0a0dh
je endfounded
inc bx
inc si
loop founded
endfounded:
inc bx
inc bx
pop cx
pop si
ret
analysedatas: ; analyse if we need to change location
; or put datas on buffer
push cx
analysedatas0:
pop cx
cmp word ptr [si],'P#'
jne analyse2bis ; change location code
call analyseposition
analyse2bis:
call putlineonbuffer ; else we put datas on buffer (*.)
push cx
dec cx
pushf
jc analyseOver
popf
jnz analysedatas0
pushf
analyseOver:
popf
pop ax
ret
putlineonbuffer:
push cx
call getendofline
push si
push bx
push es
push word ptr [segbuffer] ; set put on the buffer
pop es
xor bp,bp
mov cx,bx
sub cx,2
looponbuffer:
mov ah,byte ptr [si]
cmp ah,'*'
je putaone ; if any * the put 01h on buffer
mov ah,byte ptr [si]
cmp ah,'.'
je nothingtoput
dec di
jmp nothingtoput
putaone:
mov byte ptr es:[di],01
nothingtoput:
inc di
inc si
inc bp
loop looponbuffer
cmp byte ptr [si],'.' ; if last byte equal . the next line is
je skipcount ; concatenate
add di,320
sub di,bp
skipcount:
pop es
pop bx
pop si
pop cx
add si,bx
sub cx,bx
ret
analyseposition:
push cx
call getendofline
push bx
push si
add si,3
xor ax,ax
xor dx,dx
xor bp,bp ; bp = negative flag
stoof1:
mov dl,byte ptr [si]
cmp byte ptr [si+1],32
je endofstoof1
cmp dl,'-' ; negative number
jne positivecounter0
inc bp
inc si
jmp stoof1
positivecounter0:
sub dl,30h ; analyse number with base 10
add ax,dx ; 1234 =
mov bx,10 ; ((((1)*10)+2)*10)+3)*10)+4)
mul bx
inc si
jmp stoof1 ; loop until space detected
endofstoof1:
sub dl,30h
add ax,dx
mov bx,320
mul bx
mov dx,(320*100) ; do it over vertical position
cmp bp,0
je okaymag1 ; for negative counter
sub dx,ax
sub dx,ax
okaymag1:
add dx,ax
push dx
add si,2
xor dx,dx
xor ax,ax
xor bp,bp
stoof2: ; the same thing than upper
; but for vertical postion
mov dl,byte ptr [si]
cmp byte ptr [si+1],0dh
je endofstoof2
cmp dl,'-'
jne positivecounter
inc bp
inc si
jmp stoof2
positivecounter:
sub dl,30h
add ax,dx
mov bx,10
mul bx
inc si
jmp stoof2
endofstoof2:
sub dl,30h
add ax,dx
pop di
add di,160
cmp bp,0
je okaymag2
sub di,ax
sub di,ax
okaymag2:
add di,ax
pop si
pop bx
pop cx
sub cx,bx ; get next line
add si,bx ; sub the counter
ret
finish_and_display: ; display error mess.
mov bp,offset errormsg
mov cx,endoferrormsg-errormsg
call display0
pop ax
pop ax
jmp finish
display0: ; display string on
; screen
push cx
mov ah,03h
xor bx,bx
int 10h
pop cx
mov ax,1301h
mov bx,7
int 10h
ret
trademark: db ' Mini Conway Game emulator version &0.5 ',10,13
db ' By StarZer0 , Ikx(C) 1998 - Sourceware ' ,10,13
db 10,13
db ' use : lifegame filename.lif ' ,10,13
endoftrade:
errormsg: db 10,13
db ' *** Invalid Lif format or unrecognized version',10,13
endoferrormsg:
filenoexist: db ' File not found ',10,13
endoffile:
conwayflag: db 0
settable1: db 9 dup (9)
settable2: db 9 dup (9)
binbuffer: dw ?
segbuffer: dw ?
filebuffer: db ?
end start