From ed37a1a83a1a581ad4ff0fdd96d7e9617dd558fd Mon Sep 17 00:00:00 2001 From: Iru Cai Date: Mon, 23 Apr 2018 11:42:13 +0800 Subject: DOS piano program --- piano/COMPILE.BAT | 3 + piano/COMPILE2.BAT | 3 + piano/MYDZQ.ASM | 435 +++++++++++++++++++++++++++++++++++++++++++++++++++++ piano/pianoui.c | 42 ++++++ 4 files changed, 483 insertions(+) create mode 100644 piano/COMPILE.BAT create mode 100644 piano/COMPILE2.BAT create mode 100644 piano/MYDZQ.ASM create mode 100644 piano/pianoui.c diff --git a/piano/COMPILE.BAT b/piano/COMPILE.BAT new file mode 100644 index 0000000..0ab4136 --- /dev/null +++ b/piano/COMPILE.BAT @@ -0,0 +1,3 @@ +masm mydzq.asm; +tcc -c pianoui.c +tlink mydzq.obj pianoui.obj,mydzq,nul,c:\turboc2\lib\cs diff --git a/piano/COMPILE2.BAT b/piano/COMPILE2.BAT new file mode 100644 index 0000000..f519068 --- /dev/null +++ b/piano/COMPILE2.BAT @@ -0,0 +1,3 @@ +masm mydzq.asm; +tcc -c pianoui.c +tlink mydzq.obj pianoui.obj,mydzq,nul,c:\tc\lib\cs 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 + diff --git a/piano/pianoui.c b/piano/pianoui.c new file mode 100644 index 0000000..10da0b7 --- /dev/null +++ b/piano/pianoui.c @@ -0,0 +1,42 @@ +enum TUNE{ + LOW=0, MEDIUM=(1<<3), HIGH=(2<<3) +}; + +int transkey(unsigned int index) +{ + int note, tune; + + note = index%7; + index /= 7; + switch(index){ + case 0: + tune = HIGH; + break; + case 1: + tune = MEDIUM; + break; + case 2: + tune = LOW; + break; + default: + return -1; + } + return note|tune; +} + +int get_showcode(unsigned int note, int raise) +{ + int idx; + if (note<=2){ + idx = note*2; + } + else{ + idx = note*2-1; + } + idx += raise; + if (idx>=12){ + idx -= 12; + } + return idx+'a'; +} + -- cgit v1.2.3