:
: ;
: ; PIANO.ASM [ - For DOS - ]
: ; Simple PC Speaker Piano Keyboard
: ; Freeware from Evenbit
: ;
: ;
: .model tiny
: .code
: org 100h
:
: main: jmp start
: ;
: stor dw 0 ;our memory location storage
: ;
: ; Turn the cursor off.
: ;
: start:
: call curs_off ;go turn off cursor
: ;
: ; Get a keypress from the user, and act accordingly.
: ; (We're checking U.S. keyboard scan codes here.)
: ;
: get_key:
: mov ah,0 ;function 0 - wait for keypress
: int 16h ;call ROM BIOS keyboard services
: cmp ah,1 ;ESC key pressed?
: je exit ;yes, so go exit
: cmp ah,02h
: je tone_1
: cmp ah,03h
: je tone_2
: cmp ah,04h
: je tone_3
: cmp ah,05h
: je tone_4
: cmp ah,06h
: je tone_5
: cmp ah,07h
: je tone_6
: cmp ah,08h
: je tone_7
: cmp ah,09h
: je tone_8
: cmp ah,0ah
: je tone_9
: cmp ah,0bh
: je tone_0
: ;
: jmp get_key ;go get another keypress
: ;
: exit:
: call curs_on ;go turn cursor on
: int 20h ;exit to DOS
: ;
: tone_1:
: mov ax, 272
: mov stor, ax
: call sounder ;go generate the tone
: jmp get_key ;go get another keypress
: tone_2:
: mov ax, 294
: mov stor, ax
: call sounder ;go generate the tone
: jmp get_key ;go get another keypress
: tone_3:
: mov ax, 314
: mov stor, ax
: call sounder ;go generate the tone
: jmp get_key ;go get another keypress
: tone_4:
: mov ax, 330
: mov stor, ax
: call sounder ;go generate the tone
: jmp get_key ;go get another keypress
: tone_5:
: mov ax, 350
: mov stor, ax
: call sounder ;go generate the tone
: jmp get_key ;go get another keypress
: tone_6:
: mov ax, 370
: mov stor, ax
: call sounder ;go generate the tone
: jmp get_key ;go get another keypress
: tone_7:
: mov ax, 392
: mov stor, ax
: call sounder ;go generate the tone
: jmp get_key ;go get another keypress
: tone_8:
: mov ax, 419
: mov stor, ax
: call sounder ;go generate the tone
: jmp get_key ;go get another keypress
: tone_9:
: mov ax, 440
: mov stor, ax
: call sounder ;go generate the tone
: jmp get_key ;go get another keypress
: tone_0:
: mov ax, 475
: mov stor, ax
: call sounder ;go generate the tone
: jmp get_key ;go get another keypress
:
:
:
: ;
: ;****************************************
: ; Our sub-routines start here.
: ;****************************************
: ;
: ; Turn cursor off.
: ;
: curs_off:
: mov ch,10h ;set bits to turn cursor off
: mov ah,1 ;function 1 - cursor control
: int 10h ;call ROM BIOS video services
: ret ;return to caller
: ;
: ; Turn cursor on.
: ;
: curs_on:
: mov cx,0506h ;set bits to turn cursor on
: mov ah,1 ;function 1 - cursor control
: int 10h ;call ROM BIOS video services
: ret ;return to caller
: ;
: ; Generate sound through the PC speaker.
: ;
:
: sounder:
: mov al,10110110b ;load control word
: out 43h,al ;send it
: mov ax,stor ;tone frequency
: out 42h,al ;send LSB
: mov al,ah ;move MSB to AL
: out 42h,al ;save it
: in al,61h ;get port 61 state
: or al,00000011b ;turn on speaker
: out 61h,al ;speaker on now
: call delay ;go pause a little bit
: and al,11111100b ;clear speaker enable
: out 61h,al ;speaker off now
: call clr_keyb ;go clear the keyboard buffer
: ret ;return to caller
:
: delay:
: mov ah,00h ;function 0 - get system timer tick
: int 01Ah ;call ROM BIOS time-of-day services
: add dx,4 ;add our delay value to DX
: mov bx,dx ;store result in BX
: pozz:
: int 01Ah ;call ROM BIOS time-of-day services
: cmp dx,bx ;has the delay duration passed?
: jl pozz ;no, so go check again
: ret ;return to caller
: ;
: ; Clear the keyboard buffer.
: ;
: clr_keyb:
: push es ;preserve ES
: push di ;preserve DI
: mov ax,40h ;BIOS segment in AX
: mov es,ax ;transfer to ES
: mov ax,1Ah ;keyboard head pointer in AX
: mov di,ax ;transfer to DI
: mov ax,1Eh ;keyboard buffer start in AX
: mov es: word ptr [di],ax ;transfer to head pointer
: inc di ;bump pointer to...
: inc di ;...keyboard tail pointer
: mov es: word ptr [di],ax ;transfer to tail pointer
: pop di ;restore DI
: pop es ;restore ES
: ret ;return to caller
: ;
: end main
: end
:
:
: When you run the program, you'll just press (0-9) and the sound will produce, while ESC exits the program.
:
:
: Here I learn something: (I'm referring to the RED code)
:
: 1.) OUT is putting something to the port while IN is getting something to the port.
Correct
: 2.) (10110110b = 182 = B6h) was sent to port 43h. According to http://fly.cc.fer.hr/GDM/articles/sndmus/speaker1.html, Port 43h is a System Timer 2, is used to control sound generation. And the number that was inputed to it is countdown value (is it the same with frequency?).
This only sets up the speaker for sound generation
:
: 3.) Then the STOR was sent to AX (What will be put to AH and AL?).
If you look at the tone section depending on the tone the frequency is stored to stor.
: 4.) Then "something" (because I don't know what went to AL) was sent to Port 42h. It said Port 42h is used to set the LOW and HIGH byte (What is it? Is it the peaks and bottoms of the frequency?). Twice... (Can't understand this thing, will the second value OVERWRITE the first value?)
No, port 42h is 8bit but you must send a 16bit value to it so how do you do that? You send the LSB(Least Significant Byte) and then the MSB(Most Significant Byte). Since the instruction 'out' can only take a 8bit value from AL, you must plug in the LSB into AL first and send it then plug in the MSB into AL next and send it
:
: 5.) What are these things:
:
:
: or al,00000011b ;turn on speaker
: and al,11111100b ;clear speaker enable
:
The 1st one makes sure bits 1 and 0 are on no matter what. The second clears bits 1 and 0 because anything 'anded' with 0 is false.
: What's the meaning or OR and AND commands?
'Or' is to set bits 'on' and 'and' is usually used to check a bit for truth or clear bits.
: QUESTIONS: I summarized all here:
:
: 1.) Is countdown value the same with frequency?
No
: 2.) If I put 475 to AX, what will be put in AH and AL?
Register AX=AH+AL
AX
AH + AL =475
0000 0001 1101 1011
: 3.) Is the LOW and HIGH byte the peaks and bottoms of the frequency?
No, its just a frequency value from 0-65536
: 4.) If I sent two values in a port, will the second value OVERWRITE the first one? (Co'z that's my understanding, AX = VALUE1 then AX = VALUE 2, therefore AX is VALUE2)
I explained why you must send 2 bytes to this port earlier
: 5.) What's the meaning or OR and AND commands?
Already answered
: 6.) I tried to find some manuals in Intel Processor in
http://www.intel.com/ but all I could see is Processors and it's specs... Where can I get an Intel Documentation?
:
[/green]
http://www.fh-bochum.de/fb3/meva-lab/docu/
Download the intel vol 1 and 2. Vol 3 is for system programming which you don't need yet. Also, download the dosints.pdf.
[/green]