summaryrefslogtreecommitdiff
path: root/piano/MYDZQ.ASM
diff options
context:
space:
mode:
Diffstat (limited to 'piano/MYDZQ.ASM')
-rw-r--r--piano/MYDZQ.ASM435
1 files changed, 435 insertions, 0 deletions
diff --git a/piano/MYDZQ.ASM b/piano/MYDZQ.ASM
new file mode 100644
index 0000000..7b1ccfa
--- /dev/null
+++ b/piano/MYDZQ.ASM
@@ -0,0 +1,435 @@
+;;; Record:C-R, Play:C-P, Save:C-S, Load:C-L
+
+RECKEY equ 12h
+SAVEKEY equ 13h
+PLAYKEY equ 10h
+LOADKEY equ 0ch
+P8255A_CTL equ 0e48bh
+P8255A_A equ 0e488h
+P8255A_B equ 0e489h
+
+data segment
+;;; data1: sine wave
+ data1 db 80h,96h,0aeh,0c5h,0d8h,0e9h,0f5h,0fdh
+ db 0ffh,0fdh,0f5h,0e9h,0d8h,0c5h,0aeh,96h
+ db 80h,66h,4eh,38h,25h,15h,09h,04h
+ db 00h,04h,09h,15h,25h,38h,4eh,66h
+;;; time: 8253 initial value
+ time db 120,106,94,89,79,70,63,59
+
+ msg db 'Press 1,2,3,4,5,6,7,8,ESC:',0dh,0ah,'$'
+ keys db 'qwertyuasdfghjzxcvbnm'
+ initval db ?
+ tmpval db ?
+ note dw 0
+ raisetune dw ?
+ recording db 0
+;;; a big buffer for recording
+ BUFSIZE equ 200h
+ datasize dw 0
+ buffer db BUFSIZE dup(?)
+;;; File param
+ fnmax db 0ffh
+ fnlen db ?
+ filename db 0ffh dup (?)
+ handle dw ?
+ prompt db 'Filename: ', '$'
+;;; The Graphical Interface
+ pianoui db 'aaabbbbcddddeeefffgggghiiiijkkkklll', 0
+ db 'aaabbbbcddddeeefffgggghiiiijkkkklll', 0
+ db 'aaabbbbcddddeeefffgggghiiiijkkkklll', 0
+ db 'aaabbbbcddddeeefffgggghiiiijkkkklll', 0
+ db 'aaabbbbcddddeeefffgggghiiiijkkkklll', 0
+ db 'aaabbbbcddddeeefffgggghiiiijkkkklll', 0
+ db 'aaaaaccccceeeeefffffhhhhhjjjjjlllll', 0
+ db 'aaaaaccccceeeeefffffhhhhhjjjjjlllll', 0
+ db 'aaaaaccccceeeeefffffhhhhhjjjjjlllll', 0
+ db 'aaaaaccccceeeeefffffhhhhhjjjjjlllll', 0
+ db 0ffh
+ colors db 01111111b, 00001000b, 01111111b, 00001000b, 01111111b, 01111111b
+ db 00001000b, 01111111b, 00001000b, 01111111b, 00001000b, 01111111b
+ showcode db 0
+
+data ends
+
+stack segment stack
+mysp db 100h dup (?)
+sttop equ $-mysp
+stack ends
+
+code segment
+ assume cs:code,ds:data
+ extrn _transkey: near
+ extrn _get_showcode: near
+start: mov ax,data
+ mov ds,ax
+ mov es,ax
+ mov ax, stack
+ mov ss, ax
+ mov sp, sttop
+ call graphic_init
+ mov dx, 0510h
+ call showui
+ call ledoff
+
+sss: mov ah,0
+ int 16h ; getkey
+
+ cmp al, 1bh
+ jne TREC ; ESC=>exit
+ mov ax, 4c00h
+ int 21h
+ ;; program ends
+TREC:
+ cmp al, RECKEY
+ jne TSAVE
+ mov recording, 1
+ mov datasize, 0
+ call ledon
+ jmp sss
+TSAVE:
+ cmp al, SAVEKEY
+ jne TLOAD
+ mov recording, 0
+ call savetofile
+ call ledoff
+ jmp sss
+TLOAD:
+ cmp al, LOADKEY
+ jne TPLAY
+ call loadfile
+ jmp sss
+TPLAY:
+ cmp al, PLAYKEY
+ jne TSPACE
+ call playaudio
+ jmp sss
+TSPACE:
+ cmp al, ' '
+ jne TBACKSP
+ cmp recording, 1
+ jne sss ; ignore it
+ mov bx, datasize
+ mov buffer[bx], 0
+ inc datasize
+ jmp sss
+TBACKSP:
+ cmp al, 08 ; backspace
+ jne OTHERKEY
+ cmp datasize, 0
+ js nodec
+ dec datasize ; sub datasize by 1 regardless of the state
+nodec:
+ jmp sss
+
+OTHERKEY:
+ mov raisetune, 0
+ cmp al, 'A'
+ jl sss
+ cmp al, 'Z'
+ jg lowerletter
+ mov raisetune, 1
+ or al, 00100000b
+
+lowerletter:
+ mov di, offset keys
+ mov cx, 21
+ repnz scasb
+ jz trans ; key found
+ jmp sss
+trans:
+ sub di, offset keys
+ dec di ; index = di-keys-1
+ push di
+ call _transkey
+ add sp, 2
+ cmp ax, -1
+ jnz proctune
+ jmp sss
+
+proctune:
+ cmp ax, 16 ;; ax>=16 => high tune
+ jl mediumlow
+ and al, 00000111b
+ mov note, al
+ mov bx, offset time
+ xlat
+ shr al, 1
+ jmp tune
+mediumlow:
+ cmp ax, 8 ;; ax>=8 => medium tune
+ jl lowt
+ and al, 00000111b
+ mov note, al
+ mov bx, offset time
+ xlat
+ jmp tune
+lowt:
+ and al, 00000111b
+ mov note, al
+ mov bx, offset time
+ xlat
+ shl al, 1
+tune:
+ cmp raisetune, 1
+ jne process
+ cbw
+ push ax
+ call raisehalf
+
+process:
+ mov initval, al
+ ;; show ui
+ push raisetune
+ push note
+ call _get_showcode
+ mov showcode, al
+ mov dx, 0510h
+ call showui
+ ;; record
+ cmp recording, 1
+ jne norec
+ mov al, initval
+ mov bx, datasize
+ mov buffer[bx], al
+ inc datasize
+norec:
+ mov al, initval
+ mov tmpval, al
+ call playtune
+ jmp sss
+
+exit:
+ mov ah,4ch
+ int 21h
+
+playtune proc near
+;;; play sound according to the init value of 8253
+;;; initval store in tmpval
+ push cx
+ push si
+ push dx
+
+ mov cx,60 ; 60 waves
+ddd: mov si,0
+lll: mov al,data1[si] ;取正弦波数据
+ mov dx,0e490h
+ out dx,al ;放音
+ call delay ;调延时子程序
+ inc si
+ cmp si,32 ;是否取完32个数据
+ jl lll ;若没有,则继续
+ loop ddd ;总循环次数60是否完,没有,则继续
+
+ pop dx
+ pop si
+ pop cx
+ ret
+playtune endp
+
+delay proc near
+;;; delay and play according to tmpval
+ccc: ;mov bx,offset time
+ mov dx,0e483h ;置8253通道0为方式0工作
+ mov al,10h
+ out dx,al
+ mov dx, P8255A_CTL
+ mov al,90h ; a in, method 0
+ out dx,al
+ mov al,tmpval
+ mov dx,0e480h
+ out dx,al ; output the initial value to 8253
+kkk: mov dx, P8255A_A
+ in al,dx ;从8255A口读一字节
+ test al,01 ;判PA0口是否为1
+ jz kkk ;若不为1,则转KKK
+ ret ;子程序返回
+delay endp
+
+raisehalf proc near
+;; al: initial value
+;; output the new initial value to ax
+;; 2^(1/12) = 1.0594631
+;; first mul 10000, then div 10595
+ push dx
+ push cx
+ cbw
+ mov cx, 10000
+ mul cx
+ mov cx, 10595
+ div cx
+ pop cx
+ pop dx
+ ret
+raisehalf endp
+
+graphic_init proc near
+ xor ah, ah
+ mov al, 3
+ int 10h
+ mov ah, 6
+ xor al, al
+ mov bh, 00100000b
+ mov ch, 0
+ mov cl, 0
+ mov dh, 24
+ mov dl, 79
+ int 10h
+ ret
+graphic_init endp
+
+showui proc near
+;;; show code stored in mem
+;;; dh, dl: line, column
+
+;;; initialize cursor
+ push ax
+ push bx
+ push cx
+ push si
+
+ mov si, offset pianoui
+ mov cx, 1
+ push dx
+show_loop:
+ cmp byte ptr [si], 0ffh
+ jz show_end
+ cmp byte ptr [si], 0
+ jnz show_cont
+ pop dx
+ inc dh
+ push dx
+ inc si
+ jmp show_loop
+show_cont:
+ ;; set cursor
+ xor bx, bx
+ mov ah, 2
+ int 10h
+
+ mov al, [si]
+ cmp byte ptr showcode, al
+ jz set_color
+ sub al, 'a'
+ mov bx, offset colors
+ xlat
+ mov bl, al
+ jmp show_sp
+set_color:
+ mov bl, 00011000b
+show_sp:
+ mov ah, 9
+ mov al, ' '
+ xor bh, bh
+ int 10h
+
+ inc dl
+ inc si
+ jmp show_loop
+show_end:
+ pop dx
+ pop si
+ pop cx
+ pop bx
+ pop ax
+ ret
+showui endp
+
+playaudio proc near
+ mov cx, datasize
+ cmp cx, BUFSIZE
+ ja pret
+ mov bx, offset buffer
+playloop:
+ mov al, [bx]
+ mov tmpval, al
+ call playtune
+ inc bx
+ loop playloop
+pret:
+ ret
+playaudio endp
+
+savetofile proc near
+ call getfilename
+ ;; create file
+ mov ah, 3ch
+ xor cx, cx
+ mov dx, offset filename
+ int 21h
+ mov handle, ax
+ ;; save data
+ mov cx, datasize
+ add cx, 2
+ mov dx, offset datasize
+ mov bx, handle
+ mov ah, 40h
+ int 21h
+ ;; close file
+ mov ah, 3eh
+ int 21h
+ ret
+savetofile endp
+
+loadfile proc near
+ call getfilename
+ ;; open file
+ mov ah, 3dh
+ mov dx, offset filename
+ mov al, 0
+ int 21h
+ mov handle, ax
+ ;; read
+ mov dx, offset datasize
+ mov bx, ax
+ mov ah, 3fh
+ mov cx, BUFSIZE
+ int 21h
+ ;; close
+ mov ah, 3fh
+ int 21h
+ ret
+loadfile endp
+
+getfilename proc near
+ mov ah, 2
+ mov bh, 0
+ mov dx, 1410h
+ int 10h
+ mov dx, offset prompt
+ mov ah, 9
+ int 21h
+ mov dx, offset fnmax
+ mov ah, 0ah
+ int 21h
+ mov bx, offset filename
+ mov al, fnlen
+ cbw
+ add bx, ax
+ mov byte ptr [bx], 0
+ ret
+getfilename endp
+
+ledon proc near
+ mov dx, P8255A_CTL
+ mov al, 10000000b ; method 0, b out
+ out dx, al
+ mov dx, P8255A_B
+ mov al, 1
+ out dx, al
+ ret
+ledon endp
+
+ledoff proc near
+ mov dx, P8255A_CTL
+ mov al, 10000000b ; method 0, b out
+ out dx, al
+ mov dx, P8255A_B
+ mov al, 0
+ out dx, al
+ ret
+ledoff endp
+
+code ends
+ end start
+