Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- .286
- .287
- myCode segment para 'code'
- assume cs:myCode
- assume ss:myStack
- assume ds:myData
- start:
- mov ax,myData
- mov ds,ax
- push offset music
- call far ptr cvt_music
- add sp,2
- mov nNotes,ax
- call far ptr inst_kbd
- call far ptr inst_metro
- call far ptr set_mode_13
- xor cx,cx
- xor bx,bx
- forever:
- xor ax,ax
- mov dx,3c8h
- out dx,al
- inc dx
- mov al,ch
- out dx,al
- out dx,al
- mov al,3fh
- out dx,al
- cmp bx,0
- jne reverse
- add cx,10h
- cmp ch,40h
- jne skip_reset
- mov bx,1
- sub cx,10h
- jmp skip_reset
- reverse:
- sub cx,10h
- cmp ch,40h
- jna skip_reset
- mov bx,0
- add cx,10h
- skip_reset:
- hlt
- cmp dying,1
- jne forever
- call far ptr rem_metro
- call far ptr rem_kbd
- call far ptr set_mode_txt
- mov ah,4ch
- int 21h
- ends myCode
- farCode segment para 'farcode'
- assume cs:farCode
- assume ss:myStack
- assume ds:myData
- set_mode_13:
- mov ax,13h
- int 10h
- retf
- set_mode_txt:
- mov ax,3h
- int 10h
- retf
- note_freq:
- nf_semi equ [bp+4]
- nf_cntr equ word ptr [bp-2]
- nf_cona equ 48
- push bp
- mov bp,sp
- push ax
- mov ax,nf_semi
- sub ax,nf_cona
- ja nf_high
- fld freq_base_inv
- neg ax
- jmp nf_skip_high
- nf_high:
- fld freq_base
- nf_skip_high:
- fld1
- cmp ax,0
- je nf_skip_power
- nf_power_loop:
- fmul st(0),st(1)
- dec ax
- jnz nf_power_loop
- nf_skip_power:
- fld freq_timer_prediv
- fdiv st(0),st(1)
- fist nf_cntr
- pop ax
- pop bp
- ret
- txt_to_semi:
- ts_src equ [bp+4]
- push bp
- mov bp,sp
- push si
- push di
- mov si,ts_src
- xor cx,cx
- mov cl,[si]
- cmp cl,'-'
- jne ts_norest
- mov ax,0ffffh
- jmp ts_done
- ts_norest:
- sub cl,'A'
- mov di,cx
- mov cl,[note_names+di]
- inc si
- mov al,[si]
- sub al,'0'
- mov ah,12
- mul ah
- inc si
- cmp byte ptr [si],'#'
- jne ts_nosharp
- inc cx
- jmp ts_noflat
- ts_nosharp:
- cmp byte ptr [si],'b'
- jne ts_noflat
- dec cx
- ts_noflat:
- add ax,cx
- ts_done:
- pop di
- pop si
- pop bp
- ret
- cvt_music:
- cm_music equ [bp+6]
- push bp
- mov bp,sp
- push si
- push di
- mov si,cm_music
- mov di,cm_music
- cm_loop:
- cmp byte ptr [si],'$'
- je cm_done
- push si
- call txt_to_semi
- add sp,2
- cmp ax,0ffffh
- je cm_rest
- push ax
- call note_freq
- add sp,2
- jmp cm_rest_skip
- cm_rest:
- mov ax,0
- cm_rest_skip:
- mov [di],ax
- add di,2
- add si,3
- jmp cm_loop
- cm_done:
- sub di,cm_music
- shr di,1
- mov ax,di
- pop di
- pop si
- pop bp
- retf
- inst_metro:
- metro_freq_div equ 800h
- push es
- xor ax,ax
- mov es,ax
- cli
- mov ax,es:[0020h]
- mov oldTimerIsrOff,ax
- mov ax,es:[0022h]
- mov oldTimerIsrSeg,ax
- mov word ptr es:[0020h],offset metro_isr
- mov word ptr es:[0022h],farCode
- mov al,00110100b ; meaning that we're about to load
- out 43h,al ; a new countdown value
- mov ax,metro_freq_div
- out 40h,al ; Output low byte.
- mov al,ah ; Output high byte.
- out 40h,al
- sti
- push iNote
- call do_music_cmd
- add sp,2
- pop es
- retf
- rem_metro:
- push es
- xor ax,ax
- mov es,ax
- cli
- mov ax,oldTimerIsrOff
- mov es:[0020h],ax
- mov ax,oldTimerIsrSeg
- mov es:[0022h],ax
- mov al,00110100b ; meaning that we're about to load
- out 43h,al ; a new countdown value
- mov ax,0
- out 40h,al ; Output low byte.
- mov al,ah ; Output high byte.
- out 40h,al
- sti
- call speaker_off
- pop es
- retf
- speaker_on:
- in al,61h
- or al,00000011b
- out 61h,al
- ret
- speaker_off:
- in al,61h
- and al,11111100b
- out 61h,al
- ret
- set_speaker_tone:
- st_new_tone equ [bp+4]
- push bp
- mov bp,sp
- mov al,10110110b ; meaning that we're about to load
- out 43h,al ; a new countdown value into channel 0
- mov ax,st_new_tone
- out 42h,al ; Output low byte.
- mov al,ah ; Output high byte.
- out 42h,al
- pop bp
- ret
- do_music_cmd:
- dmc_icmd equ [bp+4]
- push bp
- mov bp,sp
- push bx
- mov bx,dmc_icmd
- shl bx,1
- mov bx,[bx + offset music]
- cmp bx,0
- je music_rest
- call speaker_on
- jmp music_rest_skip
- music_rest:
- call speaker_off
- jmp music_done
- music_rest_skip:
- push bx
- call set_speaker_tone
- add sp,2
- music_done:
- pop bx
- pop bp
- ret
- inst_kbd:
- push es
- xor ax,ax
- mov es,ax
- cli
- mov ax,es:[024h]
- mov old_kbd_off,ax
- mov word ptr es:[024h],offset kbd_isr
- mov ax,es:[026h]
- mov old_kbd_seg,ax
- mov word ptr es:[026h],farCode
- sti
- pop es
- retf
- rem_kbd:
- push es
- xor ax,ax
- mov es,ax
- cli
- mov ax,old_kbd_off
- mov es:[024h],ax
- mov ax,old_kbd_seg
- mov es:[026h],ax
- sti
- pop es
- retf
- metro_isr:
- dec metroCounter
- jz metro_cmd
- mov al,20h
- out 20h,al
- iret
- metro_cmd:
- push ax
- mov ax,metroStart
- mov metroCounter,ax
- mov ax,iNote
- inc ax
- cmp ax,nNotes
- jne metro_skip_wrap
- xor ax,ax
- metro_skip_wrap:
- mov iNote,ax
- push ax
- call do_music_cmd
- add sp,2
- mov al,20h
- out 20h,al
- pop ax
- iret
- kbd_isr:
- push ax
- in al,60h
- cmp al,01h
- jne finished
- mov [dying],1
- finished:
- mov al,020h
- out 020h,al
- pop ax
- iret
- ends farCode
- myData segment para 'data'
- oldTimerIsrOff dw ?
- oldTimerIsrSeg dw ?
- old_kbd_off dw ?
- old_kbd_seg dw ?
- dying dw 0
- default_tempo equ 100
- metroCounter dw default_tempo
- metroStart dw default_tempo
- freq_base dd 1.059463
- freq_base_inv dd 0.943874
- freq_timer_prediv dd 2711.775 ; pit oscillator frequency predivided by concert a
- note_names db 0,2,3,5,7,8,10
- iNote dw 0
- nNotes dw ?
- music db 'C3 D3 E3 G3 C4 D4 E4 G4 C5 D5 E5 G5 C6 D6 E6 G6 '
- db 'C7 G6 E6 D6 C6 G5 E5 D5 C5 G4 E4 D4 C4 G3 E3 D3 '
- db 'A3 B3 C3 E3 A4 B4 C4 E4 A5 B5 C5 E5 A6 B6 C6 E6 '
- db 'A7 E6 C6 B6 A6 E5 C5 B5 A5 E4 C4 B4 A4 E3 C3 B3 '
- db 'C3 D3 E3 G3 C4 D4 E4 G4 C5 D5 E5 G5 C6 D6 E6 G6 '
- db 'C7 G6 E6 D6 C6 G5 E5 D5 C5 G4 E4 D4 C4 G3 E3 D3 '
- db 'A3 B3 C3 E3 A4 B4 C4 E4 A5 B5 C5 E5 A6 B6 C6 E6 '
- db 'A7 E6 C6 B6 A6 E5 C5 B5 A5 E4 C4 B4 A4 E3 C3 B3 '
- db 'A3 C3 F3 G3 A4 C4 F4 G4 A5 C5 F5 G5 A6 C6 F6 G6 '
- db 'A7 G6 F6 C6 A6 G5 F5 C5 A5 G4 F4 C4 A4 G3 F3 C3 '
- db 'B3 D3 G3 A4 B4 D4 G4 A5 B5 D5 G5 A6 B6 D6 G6 A7 '
- db 'B7 A7 G6 D6 B6 A6 G5 D5 B5 A5 G4 D4 B4 A4 G3 D3 '
- db 'A3bC3 E3bG3 A4bC4 E4bG4 A5bC5 E5bG5 A6bC6 E6bG6 '
- db 'A7bG6 E6bC6 A6bG5 E5bC5 A5bG4 E4bC4 A4bG3 E3bC3 '
- db 'B3bD3 F3 A4 B4bD4 F4 A5 B5bD5 F5 A6 B6bD6 F6 A7 '
- db 'B7bA7 F6 D6 B6bA6 F5 D5 B5bA5 F4 D4 B4bA4 F3 D3 $'
- ends myData
- myStack segment para stack 'stack'
- ends myStack
- end start
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement