mirror of https://github.com/nmlgc/ReC98.git
278 lines
4.7 KiB
NASM
278 lines
4.7 KiB
NASM
; master library - BGM
|
|
;
|
|
; Description:
|
|
;
|
|
;
|
|
; Function/Procedures:
|
|
; int _bgm_play(int sp, int ep, int rp);
|
|
;
|
|
; Parameters:
|
|
;
|
|
;
|
|
; Returns:
|
|
;
|
|
;
|
|
; Binding Target:
|
|
; Microsoft-C / Turbo-C / Turbo Pascal
|
|
;
|
|
; Running Target:
|
|
; PC-9801V
|
|
;
|
|
; Requiring Resources:
|
|
; CPU: V30
|
|
;
|
|
; Notes:
|
|
;
|
|
;
|
|
; Assembly Language Note:
|
|
;
|
|
;
|
|
; Compiler/Assembler:
|
|
; TASM 3.0
|
|
; OPTASM 1.6
|
|
;
|
|
; Author:
|
|
; femy(淀 文武) : オリジナル・C言語版
|
|
; steelman(千野 裕司) : アセンブリ言語版
|
|
; 恋塚
|
|
;
|
|
; Revision History:
|
|
; 93/12/19 Initial: b_play.asm / master.lib 0.22 <- bgmlibs.lib 1.12
|
|
; 94/ 4/11 [M0.23] AT互換機対応
|
|
|
|
BGM_BELL:
|
|
push SI
|
|
mov SI,BX
|
|
|
|
;マスクON ならリターン
|
|
cmp [SI].SGLB.pmask,ON
|
|
je short B_PLAY_EXIT
|
|
;spval = (ulong)(note_dat[part2->note - 'A'] * 2);
|
|
mov BX,[SI].SPART.note
|
|
shl BX,1
|
|
mov BX,note_dat[BX-('A'*2)]
|
|
|
|
cmp [SI].SPART.oct,1
|
|
jne short B_PLAY_NOTOCT1
|
|
shl BX,1
|
|
jmp short B_PLAY_OCT1
|
|
B_PLAY_NOTOCT1:
|
|
;spval = (ulong)(note_dat[part2->note - 'A'] / octdat[part2->oct - 1]);
|
|
mov CX,[SI].SPART.oct
|
|
dec CX
|
|
dec CX
|
|
shr BX,CL
|
|
B_PLAY_OCT1:
|
|
test Machine_State,10h ; PC/AT
|
|
jz short B_PLAY_PC98
|
|
;@@PCAT:
|
|
in AL,61h ;ビープON
|
|
or AL,3
|
|
out 61h,AL ; AT
|
|
mov AX,BX
|
|
mov BX,TVALATORG/2
|
|
mov CX,BEEP_CNT_AT
|
|
jmp short B_PLAY_DO_SCALE
|
|
EVEN
|
|
B_PLAY_PC98:
|
|
;ビープON (上にもってきたけど大丈夫かなあ)
|
|
mov AL,BEEP_ON
|
|
out BEEP_SW,AL ; 98
|
|
|
|
mov CX,BEEP_CNT
|
|
;BX = spval
|
|
;8MHz なら 998/1229倍する
|
|
xor AX,AX
|
|
mov ES,AX
|
|
test byte ptr ES:[0501H],80h
|
|
jz short B_PLAY_CLOCK10MHZ
|
|
;spval = spval * 998UL / 1229UL;
|
|
mov AX,BX
|
|
mov BX,TVAL8ORG/2
|
|
B_PLAY_DO_SCALE:
|
|
mul BX
|
|
mov BX,TVAL10ORG/2
|
|
div BX
|
|
mov BX,AX
|
|
B_PLAY_CLOCK10MHZ:
|
|
;タイマカウント値設定
|
|
mov AL,BL
|
|
mov DX,CX
|
|
out DX,AL ; 98,AT
|
|
mov AL,BH
|
|
out DX,AL ; 98,AT
|
|
;ビープON
|
|
; mov AL,BEEP_ON
|
|
; out BEEP_SW,AL
|
|
B_PLAY_EXIT:
|
|
pop SI
|
|
ret
|
|
|
|
func _BGM_PLAY
|
|
enter 4,0
|
|
push DI
|
|
push SI
|
|
_sp = (RETSIZE+3)*2
|
|
_ep = (RETSIZE+2)*2
|
|
_rp = (RETSIZE+1)*2
|
|
; register DI = pcnt
|
|
; register SI = mute
|
|
|
|
mov AX,glb.pcnt
|
|
imul BX,AX,type SPART
|
|
cmp part[BX].lcnt,MINLCNT
|
|
jne short @@MUTEISFALSE
|
|
cmp part[BX].tnt,ON
|
|
je short @@MUTEISFALSE
|
|
cmp part[BX].len,MINNOTE
|
|
je short @@MUTEISFALSE
|
|
mov SI,TRUE
|
|
jmp short @@MUTEISTRUE
|
|
@@MUTEISFALSE:
|
|
xor SI,SI ; FALSE
|
|
@@MUTEISTRUE:
|
|
;switch (glb.pcnt - sp) {
|
|
mov CX,[BP+_sp]
|
|
sub AX,CX
|
|
je short @@PART0
|
|
dec AX
|
|
je short @@PART1
|
|
dec AX
|
|
je short @@PART2
|
|
jmp short @@NOBELL
|
|
|
|
;パート0
|
|
even
|
|
@@PART0:
|
|
imul BX,CX,type SPART
|
|
cmp byte ptr part[BX].note,REST
|
|
je short @@PART0_NOT_BELL_PART0
|
|
or SI,SI
|
|
je short @@BELL_PART0
|
|
@@PART0_NOT_BELL_PART0:
|
|
cmp byte ptr part[BX+type SPART].note,REST
|
|
je short @@PART0_NOT_BELL_PART1
|
|
cmp part[BX+type SPART].lcnt,MINLCNT
|
|
jg short @@BELL_PART1
|
|
@@PART0_NOT_BELL_PART1:
|
|
cmp byte ptr part[BX+type SPART*2].note,REST
|
|
je short @@BELL_PART0
|
|
cmp part[BX+type SPART*2].lcnt,MINLCNT
|
|
jg short @@BELL_PART2
|
|
|
|
;パート0のベルを鳴らす
|
|
even
|
|
@@BELL_PART0:
|
|
add BX,offset part
|
|
jmp short @@BELL
|
|
|
|
|
|
;パート1
|
|
even
|
|
@@PART1:
|
|
imul BX,CX,type SPART
|
|
cmp byte ptr part[BX+type SPART].note,REST
|
|
je short @@PART1_NOT_BELL_PART1
|
|
or SI,SI
|
|
je short @@BELL_PART1
|
|
@@PART1_NOT_BELL_PART1:
|
|
cmp byte ptr part[BX].note,REST
|
|
jne short @@NOBELL
|
|
cmp byte ptr part[BX+type SPART*2].note,REST
|
|
je short @@NOBELL
|
|
cmp part[BX+type SPART*2].lcnt,MINLCNT
|
|
jle short @@NOBELL
|
|
jmp short @@BELL_PART2
|
|
|
|
;パート1のベルを鳴らす
|
|
even
|
|
@@BELL_PART1:
|
|
add BX,offset part+type SPART
|
|
jmp short @@BELL
|
|
|
|
|
|
;パート2
|
|
even
|
|
@@PART2:
|
|
imul BX,CX,type SPART
|
|
cmp byte ptr part[BX+type SPART*2].note,REST
|
|
je short @@NOBELL
|
|
or SI,SI
|
|
jne short @@NOBELL
|
|
|
|
;パート2のベルを鳴らす
|
|
even
|
|
@@BELL_PART2:
|
|
add BX,offset part+(type SPART*2)
|
|
even
|
|
@@BELL:
|
|
call BGM_BELL
|
|
even
|
|
@@NOBELL:
|
|
|
|
|
|
;音長カウンタデクリメント
|
|
imul BX,glb.pcnt,type SPART
|
|
dec part[BX].lcnt
|
|
jne short @@NOTPARTEND
|
|
;パート終了チェック
|
|
add BX,offset part
|
|
push BX
|
|
nopcall _BGM_MGET
|
|
or AX,AX
|
|
jne short @@NOTPARTEND
|
|
mov CL,byte ptr glb.pcnt
|
|
inc AX
|
|
shl AX,CL
|
|
or glb.fin,AX
|
|
@@NOTPARTEND:
|
|
|
|
;次のパートに移す
|
|
mov AX,word ptr [BP+_ep]
|
|
inc glb.pcnt
|
|
cmp glb.pcnt,AX
|
|
jne short @@NOTALLPARTEND
|
|
mov AX,word ptr [BP+_rp]
|
|
mov glb.pcnt,AX
|
|
|
|
;全てのパートが終了したらパート初期化
|
|
cmp glb.fin,ALL_PART
|
|
jne short @@NOTALLPARTEND
|
|
|
|
xor DI,DI
|
|
mov glb.fin,DI
|
|
mov SI,offset part
|
|
even
|
|
@@PARTINITLOOP:
|
|
push SI
|
|
nopcall _BGM_PINIT
|
|
;part[pcnt].mask = ((glb.mask & (1 << pcnt)) ? ON : OFF);
|
|
mov CX,DI
|
|
mov AX,1
|
|
shl AX,CL
|
|
and AX,glb.pmask
|
|
cmp AX,1
|
|
sbb AX,AX
|
|
inc AX
|
|
mov [SI].msk,AX
|
|
push SI
|
|
nopcall _BGM_MGET
|
|
inc DI
|
|
add SI,type SPART
|
|
cmp SI,offset part+(type SPART*PMAX)
|
|
jb short @@PARTINITLOOP
|
|
|
|
mov AX,FINISH
|
|
pop SI
|
|
pop DI
|
|
leave
|
|
ret 6
|
|
even
|
|
@@NOTALLPARTEND:
|
|
xor AX,AX ;NOTFIN
|
|
pop SI
|
|
pop DI
|
|
leave
|
|
ret 6
|
|
endfunc
|