summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIru Cai <mytbk920423@gmail.com>2018-04-23 11:42:13 +0800
committerIru Cai <mytbk920423@gmail.com>2018-04-23 11:42:13 +0800
commited37a1a83a1a581ad4ff0fdd96d7e9617dd558fd (patch)
treed3d68810310003a45ba71804a60ba5f863e10ea8
parent72498722f988c639b38104c8d4589629b1761c0f (diff)
downloadbitbucket-ed37a1a83a1a581ad4ff0fdd96d7e9617dd558fd.tar.xz
DOS piano program
-rw-r--r--piano/COMPILE.BAT3
-rw-r--r--piano/COMPILE2.BAT3
-rw-r--r--piano/MYDZQ.ASM435
-rw-r--r--piano/pianoui.c42
4 files changed, 483 insertions, 0 deletions
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';
+}
+