Starport BBS
VIEWER: tron.asm MODE: TEXT (ASCII)
;----------------------------------------------------------------------------
; tron.asm    public beta version 0.4   Copyright (C) 1997, brioche/aspirine
;----------------------------------------------------------------------------
; Kinda 2 player nibble game as seen in a well known old movie called 'Tron'
;----------------------------------------------------------------------------
; Mainly optimized for size but my first goal was to have fun! :)
; This proggy assumes that all the common registers are set to zero and that
; the direction flag is cleared...
; Nothing more to say about this source except that it has been assembled
; with some good old Borland tasm 3.1 and linked with tlink 5.1
;----------------------------------------------------------------------------
; Version 0.4 fixes another bug about the 'both crashed' case (4 bytes lost)
; and I'm wondering if it is really necessary to support the escape key...
; The brand new stuff is a few self-modifying code in the main loop, I saved
; plenty of bytes and ticks! assembler rules!
;----------------------------------------------------------------------------
; About the lack of comments: real coders don't need comments! :)
;----------------------------------------------------------------------------
; This is freeware but e-mails are welcome!    106146.1452@compuserve.com
;----------------------------------------------------------------------------

		.386
		.model  tiny

SC_ESC          equ     1                       ;several scancodes in use
SC_UP           equ     72                      
SC_DOWN         equ     80
SC_LEFT         equ     75
SC_RIGHT        equ     77
SC_A            equ     16
SC_Q            equ     30
SC_W            equ     44                      ;oops!
SC_X            equ     45                      ;azerty frenchy keyboard! :)

movseg          macro   _dst, _src              ;quite useful macro

		push    _src
		pop     _dst

		endm

code            segment use16

		assume  cs:code, ds:code, es:code, ss:code
		org     100h
		
start:          mov     al, 13h               	;init video mode
		int     10h

		xor     ax, ax                	;init palette
		mov     dx, 3c8h
		out     dx, al
		inc     dx
		mov     cl, 5*3
		mov     si, offset palette
		rep     outsb

		mov     ax, 3509h             	;init keyboard handler
		int     21h
		mov     word ptr old9, bx
		mov     word ptr old9+2, es
		mov     ah, 25h
		mov     dx, offset new9
		int     21h
		
		movseg  es, 0a000h              ;now es = VGA memory segment

		mov     eax, 01010101h          ;build the back grid
		xor     di, di

		mov     bl, 25                  ;draw inner grid
gridlp1:        mov     cx, 40*7
gridlp2:        stosb
		add     di, 7
		loop    gridlp2
		call	hline
		dec     bl
		jnz     gridlp1

		xor     di, di                  ;outer grid (game bounds)
		shl	eax, 1			;now, eax=02020202h
		call	hline
		mov     cl, 198
gridlp3:        stosb             
		add     di, 318
		stosb
		loop    gridlp3
		call	hline

mainloop:       mov     dx, 3dah                ;wait for vertical retrace
		in      al, dx			;to slow it down... :)
		test    al, 8			
		jz      $-3
		in      al, dx
		test    al, 8
		jnz     $-3

		mov	di, plyr1	        ;di = player1 offset
		mov	si, plyr2               ;si = player2 offset

		cli                             ;disable interrupts

		db	81h, 0c6h	        ;opcode of add di, xxxx
patch1:		dw	-1	

		db	81h, 0c7h	        ;opcode of add si, xxxx
patch2:		dw	1

		sti			        ;interrupts enabled now

		mov	plyr1, di		;save new offsets
		mov	plyr2, si

		cmp     byte ptr es:[di], 1
		seta    cl	                ;player1 crashed?
		
		cmp     byte ptr es:[si], 1
		seta    ch                      ;player2 crashed?

		mov     byte ptr es:[di], 3     ;draw both players on screen
		mov     byte ptr es:[si], 4 

		cmp	di, si			;both crashed
		je	bye

		jcxz	chkesc			;nobody crashed

		cmp	cl, ch
		jb	win1			;player1 wins
		ja	win2			;player2 wins
		je	bye			;both crashed on boundaries
				
chkesc:		cmp     escape, 0		;check if escape has been hit
		je      mainloop
		
		jmp     bye

win1:		mov	winplyr, '1'		;just show who won...
		jmp	bye

win2:           mov     winplyr, '2'

bye:        	mov     ax, 3   
		int     10h

		mov     ah, 09h                 ;print some messages
		mov	dx, offset msg-1	;get CR from the palette!
		int     21h                             

		lds     dx, dword ptr old9      ;reset keyboard stuff
		mov	ax, 2509h
		int     21h

		ret				;get back to DOS!

;-- new keyboard handler ----------------------------------------------------

new9:           push    ax		  	;ugly 'switch() case...'
		push    bx

		in      al, 60h
	
new9_esc:       cmp     al, SC_ESC              ;exit
		jne     new9_up1
	
		mov     escape, 1		;gosh! teacher's coming! :)
		jmp     new9_ack

new9_up1:       mov     bx, offset patch1

		cmp     al, SC_UP               ;player1 up
		jne     new9_down1

		jmp     mvup          

new9_down1:     cmp     al, SC_DOWN             ;player1 down
		jne     new9_left1

		jmp     mvdown

new9_left1:     cmp     al, SC_LEFT             ;player1 left
		jne     new9_right1
		
		jmp     mvleft

new9_right1:    cmp     al, SC_RIGHT            ;player1 right
		jne     new9_up2

		jmp     mvright

new9_up2:       mov     bx, offset patch2

		cmp     al, SC_A                ;player2 up
		jne     new9_down2
		
		jmp      mvup

new9_down2:     cmp     al, SC_Q                ;player2 down
		jne     new9_left2

		jmp     mvdown

new9_left2:     cmp     al, SC_W                ;player2 left
		jne     new9_right2
		
		jmp     mvleft

new9_right2:    cmp     al, SC_X                ;player2 right
		jne     new9_ack

		jmp     mvright

new9_ack:       in      al, 61h		  	;send release code to kb ctrl
		mov     ah, al
		or      al, 80h
		out     61h, al
		mov     al, ah
		out     61h, al

new9_eoi:       mov     al, 20h              	;end of interrupt
		out     20h, al

		pop     bx
		pop     ax

		iret

;-- misc support routines ---------------------------------------------------

mvup:           cmp     byte ptr [bx], (320 and 255)	;going down?
		je      new9_ack
		mov     word ptr [bx], -320
		jmp     new9_ack
		
mvdown:         cmp     byte ptr [bx], (-320 and 255)	;going up?
		je      new9_ack
		mov     word ptr [bx], 320
		jmp     new9_ack

mvleft:         cmp     byte ptr [bx], 1	;going right?
		je      new9_ack
		mov     word ptr [bx], -1
		jmp     new9_ack

mvright:        cmp     byte ptr [bx], -1	;going left?
		je      new9_ack
		mov     word ptr [bx], 1
		jmp     new9_ack

hline:		mov	cl, 80			;vacuum clouds...
		rep	stosd
		ret

;-- data --------------------------------------------------------------------

X1 		= 159-100			;initial coordinates
Y1		= 99
X2		= 159+100				
Y2		= 99

plyr1           dw	(Y1*320)+X1		;initial offsets
plyr2           dw	(Y2*320)+X2

escape          db      0

palette         db      3, 8, 13                ;bknd
		db      6, 11, 16               ;inner grid
		db      8, 13, 18               ;outer grid
		db      0, 29, 63               ;player2
		db      56, 0, 13               ;player1

msg          	db      10			;message
		db	'player '
winplyr         db      '?'			 
		db      ' wins!'
		db	13, 10, 10
		db      'brioche/aspirine$'              

old9            dd      0                       ;removable zero data


code            ends

		end     start           	 ;eat this! :)

[ RETURN TO DIRECTORY ]