; 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].pmask,ON je short @@EXIT ;spval = (ulong)(note_dat[part2->note - 'A'] * 2); mov BX,[SI].note shl BX,1 mov BX,note_dat[BX-('A'*2)] cmp [SI].oct,1 jne short @@NOTOCT1 shl BX,1 jmp short @@OCT1 @@NOTOCT1: ;spval = (ulong)(note_dat[part2->note - 'A'] / octdat[part2->oct - 1]); mov CX,[SI].oct dec CX dec CX shr BX,CL @@OCT1: test Machine_State,10h ; PC/AT jz short @@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 @@DO_SCALE EVEN @@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 @@CLOCK10MHZ ;spval = spval * 998UL / 1229UL; mov AX,BX mov BX,TVAL8ORG/2 @@DO_SCALE: mul BX mov BX,TVAL10ORG/2 div BX mov BX,AX @@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 @@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