home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Assembly 1994 - The 3rd Phase
/
ASMROM94.mdf
/
fc
/
other
/
sp2.asm
< prev
next >
Wrap
Assembly Source File
|
1993-11-25
|
21KB
|
977 lines
;--------------------------------------------------------------------
; StarPort Intro II V1.0
;--------------------------------------------------------------------
; Copyright (C) 1993 Future Crew
;--------------------------------------------------------------------
; code: Psi
; music: Skaven
;--------------------------------------------------------------------
; This code is released to the public domain. You can do
; whatever you like with this code, but remember, that if
; you are just planning on making another small intro by
; changing a few lines of code, be prepared to enter the
; worldwide lamers' club. However, if you are looking at
; this code in hope of learning something new, go right
; ahead. That's exactly why this source was released.
; (BTW: I don't claim there's anything new to find here,
; but it's always worth looking, right?)
;--------------------------------------------------------------------
; The code is optimized mainly for size but also a little
; for speed. The goal was to get this little bbs intro to
; under 2K, and 1993 bytes sounded like a good size. Well,
; it wasn't easy, and there are surely places left one could
; squeeze a few extra bytes off...
; Making a small intro is not hard. Making a small intro
; with a nice feel is very hard, and you have to sacrifice
; ideas to fit the intro to the limits you have set. I had
; a lot of plans (a background piccy for example), but well,
; the size limit came first.
; I hope you enjoy my choice of size/feature ratio in this
; intro! In case you are interested, this was a three evening
; project (the last one spent testing).
;--------------------------------------------------------------------
; You can compile this with TASM, but the resulting COM-file
; will be a lot larger than the released version. This is
; because all the zero data is included to the result. The
; released version was first compiled to a COM file, and then
; a separate postprocessing program was ran which removed all
; the zero data from the end of the file. If you are just
; experimenting, recompiling is as easy as MAKE.BAT. If you
; want to make this small again, you have to do some work as
; well, and make your own postprocessor.
;--------------------------------------------------------------------
BORDERS=0 ;set to 1 for visible border-timings
code SEGMENT para public 'CODE'
ASSUME cs:code
LOCALS
.386
ORG 100h
start: cld ;filler to make the filesize exactly 1993 bytes
cld ;filler to make the filesize exactly 1993 bytes
jmp main
;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ setborder ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
;descr: debug/change border color
setborder MACRO col
IF BORDERS
push ax
push dx
mov dx,3dah
in al,dx
mov dx,3c0h
mov al,11h+32
out dx,al
mov al,col
out dx,al
pop dx
pop ax
ENDIF
ENDM
;████████████████ Simplex Adlib Player ████████████████
;this doesn't just read raw data to output to adlib like the one
;used in the last starport intro. This player really does have
;note & instrument data it reads and processes!
;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ output data to adlib ▒▒▒▒▒▒▒▒▒▒▒▒▒▒
a_lodsboutaw03: ;size optimization related entry (instrument loading)
call a_lodsboutaw
add ah,3
a_lodsboutaw: ;size optimization related entry (instrument loading)
lodsb
a_outaw PROC NEAR ;ah=reg,al=data
push ax
push cx
xchg al,ah
mov dx,388h
out dx,al
mov cx,7
call a_wait
mov dx,389h
mov al,ah
out dx,al
mov cx,30
call a_wait
pop cx
pop ax
ret
a_wait: in al,dx
loop a_wait
ret
a_outaw ENDP
;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ load instrument to adlib ▒▒▒▒▒▒▒▒▒▒▒▒▒▒
a_loadinstrument PROC NEAR
;bx=channel, ds:si=offset to instrument data
mov ah,ds:a_inst_table[bx]
mov cx,4
@@1: call a_lodsboutaw03
add ah,20h-3
loop @@1
add ah,40h
call a_lodsboutaw03
mov ah,bl
add ah,0c0h
jmp a_lodsboutaw
a_loadinstrument ENDP
;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ set note on/off ▒▒▒▒▒▒▒▒▒▒▒▒▒▒
a_playnote PROC NEAR
;bx=channel, ax=data
push bx
xchg ah,bl
add ah,0a0h
call a_outaw
mov al,bl
add ah,010h
pop bx
jmp a_outaw
a_playnote ENDP
;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ initialize/clear/shutup adlib ▒▒▒▒▒▒▒▒▒▒▒▒▒▒
a_init PROC NEAR
mov ax,00120h
call a_outaw
mov ax,00800h
call a_outaw
mov ah,0bdh
call a_outaw
mov bp,9
xor bx,bx
mov di,OFFSET music_instruments
@@1: mov si,ds:[di]
add di,2
call a_loadinstrument
xor ax,ax
call a_playnote
inc bx
dec bp
jnz @@1
ret
a_init ENDP
;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ advance music one row ▒▒▒▒▒▒▒▒▒▒▒▒▒▒
a_dorow PROC NEAR
sub ds:a_musiccnt,1
jnc @@0
mov ds:a_musiccnt,music_speed
mov cx,music_channels
mov di,OFFSET music_patterns
xor bx,bx
@@1: sub ds:a_chdelaycnt[bx],1
jns @@2
mov si,ds:[di]
xor ax,ax
call a_playnote
@@4: lodsb
or al,al
jz @@7
jns @@6
sub al,81h
mov ds:a_chdelay[bx],al
lodsb
@@6: mov dl,al
and ax,15
mov bp,ax
add bp,bp
mov ax,ds:a_note_table[bp]
shr dl,2
and dl,not 3
add ah,dl
call a_playnote
mov al,ds:a_chdelay[bx]
mov ds:a_chdelaycnt[bx],al
mov ds:[di],si
@@2: add di,4
inc bx
loop @@1
@@0: ret
@@7: mov si,ds:[di+2]
jmp @@4
a_dorow ENDP
;███████████████ Intro Routines ████████████████████
;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ sin/cos ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
;entry: ax=angle (0..65535)
; exit: ax=muller (-127..127)
addwcos:add ax,ds:[bx] ;optimized entry for wavesets
mov ds:[bx],ax
cos: add ax,16384
sin: mov bx,ax
mov cx,bx
and cx,1023
neg cx
add cx,1023
shr bx,10
mov ah,ds:sintable[bx]
xor al,al
imul cx
push ax
push dx
mov ah,ds:sintable[bx+1]
xor al,al
neg cx
add cx,1023
imul cx
pop bx
pop cx
add ax,cx
adc dx,bx
shrd ax,dx,11
ret
;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ rand ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
;returns a random value in range -4096..4095
rand PROC NEAR
mov eax,1107030247
mul ds:seed
add eax,97177
mov ds:seed,eax
shr eax,15
and ax,8191
sub ax,4096
;size optimizatin, some code moved from after all rand calls
add bx,2
mov ds:[bx],ax
ret
rand ENDP
;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ timer ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
inittimer PROC NEAR
mov eax,fs:[8*4]
mov ds:oldint8,eax
mov ax,cs
shl eax,16
mov ax,OFFSET intti8
mov dx,17000 ;70hz
jmp @@1
deinittimer:
mov eax,ds:oldint8
xor dx,dx
@@1: cli
mov fs:[8*4],eax
mov al,036h
out 43h,al
mov al,dl
out 40h,al
mov al,dh
out 40h,al
sti
ret
inittimer ENDP
intti8 PROC FAR ;timer interrupt
push ax
mov al,20h
out 20h,al
inc cs:framecounter
pop ax
iret
intti8 ENDP
;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ load indexed palette ▒▒▒▒▒▒▒▒▒▒▒▒▒▒
setpal PROC NEAR
;ds:si=pointer to colorindices
mov dx,3c8h
xor al,al
out dx,al
inc dx
mov cx,8
@@1: xor bh,bh
mov bl,ds:[si]
shr bl,2
call setpl2
mov bl,ds:[si]
shl bx,2
call setpl2
inc si
loop @@1
ret
setpl2: and bx,15*2
mov ax,word ptr ds:col0[bx]
out dx,al
mov al,ah
out dx,al
mov al,ds:col0[bx+2]
out dx,al
ret
setpal ENDP
;▒▒▒▒▒▒▒▒▒▒▒▒▒▒ clear & copy videobuffer to screen ▒▒▒▒▒▒▒▒▒▒▒▒▒▒
clearcopy PROC NEAR
;---copy/clear buf
xor edx,edx
mov si,OFFSET vbuf
mov bx,4
mov cx,200
mov di,-4
@@1: mov bp,5
@@2: REPT 2
mov eax,ds:[si]
add di,bx
mov ds:[si],edx
add si,bx
mov es:[di],eax
ENDM
dec bp
jnz @@2
add si,bx
dec cx
jnz @@1
ret
clearcopy ENDP
;▒▒▒▒▒▒▒▒▒▒▒▒▒▒ draw a small pixel ▒▒▒▒▒▒▒▒▒▒▒▒▒▒
pset1 PROC NEAR ;ds:di=destination center, si=xmask offset
mov al,ds:colb[si]
or ds:[di],al
@@1: ret
pset1 ENDP
;▒▒▒▒▒▒▒▒▒▒▒▒▒▒ draw a big pixel (depending on Z) ▒▒▒▒▒▒▒▒▒▒▒▒▒
pset2 PROC NEAR ;ds:di=destination center, si=xmask offset
mov ax,ds:colbww[si]
or ds:[di+0],ax
or ds:[di+44],ax
cmp bp,8300 ;zcompare for size
jl pset3
;smaller one
mov ax,ds:colbw[si]
or ds:[di-44],ax
or ds:[di+88],ax
mov ax,ds:colbv[si]
or ds:[di-88],ax
or ds:[di+132],ax
ret
pset3: ;larger one
or ds:[di-44],ax
or ds:[di+88],ax
mov ax,ds:colbw[si]
or ds:[di-88],ax
or ds:[di+132],ax
ret
pset2 ENDP
;▒▒▒