Last active
December 20, 2015 21:09
-
-
Save Xom/6195195 to your computer and use it in GitHub Desktop.
pongvoll.asm
Get binary from http://xomnom.com/pongvoll.zip
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
PONG VOLLEYBALL | |
Xomnom | |
https://gist.github.com/xomnom | |
target platform: DOSBox | |
screen guide: | |
grey - walls, ceiling, net | |
yellow - floors | |
white - balls | |
green - paddles | |
blue, red - projectiles | |
magenta - score | |
cyan - meter | |
objective: | |
Score five (or more) points to win the match. | |
Point(s) are awarded when opponent faults. | |
Letting a ball hit floor is a fault. | |
Letting paddle hit a stationary projectile is a fault. | |
New round starts after each fault. | |
universal controls: | |
escape - force-quit | |
P1 controls: | |
W - up | |
A - left | |
D - right | |
S - special | |
P2 controls: | |
up arrow - up | |
left arrow - left | |
right arrow - right | |
down arrow - special | |
special meter: | |
Meter charges when balls hit opponent's ceiling; overflow depletes. | |
Pressing "down" stops paddle if in motion. If already stationary, | |
if at least 30% meter and you haven't six already, subtracts that much | |
meter and deploys a projectile; otherwise activates doubling cube if | |
permitted. Single fault may be canceled with 60% meter. | |
projectiles: | |
Travels to opponent's side when deployed (blue); specials cannot be | |
activated by either player until projectile reaches | |
destination and becomes stationary (red). | |
Deliberately nameless; come up with your own nickname. | |
doubling cube: | |
Please refer to Wikipedia for explanation: | |
http://en.wikipedia.org/wiki/Backgammon#Doubling_cube | |
Crawford rule is in effect; "beaver", "raccoon", other rules aren't. | |
Extra balls appear at double and octuple stakes. | |
Stakes, projectiles, extra balls, etc. reset at new round. | |
collision physics: | |
Net, stationary paddle bounces balls à la Pong / Breakout. | |
Stationary projectile sends ball down. | |
Moving paddle bounces balls erratically (but always up). | |
hints: | |
Frame rate is a little under 20 FPS. | |
Only positive-edge keystrokes are processed; auto-repeat is | |
deliberately at default, non-useful setting to discourage | |
holding keys down. | |
Input is ignored during long beeps. | |
Spawn positions in new rounds depend upon prior positions. | |
Projectiles won't deploy if below top of net. | |
Doubling becomes a good idea with roughly three-to-one favorable odds. | |
Paddles can't chase balls downward, so be careful when venturing high. | |
I'm really paranoid about having missed something here. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
PONG VOLLEYBALL | |
-- | |
NOTES FROM 2013: | |
Xomnom | |
https://gist.github.com/xomnom | |
Pong Volleyball and this report on it were originally written for a class | |
project. Some personal information has been removed from these files. | |
'pongvoll.asm' is targeted at the Dewar Assembler, which AFAICT is only | |
used to teach CS at NYU, but is very close to MASM (Microsoft Assembler). | |
A binary is available at: http://xomnom.com/pongvoll.zip | |
You may also need DOSBox, depending on your system. | |
(see [C1] [PLATFORM]) | |
Edit: I forgot to mention I was in my first year of college when I made this. | |
END NOTES FROM 2013. | |
-- | |
[AA] [CONTENTS] | |
[AB] [FILES] | |
[AC] [MODULES] | |
[AD] [EXTERNALCODE] | |
[B1] [OVERVIEW] | |
[B2] [OBJECTIVE] | |
[C1] [PLATFORM] | |
[C2] [INSTRUCTIONS] | |
[C3] [PROBLEMS] | |
[D1] [TECHNICAL] | |
[EE] [POSTMORTEM] | |
[AB] [FILES] | |
devnotes.txt | |
> This report. | |
pongvoll.asm | |
> [AC] This file contains all of the game's source code. | |
readme.txt | |
> "This game is bloody complicated. | |
> You need to read the full instructions." | |
[AD] [EXTERNALCODE] | |
Several procedures were borrowed from Dewar's | |
"Demonstration color/graphics program" | |
> "Routine to play note on speaker" | |
> "Write Message Routine" | |
Code was also borrowed from 'printstr.asm'. | |
[B1] [OVERVIEW] | |
This game is a finished product and implements exactly what I had in mind, no | |
more and no less. That has been my intention from the moment I started | |
coding; therefore I coded with significant disregard for ease of refactoring. | |
[B2] [OBJECTIVE] | |
Prevent balls from colliding with your floor. | |
Prevent your paddle from colliding with projectiles. | |
Matches are to five points. | |
There is a Doubling Cube. | |
[C1] [PLATFORM] | |
DOSBox is defined as the target platform. | |
All modern computers should be capable; | |
likewise with the IBM-PCs DOSBox is designed to emulate. | |
[C2] [INSTRUCTIONS] | |
See README file; it and either the binary or the source are the only files | |
with which a hypothetical end-user would hypothetically be presented. | |
Escape to force-quit. | |
[C3] [PROBLEMS] | |
For gameplay hints, see README file. | |
It is possible for the erasure of a ball's or player's previous position | |
to cover another ball or for the former to disfigure the net; both glitches | |
are both incredibly rare and extremely inconsequential. | |
If both players attempt to activate specials during the same frame, | |
the outcome is determined by the vagaries of the keystroke buffer. | |
[D1] [TECHNICAL] | |
Since my code is poorly commented, I will give an overview of the structure | |
and point out anything interesting as I go. Note that after a certain point | |
I tried to avoid fanciness, even at the cost of more lines of code, due to | |
error-prone-ness in my fatigued state (I even had a fever a day or two ago; | |
if I'd written this yesterday it would've been whining, but somehow now it | |
feels like boasting). | |
From the top: | |
> code from 'printstr.asm' | |
Some perfunctory text to satisfy bureaucratic requirements, followed by a | |
stern warning to ignore said snippets, and RTFM. It is possible to quit out | |
at this message with Escape; if you weren't aware, you probably should've. | |
> variables | |
Arrays are uniformly DW for the sake of pointer loops. | |
> draw environment | |
What isn't in procedures, mostly never needs redrawing. There is a CEILP | |
procedure that redraws the half of the ceiling used for message text. | |
Oh, and mode is 320x200 4-bit color. | |
> process keystrokes | |
Pretty standard fare; I'm sure everyone has one of these loops. | |
Contained therein is all of the logic for activating specials: | |
> special activation | |
Giant collection of branching ifs. One of the many blocks of code that has to | |
be duplicated and tweaked for each side; I don't think there's a better way to | |
do it, though (what I would give for the (foo ? bar : baz) construction!). | |
> ball movement | |
90% collision code; pointer loop pretty much required, so I'm glad I wrote | |
this part early on. Basically, there's paddles and balls, and then there's | |
projectiles and the environment; the former collide with each of the other | |
three. Paddle-ball collision is handled by inside the pointer loop for ball | |
movement. Ball collision in general is handled in reverse order of priority | |
with respect to effect on direction of travel. Side effects are also handled | |
inside the loop. | |
> projectile movement | |
Only one projectile is allowed to be traveling across the screen at a time. | |
Some messy pointer loops are used to append to the list of non-traveling | |
projectile properties. I coded those after I mangled my sleep schedule, but | |
if my memory is reliable (I doubt it), it went surprisingly smoothly (unlike | |
everything else). | |
> paddle movement | |
Again, duplicate code per side. "; redraw is coded the lazy way". As long as | |
paddle isn't moving, no redraw, with added benefit of no "lazy way" flicker. | |
> win conditions | |
There is an egregiously named variable, LOCAL, which tracks how many loss | |
conditions are encountered during the progression of each frame. At the end | |
of the tally, only the difference between the sides matters; if only by one, | |
60% meter is burnt if available (surrender (doubling cube) is worth sixteen, | |
enough to guarantee round loss. | |
> quit game | |
Following the main loop, of course. Most of the logic is in procedure RESET. | |
> paint procedures | |
A separate one for each shape. Note the weird loops that draw two rows per | |
iteration. Behavior with regard to preserving registers is inconsistent | |
across shapes. Meter update, which can be caused by all sorts of things, | |
is responsible for calling the short beeps you hear during the game. | |
> doubling cube | |
Changes a bunch of stuff; really quite messy. | |
> reset (new round) | |
Changes even more stuff; even messier. On match conclusion, pops procedure | |
call off stack and jumps directly to QUIT. | |
> 'pg4.asm' procedures | |
I bet everyone has these, too. | |
[EE] [POSTMORTEM] | |
Continued from: [B1] [OVERVIEW] | |
Assembly makes other languages look a lot less scary. | |
I came up with the doubling cube before the projectiles. | |
A doubling cube is an ideal litmus test for non-trivial positional advantages. | |
I've never played Backgammon, but doubling cubes are just that awesome. | |
[EF] [ENDOFFILE] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
; PONG VOLLEYBALL | |
; | |
; Xomnom | |
; https://gist.github.com/xomnom | |
; | |
; target platform: DOSBox | |
; | |
; source: printstr.asm | |
mov di, 0 | |
help: mov al, rules[di] ;get next char | |
cmp al, 0 | |
je okay | |
mov ah, 0eh | |
xor bh, bh | |
int 10h | |
inc di ;point to next char | |
jmp help | |
; await keystroke | |
okay: xor ah, ah | |
int 16h | |
cmp ah, 1 | |
je ohno | |
jmp init ; skip variables | |
ohno: int 20h ; HALT! | |
; variables | |
rules db 0Dh, 0Ah, 'PONG VOLLEYBALL', 0Dh, 0Ah | |
db 'by Xomnom ', 0Dh, 0Ah, 0Dh, 0Ah | |
db 'http://git.io/VaJDfA', 0Dh, 0Ah | |
db 'Spring 2009 ', 0Dh, 0Ah, 0Dh, 0Ah | |
db 'target platform: DOSBox', 0Dh, 0Ah, 0Dh, 0Ah | |
db 'P1 controls:', 0Dh, 0Ah | |
db ' W: up A: left D: right', 0Dh, 0Ah | |
db ' S: special abilities', 0Dh, 0Ah, 0Dh, 0Ah | |
db 'P2 controls:', 0Dh, 0Ah | |
db ' layout as P1, but with arrow keys', 0Dh, 0Ah, 0Dh, 0Ah | |
db ' escape: quit game', 0Dh, 0Ah, 0Dh, 0Ah | |
db 'WARNING: This game is bloody complicated.', 0Dh, 0Ah | |
db ' You need to read the full instructions.' | |
db 0Dh, 0Ah, 0Dh, 0Ah, 'Press any key to start...', 0 | |
weast db ' *anykey exits* P2 has won the match!', 0 | |
wwest db ' P1 has won the match! *anykey exits*', 0 | |
dwest db ' Doubling Cube! MOV=Double SPC=Drop', 0 | |
deast db ' MOV=Double SPC=Drop Doubling Cube!', 0 | |
lwest db ' P2 has won this round!', 0 | |
least db ' P1 has won this round!', 0 | |
crawf db 0 | |
dcpms db 0 ; side: 1 = P1; 2 = P2 | |
dcube db 1 ; 0 = max | |
westp db 0 ; P1 score | |
eastp db 0 ; P2 score | |
local db 128 ; auxiliary | |
westg db 64 ; P1 meter | |
eastg db 64 ; P2 meter | |
mined dw 0 ; deployed mine destination | |
minex dw 16 ; deployed mine current X | |
miney dw 152 ; deployed mine current Y | |
westn dw 0 ; count P2 mines on P1 side times two | |
eastn dw 0 ; count P1 mines on P2 side times two | |
wemix dw 6 dup(16) ; western mine X | |
wemiy dw 6 dup(16) ; western mine Y | |
eamix dw 6 dup(288) ; eastern mine X | |
eamiy dw 6 dup(16) ; eastern mine Y | |
balln dw 4 ; equal to balls onscreen times two | |
ballh dw 1,0,1,0,1,0 ; 0 = left | |
ballv dw 6 dup(0) ; 0 = up | |
ballx dw 16,300,16,300,16,300 ; ball Xs | |
bally dw 6 dup(156) ; ball Ys | |
westd db 0 ; 0 = stop; 1 = up | |
eastd db 0 ; 2 = left; 3 = right | |
westx dw 120 ; P1 X | |
westy dw 144 ; P1 Y | |
eastx dw 168 ; P2 X | |
easty dw 144 ; P2 Y | |
; init graphics mode | |
init: mov ax, 0Dh ; 320x200 4-bit color | |
int 10h ; video interrupt | |
; draw ceiling | |
xor bh, bh ; video page | |
mov ax, 0C07h ; grey pixels | |
xor dx, dx ; DX = row; CX = column | |
ceio: mov cx, 319 ; breadth; start outer | |
int 10h ; video interrupt | |
ceii: dec cx ; start inner | |
int 10h ; video interrupt | |
jnz ceii ; end inner | |
inc dx ; | |
cmp dx, 16 ; depth | |
jb ceio ; end outer | |
; draw walls | |
mov dx, 16 | |
walo: mov cx, 15 ; start outer | |
int 10h ; pixel | |
wall: dec cx ; start left | |
int 10h ; pixel | |
jnz wall ; end left | |
mov cx, 304 ; | |
walr: int 10h ; pixel; start right | |
inc cx ; | |
cmp cx, 320 ; | |
jb walr ; end right | |
inc dx ; | |
cmp dx, 176 ; | |
jb walo ; end outer | |
; draw net | |
mov dx, 120 | |
neto: mov cx, 152 ; start outer | |
neti: int 10h ; pixel; start inner | |
inc cx ; | |
cmp cx, 168 ; | |
jb neti ; end inner | |
inc dx ; | |
cmp dx, 176 ; | |
jb neto ; end outer | |
; draw floors | |
dec al ; yellow | |
mov dx, 160 ; | |
floo: mov cx, 16 ; start outer | |
flol: int 10h ; pixel; start left | |
inc cx ; | |
cmp cx, 152 ; | |
jb flol ; end left | |
mov cx, 168 ; | |
flor: int 10h ; pixel; start right | |
inc cx ; | |
cmp cx, 304 ; | |
jb flor ; end right | |
inc dx ; | |
cmp dx, 176 ; | |
jb floo ; end outer | |
; draw indicators | |
dec al ; magenta | |
mov cx, 12 | |
mov dx, 180 | |
call sboxp | |
mov cx, 284 | |
call sboxp | |
call weggp | |
call eaggp | |
; START MAIN LOOP | |
; PROCESS KEYSTROKES | |
keyl: mov ah, 1 ; check keystrokes | |
int 16h ; keyboard interrupt | |
jnz keym ; if no more | |
jmp balm ; then break | |
keym: xor ah, ah ; get from buffer | |
int 16h ; keyboard interrupt | |
cmp ah, 11h ; 'W' | |
jne keya ; next | |
mov westd, 1 ; P1 up | |
jmp keyl ; loop | |
keya: cmp ah, 48h ; up | |
jne keyb ; next | |
mov eastd, 1 ; P2 up | |
jmp keyl ; loop | |
keyb: cmp ah, 1Eh ; 'A' | |
jne keyc ; next | |
mov westd, 2 ; P1 left | |
jmp keyl ; loop | |
keyc: cmp ah, 20h ; 'D' | |
jne keyd ; next | |
mov westd, 3 ; P1 right | |
jmp keyl ; loop | |
keyd: cmp ah, 4Bh ; left | |
jne keye ; next | |
mov eastd, 2 ; P2 left | |
jmp keyl ; loop | |
keye: cmp ah, 4Dh ; right | |
jne keyf ; next | |
mov eastd, 3 ; P2 right | |
jmp keyl ; loop | |
keyf: cmp ah, 1Fh ; 'S' | |
je klol | |
jmp keyg ; next | |
klol: cmp westd, 0 ; none | |
je klom | |
jmp keyi ; skip | |
; P1 special | |
klom: cmp mined, 0 ; one at a time | |
je klon | |
jmp keyi ; no dice | |
klon: cmp westg, 75 ; got meter? | |
jb kwwx | |
jmp kweg ; forthward! | |
kwwx: cmp dcpms, 2 | |
jne kwww | |
jmp keyi | |
kwww: cmp crawf, 1 ; Crawford rule | |
jne kloo | |
jmp keyi | |
kloo: cmp dcube, 0 | |
jne klop | |
jmp keyi | |
klop: mov dcpms, 2 ; kekeke | |
xor dx, dx | |
mov bl, 87h | |
mov si, offset dwest | |
call gr_msg | |
mov ax, 294 ; D | |
mov dx, 100 | |
call note | |
kdcv: mov ah, 1 ; debuffer | |
int 16h | |
jz kdcw | |
cmp ah, 1 ; escape | |
jne komf | |
jmp quit ; abort | |
komf: xor ah, ah | |
int 16h | |
jmp kdcv ; done | |
kdcw: xor ah, ah ; keystroke | |
int 16h | |
cmp ah, 1 ; escape | |
jne komg | |
jmp quit ; abort | |
komg: cmp ah, 50h ; down | |
jne kdcx | |
add local, 16 ; drop | |
call ceilp ; erase | |
jmp keyi | |
kdcx: cmp ah, 48h ; up | |
je kdcy | |
cmp ah, 4Bh ; left | |
je kdcy | |
cmp ah, 4Dh ; right | |
je kdcy | |
jmp kdcw ; next | |
kdcy: call ceilp ; erase | |
call dbltk | |
jmp keyi | |
kweg: cmp westy, 113 ; minimum height | |
jnb keyi ; no dice | |
cmp eastn, 12 ; six at a time | |
jnb keyi ; no dice | |
sub westg, 75 ; 30% tension | |
call weggp ; update gauge | |
mov dx, westy ; copy Y | |
mov miney, dx ; paste Y | |
mov dx, westx ; copy X | |
add dx, 24 ; adjustment | |
mov minex, dx ; paste X | |
neg dx ; mirror | |
add dx, 312 ; across | |
mov mined, dx ; center | |
keyi: mov westd, 0 ; stop | |
jmp keyl ; loop | |
keyg: cmp ah, 50h ; down | |
je kbbq | |
jmp keyh ; next | |
kbbq: cmp eastd, 0 ; none | |
je kbbr | |
jmp keyj ; skip | |
; P2 special | |
kbbr: cmp mined, 0 ; one at a time | |
je kbbs | |
jmp keyj ; no dice | |
kbbs: cmp eastg, 75 ; got meter? | |
jb keef | |
jmp keag ; forthward! | |
keef: cmp dcpms, 1 | |
jne kbbt | |
jmp keyj | |
kbbt: cmp dcube, 0 | |
jne keee | |
jmp keyj | |
keee: cmp crawf, 1 ; Crawford rule | |
jne kbbu | |
jmp keyj | |
kbbu: mov dcpms, 1 ; kekeke | |
xor dx, dx | |
mov bl, 87h | |
mov si, offset deast | |
call gr_msg | |
mov ax, 294 ; D | |
mov dx, 100 | |
call note | |
kdcd: mov ah, 1 ; debuffer | |
int 16h | |
jz kdce | |
cmp ah, 1 ; escape | |
jne kwte | |
jmp quit ; abort | |
kwte: xor ah, ah | |
int 16h | |
jmp kdcd ; done | |
kdce: xor ah, ah ; keystroke | |
int 16h | |
cmp ah, 1 ; escape | |
jne kwtf | |
jmp quit ; abort | |
kwtf: cmp ah, 1Fh ; 'S' | |
jne kdcf | |
sub local, 16 ; drop | |
call ceilp ; erase | |
jmp keyj | |
kdcf: cmp ah, 11h ; 'W' | |
je kdcg | |
cmp ah, 1Eh ; 'A' | |
je kdcg | |
cmp ah, 20h ; 'D' | |
je kdcg | |
jmp kdce ; next | |
kdcg: call ceilp ; erase | |
call dbltk | |
jmp keyj | |
keag: cmp easty, 113 ; minimum height | |
jnb keyj ; no dice | |
cmp westn, 12 ; six at a time | |
jnb keyj ; no dice | |
sub eastg, 75 ; 30% tension | |
call eaggp ; update gauge | |
mov dx, easty ; copy Y | |
mov miney, dx ; paste Y | |
mov dx, eastx ; copy X | |
mov minex, dx ; paste X | |
neg dx ; mirror | |
add dx, 312 ; across | |
mov mined, dx ; center | |
keyj: mov eastd, 0 ; stop | |
jmp keyl ; loop | |
keyh: cmp ah, 1 ; escape | |
je keyk ; short | |
jmp keyl ; long | |
keyk: jmp quit ; abort game | |
; BALL MOVEMENT | |
balm: xor bx, bx | |
; cleanup | |
balo: mov cx, ballx[bx] ; start outer | |
mov dx, bally[bx] ; graphical glitch | |
mov ax, 0C00h ; when newer position | |
call ballp ; of previous ball | |
; object collision | |
cmp cx, 160 ; mines | |
jnb bbls | |
jmp bals | |
bbls: cmp eastn, 0 | |
jne bblt | |
jmp bclt | |
bblt: push bx | |
xor bx, bx | |
balu: cmp cx, eamix[bx] ; start loop | |
jb balv | |
cmp dx, eamiy[bx] | |
jb balv | |
mov ax, eamix[bx] | |
add ax, 8 | |
cmp cx, ax | |
jnb balv | |
mov ax, eamiy[bx] | |
add ax, 8 | |
cmp ax, dx | |
jb balv | |
push cx | |
push dx | |
mov cx, eamix[bx] | |
mov dx, eamiy[bx] | |
mov ax, 0C00h | |
call minep | |
dec al | |
push bx | |
sub eastn, 2 | |
mov bx, eastn | |
mov cx, eamix[bx] | |
mov dx, eamiy[bx] | |
pop bx | |
mov eamix[bx], cx | |
mov eamiy[bx], dx | |
pop dx | |
pop cx | |
cmp bx, eastn | |
jb balu | |
balv: add bx, 2 | |
cmp bx, eastn | |
jb balu ; end loop | |
pop bx | |
jmp balt | |
bals: cmp westn, 0 | |
je bclt | |
push bx | |
xor bx, bx | |
bblu: cmp cx, wemix[bx] ; start loop | |
jb bblv | |
cmp dx, wemiy[bx] | |
jb bblv | |
mov ax, wemiy[bx] | |
add ax, 8 | |
cmp dx, ax | |
jnb bblv | |
mov ax, wemix[bx] | |
add ax, 8 | |
cmp cx, ax | |
jnb bblv | |
push cx | |
push dx | |
mov cx, wemix[bx] | |
mov dx, wemiy[bx] | |
mov ax, 0C00h | |
call minep | |
dec al | |
push bx | |
sub westn, 2 | |
mov bx, westn | |
mov cx, wemix[bx] | |
mov dx, wemiy[bx] | |
pop bx | |
mov wemix[bx], cx | |
mov wemiy[bx], dx | |
pop dx | |
pop cx | |
cmp bx, westn | |
jb bblu | |
bblv: add bx, 2 | |
cmp bx, westn | |
jb bblu ; end loop | |
pop bx | |
balt: cmp al, -1 | |
jne bclt | |
mov ballv[bx], 1 | |
bclt: mov ax, eastx ; P2 | |
sub ax, 8 | |
cmp ax, cx | |
jnb balc | |
add ax, 40 | |
cmp ax, cx | |
jnb bomg | |
jmp balb | |
bomg: mov ax, easty | |
sub ax, 4 | |
cmp ax, dx | |
jnb balc | |
add ax, 24 | |
cmp ax, dx | |
jb balc | |
sub ax, 12 | |
cmp ax, dx | |
jb bala | |
jmp bale | |
balc: cmp cx, 152 ; net | |
jb bald | |
cmp dx, 120 | |
jb balb | |
cmp cx, 168 | |
jnb balb | |
sub dx, 3 | |
mov ax, 0C07h ; grey | |
call ballp ; redraw | |
cmp dx, 132 | |
jnb bala | |
jmp bale | |
bald: mov ax, westx ; P1 | |
sub ax, 8 | |
cmp ax, cx | |
jnb balb | |
add ax, 40 | |
cmp ax, cx | |
jb balb | |
mov ax, westy | |
sub ax, 4 | |
cmp ax, dx | |
jnb balb | |
add ax, 24 | |
cmp ax, dx | |
jb balb | |
sub ax, 12 | |
cmp ax, dx | |
jnb bale | |
bala: neg ballh[bx] | |
inc ballh[bx] | |
bale: mov ballv[bx], 0 | |
; bound collision | |
balb: cmp dx, 22 ; ceiling | |
jnb bali ; | |
mov ballv[bx], 1 ; down | |
cmp cx, 158 | |
jb gaug | |
add westg, 11 | |
call weggp | |
jmp balj | |
gaug: add eastg, 11 | |
call eaggp | |
jmp balj | |
bali: cmp dx, 158 ; floor | |
jb balj ; | |
mov ballv[bx], 0 ; up | |
cmp cx, 158 ; loser | |
jb ball | |
add local, 2 | |
ball: dec local | |
balj: cmp cx, 18 ; walll | |
jnb balk ; | |
mov ballh[bx], 1 ; right | |
jmp balz ; | |
balk: cmp cx, 298 ; wallr | |
jb balz ; | |
mov ballh[bx], 0 ; left | |
; movement | |
balz: cmp ballh[bx], 0 ; horizontal | |
jne balx ; | |
sub cx, 8 ; | |
balx: add cx, 4 ; | |
cmp ballv[bx], 0 ; vertical | |
jne baly ; | |
sub dx, 8 ; | |
baly: inc dx ; | |
mov ballx[bx], cx ; store X | |
mov bally[bx], dx ; store Y | |
; repaint | |
mov ax, 0C0Fh ; white pixels | |
call ballp ; paint ball | |
add bx, 2 ; | |
cmp bx, balln ; | |
jnb minm ; break | |
jmp balo ; end outer | |
; MINE MOVEMENT | |
minm: cmp mined, 0 | |
jne minn | |
jmp wesm | |
minn: mov cx, minex | |
mov dx, miney | |
xor al, al | |
call minep | |
cmp cx, mined | |
jb mina | |
sub cx, 16 | |
mina: add cx, 8 | |
cmp mined, 160 | |
jnb minb | |
cmp cx, mined | |
jb miny | |
jmp minz | |
miny: mov bx, westn | |
add westn, 2 | |
mov mined, 0 | |
mov al, 4 | |
mov wemix[bx], cx | |
mov wemiy[bx], dx | |
mini: call minep ; start loop | |
sub bx, 2 | |
jc minc ; break out | |
mov cx, wemix[bx] | |
mov dx, wemiy[bx] | |
jmp mini ; end loop | |
minc: mov bx, eastn | |
minj: sub bx, 2 ; start loop | |
jc wesm ; break out | |
mov cx, eamix[bx] | |
mov dx, eamiy[bx] | |
call minep | |
jmp minj ; end loop | |
minb: cmp cx, mined | |
jb minz | |
mov bx, eastn | |
add eastn, 2 | |
mov mined, 0 | |
mov al, 4 | |
mov eamix[bx], cx | |
mov eamiy[bx], dx | |
mink: call minep ; start loop | |
sub bx, 2 | |
jc mind ; break out | |
mov cx, eamix[bx] | |
mov dx, eamiy[bx] | |
jmp mink ; end loop | |
mind: mov bx, westn | |
minl: sub bx, 2 ; start loop | |
jc wesm ; break out | |
mov cx, wemix[bx] | |
mov dx, wemiy[bx] | |
call minep | |
jmp minl ; end loop | |
minz: inc al | |
call minep | |
mov minex, cx | |
; WEST MOVEMENT | |
wesm: mov cx, westx ; redraw is coded the lazy way | |
mov dx, westy ; will fix after features done | |
cmp westd, 0 ; | |
jne wesz ; if no move | |
jmp easm ; skip ahead | |
wesz: cmp westd, 2 ; left | |
jb wesu ; | |
je wesl ; | |
add cx, 16 ; | |
wesl: sub cx, 8 ; | |
add dx, 4 ; | |
cmp cx, 16 ; wall | |
jnb wesr ; | |
mov cx, 16 ; | |
mov westd, 0 ; | |
jmp wesd ; | |
wesr: cmp cx, 121 ; net | |
jb wesd ; | |
mov cx, 120 ; | |
mov westd, 0 ; | |
wesd: cmp dx, 145 ; floor | |
jb wesc | |
mov dx, 144 | |
mov westd, 0 | |
jmp wesc | |
wesu: sub dx, 8 | |
cmp dx, 16 | |
jnb wesc | |
mov dx, 16 | |
mov westd, 0 | |
; collision | |
wesc: cmp westn, 0 | |
je wesp | |
push bx | |
xor bx, bx | |
welu: mov ax, wemiy[bx] ; start loop | |
add ax, 6 | |
cmp ax, dx | |
jb welv | |
sub ax, 20 | |
cmp ax, dx | |
jnb welv | |
mov ax, wemix[bx] | |
add ax, 6 | |
cmp ax, cx | |
jb welv | |
sub ax, 36 | |
cmp ax, cx | |
jnb welv | |
push cx | |
push dx | |
mov cx, wemix[bx] | |
mov dx, wemiy[bx] | |
mov ax, 0C00h | |
call minep | |
dec al | |
push bx | |
sub westn, 2 | |
mov bx, westn | |
mov cx, wemix[bx] | |
mov dx, wemiy[bx] | |
pop bx | |
mov wemix[bx], cx | |
mov wemiy[bx], dx | |
pop dx | |
pop cx | |
cmp bx, westn | |
jb welu | |
welv: add bx, 2 | |
cmp bx, westn | |
jb welu ; end loop | |
pop bx | |
cmp al, -1 | |
jne wesp | |
dec local | |
; repaint | |
wesp: push cx | |
push dx | |
mov cx, westx | |
mov dx, westy ; graphical glitch | |
mov ax, 0C00h ; when newer position | |
call playp ; of previous ball | |
pop dx ; | |
pop cx ; | |
easm: mov ax, 0C02h ; green | |
call playp | |
sub dx, 16 | |
mov westx, cx | |
mov westy, dx | |
; EAST MOVEMENT | |
mov cx, eastx ; redraw is coded the lazy way | |
mov dx, easty ; will fix after features done | |
cmp eastd, 0 ; | |
jne easz ; if no move | |
jmp zzzz ; skip ahead | |
easz: cmp eastd, 2 ; left | |
jb easu ; | |
je easl ; | |
add cx, 16 ; | |
easl: sub cx, 8 ; | |
add dx, 4 ; | |
cmp cx, 168 ; net | |
jnb easr ; | |
mov cx, 168 ; | |
mov eastd, 0 ; | |
jmp easd ; | |
easr: cmp cx, 273 ; wall | |
jb easd ; | |
mov cx, 272 ; | |
mov eastd, 0 ; | |
easd: cmp dx, 145 ; floor | |
jb easc | |
mov dx, 144 | |
mov eastd, 0 | |
jmp easc | |
easu: sub dx, 8 | |
cmp dx, 16 | |
jnb easc | |
mov dx, 16 | |
mov eastd, 0 | |
; collision | |
easc: cmp eastn, 0 | |
je easp | |
push bx | |
xor bx, bx | |
ealu: mov ax, eamiy[bx] ; start loop | |
add ax, 6 | |
cmp ax, dx | |
jb ealv | |
sub ax, 20 | |
cmp ax, dx | |
jnb ealv | |
mov ax, eamix[bx] | |
add ax, 6 | |
cmp ax, cx | |
jb ealv | |
sub ax, 36 | |
cmp ax, cx | |
jnb ealv | |
push cx | |
push dx | |
mov cx, eamix[bx] | |
mov dx, eamiy[bx] | |
mov ax, 0C00h | |
call minep | |
dec al | |
push bx | |
sub eastn, 2 | |
mov bx, eastn | |
mov cx, eamix[bx] | |
mov dx, eamiy[bx] | |
pop bx | |
mov eamix[bx], cx | |
mov eamiy[bx], dx | |
pop dx | |
pop cx | |
cmp bx, eastn | |
jb ealu | |
ealv: add bx, 2 | |
cmp bx, eastn | |
jb ealu ; end loop | |
pop bx | |
cmp al, -1 | |
jne easp | |
inc local | |
; repaint | |
easp: push cx | |
push dx | |
mov cx, eastx | |
mov dx, easty ; graphical glitch | |
mov ax, 0C00h ; when newer position | |
call playp ; of previous ball | |
pop dx ; | |
pop cx ; | |
zzzz: mov ax, 0C02h ; green | |
call playp | |
sub dx, 16 | |
mov eastx, cx | |
mov easty, dx | |
; VICTORY | |
cmp local, 128 | |
jne vhax | |
jmp zdbg | |
vhax: jb zwex | |
cmp local, 129 | |
jne zeaz | |
cmp eastg, 150 | |
jb zeaz | |
sub eastg, 150 | |
call eaggp | |
dec local | |
jmp zdbg | |
zeaz: mov local, 128 | |
xor dx, dx | |
mov bl, 87h | |
mov si, offset least | |
call gr_msg | |
mov ax, 262 ; C | |
mov dl, 200 | |
call note | |
call ceilp | |
mov al, dcube | |
add westp, al | |
cmp al, 0 | |
jne zeay | |
mov westp, 5 | |
zeay: call reset | |
jmp zdbg | |
zwex: cmp local, 127 | |
jne zwez | |
cmp westg, 150 | |
jb zwez | |
sub westg, 150 | |
call weggp | |
inc local | |
jmp zdbg | |
zwez: mov local, 128 | |
xor dx, dx | |
mov bl, 87h | |
mov si, offset lwest | |
call gr_msg | |
mov ax, 262 ; C | |
mov dl, 200 | |
call note | |
call ceilp | |
mov al, dcube | |
add eastp, al | |
cmp al, 0 | |
jne zwey | |
mov eastp, 5 | |
zwey: call reset | |
; FRAME DELAY | |
zdbg: xor ax, ax ; silence | |
mov dx, 5 ; 20 FPS (slower actually) | |
call note ; ZzZzZz | |
; END MAIN LOOP | |
jmp keyl ; main | |
; revert text mode | |
quit: mov ax, 2 ; text mode | |
int 10h ; video interrupt | |
int 20h ; HALT! | |
; 4x4 square (ball) | |
ballp proc ; AH = 0C0?h; ? = color | |
push bx ; DX = row; CX = column | |
xor bx, bx ; DX to increment +3 | |
bapa: int 10h ; start inner | |
inc cx ; | |
inc bl ; | |
cmp bl, 4 ; | |
jb bapa ; end inner | |
inc dx ; next row | |
bapb: dec cx ; start inner | |
int 10h ; | |
inc bl ; | |
cmp bl, 8 ; | |
jb bapb ; end inner | |
inc dx ; next row | |
bapc: int 10h ; start inner | |
inc cx ; | |
inc bl ; | |
cmp bl, 12 ; | |
jb bapc ; end inner | |
inc dx ; next row | |
bapd: dec cx ; start inner | |
int 10h ; | |
inc bl ; | |
cmp bl, 16 ; | |
jb bapd ; end inner | |
pop bx | |
ret | |
ballp endp | |
; 8x8 square (mine) | |
minep proc ; AH = 0C0?h; ? = color | |
push bx ; DX = row | |
xor bx, bx ; CX = column | |
mipo: push bx ; clear bl; start outer | |
xor bl, bl ; | |
mipi: int 10h ; start inner | |
inc cx ; | |
inc bl ; | |
cmp bl, 8 ; | |
jb mipi ; end inner | |
inc dx ; next row | |
mipj: dec cx ; start inner | |
int 10h ; | |
inc bl ; | |
cmp bl, 16 ; | |
jb mipj ; end inner | |
pop bx ; fetch bl | |
inc dx ; | |
inc bl ; | |
cmp bl, 4 ; | |
jb mipo ; end outer | |
sub dx, 8 | |
pop bx | |
ret | |
minep endp | |
; 32x16 rectangle (player) | |
playp proc ; AH = 0C0?h; ? = color | |
push bx ; DX = row; CX = column | |
xor bx, bx ; DX to increment +16 | |
plpo: push bx ; clear bl; start outer | |
xor bl, bl ; | |
plpi: int 10h ; start inner | |
inc cx ; | |
inc bl ; | |
cmp bl, 32 ; | |
jb plpi ; end inner | |
inc dx ; next row | |
plpj: dec cx ; start inner | |
int 10h ; | |
inc bl ; | |
cmp bl, 64 ; | |
jb plpj ; end inner | |
pop bx ; fetch bl | |
inc dx ; | |
inc bl ; | |
cmp bl, 8 ; | |
jb plpo ; end outer | |
pop bx | |
ret | |
playp endp | |
; P1 meter | |
weggp proc | |
PUSH AX ; save registers | |
PUSH BX | |
PUSH CX | |
PUSH DX | |
mov ax, 330 ; E | |
mov dx, 3 | |
call note | |
xor ah, ah | |
mov al, westg | |
mov bx, ax | |
mov cx, 3 | |
shl bx, cl | |
add bx, ax | |
inc cl ; BH = 0 | |
shr bx, cl ; BL = westg * 9/16 | |
shl cl, 1 ; CX = 8 | |
mov ax, 0C03h | |
wegg: sub bl, 1 ; start loop | |
jnc wegc | |
xor al, al | |
wegc: mov dx, 192 | |
int 10h | |
inc dx | |
int 10h | |
inc dx | |
int 10h | |
inc dx | |
int 10h | |
inc cx | |
cmp cx, 153 | |
jb wegg ; end loop | |
POP DX ; restore registers | |
POP CX | |
POP BX | |
POP AX | |
ret | |
weggp endp | |
; P2 meter | |
eaggp proc | |
PUSH AX ; save registers | |
PUSH BX | |
PUSH CX | |
PUSH DX | |
xor ah, ah | |
mov al, eastg | |
mov bx, ax | |
mov cx, 3 | |
shl bx, cl | |
add bx, ax | |
inc cl ; BH = 0 | |
shr bx, cl ; BL = eastg * 9/16 | |
mov cx, 311 ; CX = 311 | |
mov ax, 0C03h | |
eagg: sub bl, 1 ; start loop | |
jnc eagc | |
xor al, al | |
eagc: mov dx, 192 | |
int 10h | |
inc dx | |
int 10h | |
inc dx | |
int 10h | |
inc dx | |
int 10h | |
dec cx | |
cmp cx, 168 | |
jnb eagg ; end loop | |
mov ax, 330 ; E | |
mov dx, 3 | |
call note | |
POP DX ; restore registers | |
POP CX | |
POP BX | |
POP AX | |
ret | |
eaggp endp | |
; 24x8 outline (stakes) | |
sboxp proc ; AH = 0C0?h; ? = color | |
push bx ; DX = row | |
xor bx, bx ; CX = column | |
sbpa: int 10h ; start loop | |
inc cx | |
inc bl | |
cmp bl, 23 | |
jb sbpa ; end loop | |
sbpb: int 10h ; start loop | |
inc dx | |
inc bl | |
cmp bl, 30 | |
jb sbpb ; end loop | |
sbpc: int 10h ; start loop | |
dec cx | |
inc bl | |
cmp bl, 53 | |
jb sbpc ; end loop | |
sbpd: int 10h ; start loop | |
dec dx | |
inc bl | |
cmp bl, 60 | |
jb sbpd ; end loop | |
pop bx | |
ret | |
sboxp endp | |
; 22x6 rectangle (score) | |
sfilp proc ; AH = 0C0?h; ? = color | |
push bx ; DX = row; CX = column | |
xor bx, bx ; DX to increment +6 | |
sfpo: push bx ; clear bl; start outer | |
xor bl, bl ; | |
sfpi: int 10h ; start inner | |
inc cx ; | |
inc bl ; | |
cmp bl, 22 ; | |
jb sfpi ; end inner | |
inc dx ; next row | |
sfpj: dec cx ; start inner | |
int 10h ; | |
inc bl ; | |
cmp bl, 44 ; | |
jb sfpj ; end inner | |
pop bx ; fetch bl | |
inc dx ; | |
inc bl ; | |
cmp bl, 3 ; | |
jb sfpo ; end outer | |
pop bx | |
ret | |
sfilp endp | |
; erase message | |
ceilp proc | |
PUSH AX ; save registers | |
PUSH BX | |
PUSH CX | |
PUSH DX | |
xor bh, bh ; video page | |
mov ax, 0C07h ; grey pixels | |
xor dx, dx ; DX = row; CX = column | |
ceip: mov cx, 319 ; breadth; start outer | |
int 10h ; video interrupt | |
ceij: dec cx ; start inner | |
int 10h ; video interrupt | |
jnz ceij ; end inner | |
inc dx ; | |
cmp dx, 8 ; depth | |
jb ceip ; end outer | |
POP DX ; restore registers | |
POP CX | |
POP BX | |
POP AX | |
ret | |
ceilp endp | |
; doubling cube | |
dbltk proc | |
PUSH AX ; save registers | |
PUSH BX | |
PUSH CX | |
PUSH DX | |
cmp dcube, 1 | |
jne dcta | |
add balln, 4 | |
dcta: cmp dcube, 4 | |
jne dctb | |
add balln, 4 | |
dctb: shl dcube, 1 | |
mov ax, 0C00h | |
xor bh, bh | |
mov bl, westp | |
add bl, dcube | |
push bx ; BH = 0 | |
cmp bl, 5 | |
jb dctc | |
mov dx, 164 | |
mov cx, 72 | |
call sboxp | |
dctc: mov al, 5 | |
mov dx, 180 | |
cmp bl, 4 | |
jb dctd | |
mov cx, 132 | |
call sboxp | |
dctd: cmp bl, 3 | |
jb dcte | |
mov cx, 92 | |
call sboxp | |
dcte: mov cx, 52 | |
call sboxp | |
mov bl, eastp | |
add bl, dcube | |
pop dx | |
cmp bl, 5 | |
jb dctg | |
cmp dx, 5 | |
jb dctf | |
mov dcube, 0 | |
dctf: mov dl, 164 | |
mov cx, 224 | |
xor al, al | |
call sboxp | |
mov al, 5 | |
dctg: mov dl, 180 | |
cmp bl, 4 | |
jb dcth | |
mov cx, 164 | |
call sboxp | |
dcth: cmp bl, 3 | |
jb dcti | |
mov cx, 204 | |
call sboxp | |
dcti: mov cx, 244 | |
call sboxp | |
POP DX ; restore registers | |
POP CX | |
POP BX | |
POP AX | |
ret | |
dbltk endp | |
; new round | |
reset proc | |
PUSH AX ; save registers | |
PUSH BX | |
PUSH CX | |
PUSH DX | |
cmp crawf, 1 | |
jne resa | |
inc crawf | |
resa: mov ax, 0C05h | |
xor bh, bh | |
mov bl, westp | |
cmp bl, 1 | |
jnb reta | |
inc al | |
mov dx, 164 | |
mov cx, 72 | |
call sboxp | |
xor al, al | |
mov dl, 180 | |
mov cl, 52 | |
call sboxp | |
mov cl, 92 | |
call sboxp | |
mov cl, 132 | |
call sboxp | |
jmp resb | |
reta: mov cx, 13 | |
mov dx, 181 | |
call sfilp | |
cmp bl, 2 | |
jnb retb | |
inc al | |
mov dx, 164 | |
mov cx, 72 | |
call sboxp | |
dec al | |
mov dl, 180 | |
mov cl, 52 | |
call sboxp | |
xor al, al | |
mov cl, 92 | |
call sboxp | |
mov cl, 132 | |
call sboxp | |
jmp resb | |
retb: mov cl, 53 | |
mov dl, 181 | |
call sfilp | |
cmp bl, 3 | |
jnb retc | |
inc al | |
mov dx, 164 | |
mov cx, 72 | |
call sboxp | |
dec al | |
mov dl, 180 | |
mov cl, 52 | |
call sboxp | |
mov cl, 92 | |
call sboxp | |
xor al, al | |
mov cl, 132 | |
call sboxp | |
jmp resb | |
retc: mov cl, 93 | |
mov dl, 181 | |
call sfilp | |
cmp bl, 4 | |
jnb retd | |
inc al | |
mov dl, 164 | |
mov cl, 72 | |
call sboxp | |
dec al | |
mov dl, 180 | |
mov cl, 52 | |
call sboxp | |
mov cl, 92 | |
call sboxp | |
mov cl, 132 | |
call sboxp | |
jmp resb | |
retd: mov cl, 133 | |
mov dl, 181 | |
call sfilp | |
cmp bl, 5 | |
jnb retf | |
cmp crawf, 0 | |
jne rete | |
inc crawf | |
rete: xor al, al | |
mov dl, 164 | |
mov cl, 72 | |
call sboxp | |
mov al, 5 | |
mov dl, 180 | |
mov cl, 52 | |
call sboxp | |
mov cl, 92 | |
call sboxp | |
mov cl, 132 | |
call sboxp | |
jmp resb | |
retf: mov dl, 165 | |
mov cl, 73 | |
call sfilp | |
xor dl, dl | |
mov bl, 87h | |
mov si, offset wwest | |
call gr_msg | |
resf: mov ah, 1 ; debuffer | |
int 16h | |
jz resg | |
xor ah, ah | |
int 16h | |
jmp resf ; done | |
resg: xor ah, ah | |
int 16h | |
pop ax | |
pop ax | |
pop ax | |
pop ax | |
pop ax | |
jmp quit ; breaking out | |
resb: mov al, 5 | |
mov bl, eastp | |
cmp bl, 1 | |
jnb retg | |
inc al | |
mov dl, 164 | |
mov cl, 224 | |
call sboxp | |
xor al, al | |
mov dl, 180 | |
mov cl, 244 | |
call sboxp | |
mov cl, 204 | |
call sboxp | |
mov cl, 164 | |
call sboxp | |
jmp resc | |
retg: mov cx, 285 | |
mov dl, 181 | |
call sfilp | |
cmp bl, 2 | |
jnb reth | |
inc al | |
mov dl, 164 | |
mov cx, 224 | |
call sboxp | |
dec al | |
mov dl, 180 | |
mov cl, 244 | |
call sboxp | |
xor al, al | |
mov cl, 204 | |
call sboxp | |
mov cl, 164 | |
call sboxp | |
jmp resc | |
reth: mov cx, 245 | |
mov dl, 181 | |
call sfilp | |
cmp bl, 3 | |
jnb reti | |
inc al | |
mov dl, 164 | |
mov cl, 224 | |
call sboxp | |
dec al | |
mov dl, 180 | |
mov cl, 244 | |
call sboxp | |
mov cl, 204 | |
call sboxp | |
xor al, al | |
mov cl, 164 | |
call sboxp | |
jmp resc | |
reti: mov cl, 205 | |
mov dl, 181 | |
call sfilp | |
cmp bl, 4 | |
jnb retj | |
inc al | |
mov dl, 164 | |
mov cl, 224 | |
call sboxp | |
dec al | |
mov dl, 180 | |
mov cl, 244 | |
call sboxp | |
mov cl, 204 | |
call sboxp | |
mov cl, 164 | |
call sboxp | |
jmp resc | |
retj: mov cl, 165 | |
mov dl, 181 | |
call sfilp | |
cmp bl, 5 | |
jnb retl | |
cmp crawf, 0 | |
jne retk | |
inc crawf | |
retk: xor al, al | |
mov dl, 164 | |
mov cl, 224 | |
call sboxp | |
mov al, 5 | |
mov dl, 180 | |
mov cl, 244 | |
call sboxp | |
mov cl, 204 | |
call sboxp | |
mov cl, 164 | |
call sboxp | |
jmp resc | |
retl: mov dl, 165 | |
mov cl, 225 | |
call sfilp | |
xor dl, dl | |
mov bl, 87h | |
mov si, offset weast | |
call gr_msg | |
resd: mov ah, 1 ; debuffer | |
int 16h | |
jz rese | |
xor ah, ah | |
int 16h | |
jmp resd ; done | |
rese: xor ah, ah | |
int 16h | |
pop ax | |
pop ax | |
pop ax | |
pop ax | |
pop ax | |
jmp quit ; breaking out | |
resc: mov eastn, 0 | |
mov westn, 0 | |
mov balln, 4 | |
mov ballv, 0 | |
mov ballv[2], 0 | |
mov ballv[4], 0 | |
mov ballv[6], 0 | |
mov ballv[8], 0 | |
mov ballv[10], 0 | |
mov westg, 64 | |
mov eastg, 64 | |
mov mined, 0 | |
mov westd, 3 | |
mov eastd, 2 | |
mov ax, 0C00h | |
mov cx, ballx[4] | |
mov dx, bally[4] | |
call ballp | |
mov cx, ballx[6] | |
mov dx, bally[6] | |
call ballp | |
mov cx, ballx[8] | |
mov dx, bally[8] | |
call ballp | |
mov cx, ballx[10] | |
mov dx, bally[10] | |
call ballp | |
mov cx, minex | |
mov dx, miney | |
call minep | |
mov cx, wemix | |
mov dx, wemiy | |
call minep | |
mov cx, wemix[2] | |
mov dx, wemiy[2] | |
call minep | |
mov cx, wemix[4] | |
mov dx, wemiy[4] | |
call minep | |
mov cx, wemix[6] | |
mov dx, wemiy[6] | |
call minep | |
mov cx, wemix[8] | |
mov dx, wemiy[8] | |
call minep | |
mov cx, wemix[10] | |
mov dx, wemiy[10] | |
call minep | |
mov cx, eamix | |
mov dx, eamiy | |
call minep | |
mov cx, eamix[2] | |
mov dx, eamiy[2] | |
call minep | |
mov cx, eamix[4] | |
mov dx, eamiy[4] | |
call minep | |
mov cx, eamix[6] | |
mov dx, eamiy[6] | |
call minep | |
mov cx, eamix[8] | |
mov dx, eamiy[8] | |
call minep | |
mov cx, eamix[10] | |
mov dx, eamiy[10] | |
call minep | |
mov cx, westx | |
mov dx, westy | |
call playp | |
mov cx, eastx | |
mov dx, easty | |
call playp | |
mov westx, 120 | |
mov westy, 144 | |
mov eastx, 168 | |
mov easty, 144 | |
mov dcpms, 0 | |
mov dcube, 1 | |
resy: mov ah, 1 ; debuffer | |
int 16h | |
jz resz | |
xor ah, ah | |
int 16h | |
jmp resy ; done | |
resz: POP DX ; restore registers | |
POP CX | |
POP BX | |
POP AX | |
ret | |
reset endp | |
; source: | |
; Demonstration color/graphics program | |
; Copyright (C) 1984, Robert B. K. Dewar | |
; Routine to play note on speaker | |
; Definitions for timer gate control | |
CTRL EQU 61H ; timer gate control port | |
TIMR EQU 00000001B ; bit to turn timer on | |
SPKR EQU 00000010B ; bit to turn speaker on | |
; Definitions of input/output ports to access timer chip | |
TCTL EQU 043H ; port for timer control | |
TCTR EQU 042H ; port for timer count values | |
; Definitions of timer control values (to send to control port) | |
TSQW EQU 10110110B ; timer 2, 2 bytes, sq wave, binary | |
LATCH EQU 10000000B ; latch timer 2 | |
; Define 32 bit value used to set timer frequency | |
FRHI EQU 0012H ; timer frequency high (1193180 / 256) | |
FRLO EQU 34DCH ; timer low (1193180 mod 256) | |
; AX = Frequency in Hz (32 - 32000) | |
; DX = Duration in units of 1/100 second | |
; Note: a frequency of zero, means rest (silence) for the indicated | |
; time, allowing this routine to be used simply as a timing delay. | |
NOTE PROC | |
PUSH AX ; save registers | |
PUSH BX | |
PUSH CX | |
PUSH DX | |
PUSH SI | |
MOV BX, AX ; save frequency in BX | |
MOV CX, DX ; save duration in CX | |
; We handle the rest (silence) case by using an arbitrary frequency to | |
; program the clock so that the normal approach for getting the right | |
; delay functions, but we will leave the speaker off in this case. | |
MOV SI, BX ; copy frequency to BX | |
OR BX, BX ; test zero frequency (rest) | |
JNZ NOT1 ; jump if not | |
MOV BX, 256 ; else reset to arbitrary non-zero | |
; Initialize timer and set desired frequency | |
NOT1: MOV AL, TSQW ; set timer 2 in square wave mode | |
OUT TCTL, AL | |
MOV DX, FRHI ; set DX:AX = 1193180 decimal | |
MOV AX, FRLO ; = clock frequency | |
DIV BX ; divide by desired frequency | |
OUT TCTR, AL ; output low order of divisor | |
MOV AL, AH ; output high order of divisor | |
OUT TCTR, AL | |
; Turn the timer on, and also the speaker (unless frequency 0 = rest) | |
IN AL, CTRL ; read current contents of control port | |
OR AL, TIMR ; turn timer on | |
OR SI, SI ; test zero frequency | |
JZ NOT2 ; skip if so (leave speaker off) | |
OR AL, SPKR ; else turn speaker on as well | |
; Compute number of clock cycles required at this frequency | |
NOT2: OUT CTRL, AL ; rewrite control port | |
XCHG AX, BX ; frequency to AX | |
MUL CX ; frequency times secs/100 to DX:AX | |
MOV CX, 100 ; divide by 100 to get number of beats | |
DIV CX | |
SHL AX, 1 ; times 2 because two clocks/beat | |
XCHG AX, CX ; count of clock cycles to CX | |
; Loop through clock cycles | |
NOT3: CALL RCTR ; read initial count | |
; Loop to wait for clock count to get reset. The count goes from the | |
; value we set down to 0, and then is reset back to the set value | |
NOT4: MOV DX, AX ; save previous count in DX | |
CALL RCTR ; read count again | |
CMP AX, DX ; compare new count : old count | |
JB NOT4 ; loop if new count is lower | |
LOOP NOT3 ; else reset, count down cycles | |
; Wait is complete, so turn off clock and return | |
IN AL, CTRL ; read current contents of port | |
AND AL, 0FFH-TIMR-SPKR ; reset timer/speaker control bits | |
; note that the above statement is an equation | |
OUT CTRL, AL ; rewrite control port | |
POP SI ; restore registers | |
POP DX | |
POP CX | |
POP BX | |
POP AX | |
RET ; return to caller | |
NOTE ENDP | |
; Routine to read count, returns current timer 2 count in AX | |
RCTR PROC | |
MOV AL, LATCH ; latch the counter | |
OUT TCTL, AL ; latch counter | |
IN AL, TCTR ; read lsb of count | |
MOV AH, AL | |
IN AL, TCTR ; read msb of count | |
XCHG AH, AL ; count is in AX | |
RET ; return to caller | |
RCTR ENDP | |
; Write Message Routine | |
; (dx) ; Cursor location (screen is 25 x 40) | |
; (bl) ; Color to use for message characters | |
; (si) ; Points to message (terminated by 00h) | |
gr_msg proc | |
push ax ; save registers | |
push bx | |
push si ; note: si,di,bp destroyed | |
push di ; by write TTY function | |
push bp | |
cld ; ensure auto-increment | |
xor bh, bh ; page zero for writes | |
mov ah, 2 ; set cursor as requested | |
int 10h | |
; Loop through characters of message | |
grmsg1: lodsb ; load next character | |
or al, al ; test terminating zero? | |
jz grmsg2 ; yes-done | |
push si ; no-save pointer | |
mov ah, 14 ; write char in TTY mode | |
int 10h | |
pop si ; restore character | |
jmp grmsg1 ; loop for next character | |
; Here with all characters written | |
grmsg2: pop bp ; restore registers | |
pop di | |
pop si | |
pop bx | |
pop ax | |
ret ;return to caller | |
gr_msg endp | |
; END OF FILE | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment