ִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִ
; plasmoid/deep/thc 1996:
; code by plasmoid/deep/thc
ִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִ
vsync		macro
     		local	@@vs1, @@vs2
		mov	dx,03dah	; ש retrace sync...
@@vs1:		in	al,dx
		test	al,8
		jnz	@@vs1		; ש while not in display do.
@@vs2:		in	al,dx
		test	al,8
		jz	@@vs2		; ש while in display do
endm
ִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִ
.model small
.stack 400
.code
.386
		locals
scrwidth 	equ 	80
initheight	equ	00
vgaseg		equ	0a000h
ִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִ
.startup
c_site:		jmp	main
info		db	"ש code by plasmoid of deep ש"
ִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִ
blendout        proc    near
		mov     blendcount,00
		mov     bdirection,00
		jmp     blendit
blendin:        mov     blendcount,00
		mov     bdirection,3fh
blendit:        mov     cx,3fh
blending:       push    cx
		call    blend
		pop     cx
		loop    blending
		ret
blendout        endp
ִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִ
blend           proc near
		mov     si,offset vgapalette
		mov     dx,03c8h               ; ש write to PEL port
		mov     al,00h
		out     dx,al
		inc     dx

		mov     ah,blendcount
		xor     ah,bdirection

		mov     cx,256
@bchange:       lodsb
		add     al,ah
		cmp     al,3fh
		jb      $+4
		mov     al,3fh
		out     dx,al
		lodsb
		add     al,ah
		cmp     al,3fh
		jb      $+4
		mov     al,3fh
		out     dx,al
		lodsb
		add     al,ah
		cmp     al,3fh
		jb      $+4
		mov     al,3fh
		out     dx,al
		loop    @bchange
		inc     blendcount
@bskip:         ret
blendcount      db      00
bdirection      db      3fh
blend           endp

ִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִ
convert         proc    near
		xor     bx,bx
@@two:          mov     cx,bp           ; ש lg to cx
@@one:          xor     dx,dx
		mov     dl,ds:[si]      ; ש read from srce to dl
		shl     dx,4
		shr     dl,4
		add     dh,select
		mov     ds:[di],dh
		inc     di
		add     dl,select
		mov     ds:[di],dl
		inc     di
		inc     si
		loop    @@one
		dec     ax              ; ש dec
		jnz     @@two
		ret
select          db      00
convert         endp
ִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִ
ega2vga         proc    near
		mov     si,offset logo
		mov     di,offset vgalogo
		mov     ax,85
		mov     bp,256/2
		call    convert
		ret
ega2vga         endp
ִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִ
checkkey        proc    near
		cmp byte ptr keystroke,01
		je      escape
		jmp     no
escape:         jmp     exit
no:             ret
checkkey        endp
ִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִ
int_key         proc    near
		cli
		push    ax
		in      al,60h
		cmp     al,01                   ; ש escape
		je      put
		mov     cs:keystroke,00
		jmp     none                    ; ש none
put:            mov     cs:keystroke,al
none:           in      al,61h
		mov     ah,al
		or      al,80h
		out     61h,al
		sti
		mov     al,20h
		out     20h,al
		pop     ax
		iret
keystroke       db      00
int_key         endp
ִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִ
initkeyboard    proc    near
		cli
		push    fs
		xor     dx,dx
		mov     fs,dx
		mov     eax,fs:[9*4]
		mov     oldint9,eax
		mov     ax,cs
		shl     eax,16
		mov     ax,offset int_key
		mov     fs:[9*4],eax
		sti
		pop     fs
		ret
initkeyboard    endp
ִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִ
killkeyboard    proc near
		cli
		push    fs
		xor     dx,dx
		mov     fs,dx
		mov     eax,oldint9
		mov     fs:[9*4],eax
		sti
		pop     fs
		ret
killkeyboard    endp
ִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִ
timer           proc    near
		push    ax
		mov     al,20h
		out     20h,al
		inc     cs:counter
		inc     cs:int_1ch
		cmp     cs:int_1ch,22
		jb      no_int_1ch
		mov     cs:int_1ch,00
		int	1ch
no_int_1ch:     pop     ax
		iret
counter         dw      0
int_1ch         db      0
timer           endp
ִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִ
inittimer       proc    near
		cli
		push    gs
		xor     dx,dx
		mov     gs,dx
		mov     eax,gs:[8*4]
		mov     oldint8,eax
		mov     ax,cs
		shl     eax,16
		mov     ax,offset timer
		mov     dx,2841             ; ש 140 Hz double Screen Sync
		mov     gs:[8*4],eax

out_it:         mov     al,036h                 ; ש out these things, they
		out     43h,al                  ;   just remain a secret
		mov     al,dl                   ;   for me...
		out     40h,al
		mov     al,dh
		out     40h,al
		sti
		pop     gs
		ret
inittimer       endp
ִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִ
killtimer       proc near
		push    gs
		xor     dx,dx
		mov     gs,dx
		cli
		mov     eax,oldint8
		mov     gs:[8*4],eax
		jmp     out_it
killtimer       endp
ִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִ
initvideo	proc	near
 		call	zeropalette
		mov	ax,13h
		int	10h
		call	zeropalette
		vsync

		mov	dx,3c0h
		mov	al,30h
		out	dx,al
		mov	al,01100001b
		out	dx,al
		mov	dx,3c4h			; ש unchain mode!
		mov	ax,604h
		out	dx,ax
		mov	dx,3d4h			; ש four chain mode
		mov	ax,14h
		out	dx,ax
		mov	ax,0e317h
		out	dx,ax
		mov	dx,3c4h			; ש all planes
		mov	ax,0f02h
		out	dx,ax
		mov	dx,3ceh			; ש bitmasking
		mov	ax,0ff08h
		out	dx,ax

		push	@data
		pop	ds
		push	0a000h
		pop	es
		xor	di,di
		xor	eax,eax
		mov	cx,8000h/2
		rep	stosd			; ש clear screen
		call	setpalette
		ret
initvideo	endp
ִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִ
killvideo	proc	near
		mov     ah,12h  	        ; ש restore palette
		mov     bl,31h
		mov     al,00h
		int     10h

		mov     ax,0003h		; ש text mode!
		int     10h
		ret
killvideo	endp
ִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִ
zeropalette	proc	near
		mov     dx,03c8h                ; ש port PEL write mode
		mov     al,00h                  ;   at register 00h
		out     dx,al
		xor	al,al
		inc     dx                      ; ש port PEL data register
		mov     cx,0100h*3
@clear:		out	dx,al
		loop	@clear
		ret
zeropalette	endp
ִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִ
setpalette 	proc	near
		mov     si,offset vgapalette
		mov     dx,03c8h                ; ש port PEL write mode
		mov     al,00h                  ;   at register 00h
		out     dx,al
		inc     dx                      ; ש port PEL data register
		mov     cx,0100h*3
		rep     outsb
		ret                             ; ש vga color a 100h times
setpalette	endp
ִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִ
; =======================================
; Arrrrgghhhhhhh!!! So many comments!! %-P
; Can't bear it: I know how it works, I intended
; to do it just this way, messy as it looks.

GenerateLand:
		push	es
        MOV     CX,320                  ; This many points to generate.
        MOV     SI,OFFSET LastLine      ; Last line is in SI.
        MOV     DI,OFFSET ThisLine      ; New values in DI.

        MOV     DX,[SI+319*2]   ; DX will mean height of the (X-1) point.
                                ; We need a starting value for it, so...
    @@l1:
        PUSH    CX
        call    Random
        AND     AX,4*1024-1     ; 0 <= AX <= 4*1024-1
        ADD     AX,AX           ; 0 <= AX <= 8*1024-2

        MOV     BX,[DI]
        SUB     BX,[DI-2]       ; Get horiz. slope of prev. line.
        JNC     @@up            ; If it was negative ( -> down) we'll go up.
     @@dn:                      ; -3*1024 < AX < 5*1024. A neat trick here:
         SUB    AX,3*1024-3     ; -3 => A global tendency upwards.
         JMP    @@put           ;   The top limit will do the rest. It works!
     @@up:
         SUB    AX,5*1024-1     ; If it was positive ( -> up) we'll go down.
                                ; -5*1024 < AX < 3*1024. No tricks now.
     @@put:                             
         MOV    BP,DX           ; DX is (X-1) height. Save in BP.
                                ; AX is horiz. slope.
         ADD    AX,DX           ; Create new height.
         
         CMP    BP,8000         ; Detect overflow. Quite shitty, but works.
         JNC    @@chk0          ; If height of X-1 was below 8000 and
          CMP   AX,65536-8000   ; new height is above 65536-8000 (or
          JC    @@ok0           ; viceversa), there has been a rollover.
           MOV  AX,BP           ; In that case, stick to height of X-1.
           JMP  @@ok0
    @@chk0:
         CMP    BP,65536-8000   ; Here comes the viceversa. ;-)
         JC     @@ok0
          CMP   AX,8000
          JNC   @@ok0
           MOV  AX,BP           ; In that case, stick to height of X-1.
      @@ok0:

         MOV    BX,[SI+2]       ; Now average height with previous line.
         ADD    BX,[SI+4]       ; X+1 & X+2 seem to avoid diagonals.
         RCR    BX,1
         ADD    AX,BX
         RCR    AX,1
         
         CMP    AX,[HLimit]     ; Absolute maximum.
         JC     @@notop
          MOV   AX,BP ;[HLimit]
     @@notop:

         MOV    [DI],AX         ; Store new height, and save in DX for X+1.
         MOV    BP,DX
         MOV    DX,AX

    @@dofilter:
         ADD    AX,[DI+320*2*2] ; Filter height value for screen color.
         RCR    AX,1
         MOV    BX,[LastValue]  ; This will make the landscape look nicer.
         ADD    AX,BX
         RCR    AX,1

   @@setval:
         MOV    [DI+320*2*2],AX ; Store the screen values, at last...
         MOV    [LastValue],AX

         ADD    DI,2            ; Now, do the usual loop arrangements.
         ADD    SI,2
         POP    CX
         DEC    CX
         JNZ    SMALL @@l1


        MOV     AX,DS           ; Now copy buffers to nice positions.
        MOV     ES,AX           ; No more comments from now on.

        MOV     DI,OFFSET LastLine
        MOV     SI,OFFSET ThisLine
        MOV     CX,320/2
        REP MOVSD

        MOV     DI,OFFSET LastLine-160*2
        MOV     SI,OFFSET LastLine+160*2
        MOV     CX,160/2
        REP MOVSD
        MOV     DI,OFFSET LastLine+320*2
        MOV     SI,OFFSET LastLine
        MOV     CX,160/2
        REP MOVSD

		pop	es
        RET
ִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִ

; =======================================

DumpLandLine:
        MOV     DX,3CEh                 ; Bitmask...
        MOV     AX,0FF08h               ; 11111111b
        OUT     DX,AX

        MOV     SI,OFFSET  DrawLine+1  ; ThisLine+1
        MOV     AX,102h
    @@l1:
        PUSH    AX
        MOV     DX,3C4h
        OUT     DX,AX

        MOV     DI,[ScrollPos]
        MOV     CX,SCRWidth/2
    @@l2:
         MOV    AL,[SI]
         MOV    AH,[SI+8]
         MOV    ES:[DI+201*SCRWidth],AX
         MOV    ES:[DI+402*SCRWidth],AX
         STOSW
         ADD    SI,16
         LOOP   @@l2

        SUB     SI,16*SCRWidth/2-2
        POP     AX
        SHL     AH,1
        JNC     @@l1

        RET
ִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִ
initland	proc	near
		push	es
		push	ds
		pop	es
		mov	ax,initheight
		mov	di,offset initinitial
		mov	cx,(offset endinitial-offset initinitial)/2
		rep	stosw
		xor	ax,ax
		mov	di,offset initzero
		mov	cx,(offset endzero-offset initzero)/4
		rep	stosd
		pop	es
		ret
initland	endp
ִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִ
doframing	proc	near
		inc	framenumber
		ret
doframing	endp
ִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִ
checkheight	proc	near
		cmp	framenumber,250
		jc	carry2
		add	hlimit,50h
		cmp	hlimit,0f000h
		jc	carry3
		mov	hlimit,0f000h
		jmp	carry3
carry2:		add	hlimit,1000h/250*2
carry3:		ret
checkheight	endp
ִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִ
movelandline	proc	near
		cli
		mov	bx,[scrollpos]
		mov	dx,03d4h
		mov	al,0ch
		mov	ah,bh
		out	dx,ax			; ש high byte
		inc	al
		mov	ah,bl
		out	dx,ax			; ש low byte
		sti

		sub	scrshown,scrwidth
		sub	scrnext,scrwidth
		sub	bx,scrwidth
		jnc	@@okay
		add	bx,201*scrwidth
		add	scrshown,201*scrwidth
		add	scrnext,201*scrwidth
@@okay:		mov	scrollpos,bx
		ret
movelandline	endp
ִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִ
savescreen	proc	near
		push	ds
		push	seg screen
		pop	ds
		mov	si,scrshown
		mov	di,offset screen
		mov	cx,320*200
@saveit:	mov	bx,si
		mov     al,04                   ; ש read mask
		mov     ah,bl                   ; ש x position
		and     ah,3
		mov     dx,3ceh
		out     dx,ax
		shr	bx,2
		mov     al,es:[bx]
		mov	[di],0
		inc	di
		inc	si
		loop	@saveit

		mov	bx,[scrollpos]
		mov	dx,03d4h
		mov	al,0ch
		mov	ah,00
		out	dx,ax			; ש high byte
		inc	al
		mov	ah,00
		out	dx,ax			; ש low byte

		mov	dx,3d4h			; ש four chain mode
   		mov	ax,14h*2
   		out	dx,ax
   		mov	ax,0e317h
   		out	dx,ax
		mov	ax,01340h
		out	dx,ax

		mov	si,offset screen
		mov	di,0
		mov	cx,320*200/4
		rep	movsd
		pop	ds
		ret
savescreen	endp
ִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִ
random		proc	near
		mov	ax,randseed1
		mov	bx,randseed2
		add	ax,0a137h
		add	bx,063f7h
		rol	ax,2
		mov	randseed1,ax
		add	bx,ax
		ror	bx,1
		mov	randseed2,bx
		add	ax,bx
		ret
random		endp
ִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִ
displaylogo	proc	near
		cmp	framenumber,1615
		jb	skip
		cmp	logopos,0
		je	skip
		mov	di,offset drawline+1+32*2
		mov	si,offset vgalogo
		add	si,logopos
		mov	cx,256
invert:		mov	al,[si]
		cmp	al,00
		je	noinv1
		add	byte ptr [di],38
noinv1:		inc	si
		inc	di
		inc	di
		loop	invert
		sub	logopos,256
skip:		ret
displaylogo	endp
ִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִ
main:		call	inittimer
		call	initkeyboard
		call	initvideo
		call	initland
		call	ega2vga
scape: 		vsync
		call	doframing
		call	displaylogo
		call	dumplandline
		call	checkheight
		call	movelandline
		call	generateland
		call	checkkey
		cmp	framenumber,1750;      1335
		jb	scape
		vsync
		call	blendout
		vsync
		;call	savescreen
		call	blendin
warp:		vsync
		call	doframing
		call	checkkey
		jmp	warp

exit:   	call    zeropalette
		call	killvideo
		call	killkeyboard
		call	killtimer
		mov	ax,4c00h
		int	21h
ִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִ
.data
oldint9         dd      ?
oldint8         dd      ?

randseed1	dw	348bh
randseed2	dw	7f34h

logopos		dw	256*84
scrollpos	dw	0		; ש memory offset of upper line.
scrshown	dw	0	        ; ש base offset of currently screen
scrnext		dw	201*scrwidth	; ש "	  "	of updating screen
include		fire.pal
include		f-scape.dat
ִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִ
udataseg
initinitial	label 	word
lastvalue	dw	?
lastvalue2	dw	?

		dw	160 dup (?)
lastline	dw	320 dup (?)
		dw	160 dup (?)
endinitial 	label	word

initzero   	label	word
vgalogo		db	256*85 dup (?)

thisline	dw	320 dup (?)
slopes		dw	320 dup (?)
drawline	dw	320 dup (?)

updatescr	dw	?

framenumber	dd	?
hlimit		dw	?
lastslope	dw	?
endzero    	label	word
ִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִ
.fardata
screen		db	320*200 dup (?)
ִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִִ
end
