[BEFORE YOU READ THIS WORKS WITH THE NASM COMPILER, I'M NOT SURE ABOUT OTHER COMPILERS]
Your code is fine but here's the problem:
- It will not produce sound in a virtual machine.
What the 0x43, 0x42 ports are for are the PIT (Programmable Interval Timer) chip which handles somethings which you can read up on here OSDEVWIKI. One of the things the PIT chip handles is the on board speaker which is what you are trying to access. Virtual machines don't have an onboardspeaker.
Long story short you are trying to access the motherboard speaker but virtual machines can't use it so you don't hear anything.
Also most newer motherboards don't have on board speakers either.
- Your code.
So from just a glance at your code I'm guessing you're using nasm so I'm a little confused about this:
mov al, 182 ; meaning that we're about to load
mov ax, 182
out 43h, al ; a new countdown value
ret
To touch up this part a little you can remove the mov ax, 182
and the ret
because the return right there will jump out of the code to where you called it no longer running the code making:
mov ax, 2153 ; countdown value is stored in ax. It is calculated by
out 42h, al ; Output low byte.
mov al, ah ; Output high byte.
out 42h, al
in al, 61h
or al, 00000011b
out 61h, al ; Send the new value
ret
obsolete. For the mov ax, 182
when I use the speaker mine works without this so my guess is you don't need it so I'd say remove it if it is necessary.
So a revamped version of your code would be:
bits 16
start:
mov ax, 0x07c0 ; Setup the stack past where we are loaded
add ax, 544
cli ; Disable interrupts
mov ss, ax
mov sp, 4096
sti ; Restore interrupts
mov ax, 0x07c0 ; Set the data segment to where we are
mov ds, ax
sound:
mov al, 182 ; Were about to load
out 0x43, al
mov ax, 15000 ; 15000(Pitch) = 1,193,180 / 79.5453333(Repeating)
out 0x42, al ; Give the port the lower value
mov al, ah
out 0x42, al ; Now give it the higher
in al, 0x61
or al, 00000011b ; Connect the speaker to Timer 2
out 0x61, al
jmp $ ; hang
times 510-($-$$) db 0 ; Pad the rest of the file with 0's
dw 0xaa55 ; Little Endian MBR Signature
To run this to see if this works make sure the computer you have has an on board speaker. Mine looks like this:
here
If you don't have it yours may not look like mine, if there isn't one you could display or make something happen after the code to make sure it ran.
I use these commands to run it.
nasm -f bin <YOURFILENAME>.asm -o boot.bin
dd if=boot.bin of=\\.\<DRIVENUMBER>: bs=512
What these do is the nasm one is the nasm compiler and compiles the assembly file. The dd one is rawwrite if you are on linux it is already there, but on windows like I am using you can download rawwrite here. MAKE SURE YOUR DRIVE NUMBER IS THE DRIVE YOU ARE USING SUCH AS A USB OR FLOPPY. An example would be if your usb is on drive d: you would use:
dd if=boot.bin of=\\.\d: bs=512
Then you can plug the usb into the computer with the oscillator. Boot up the computer and get into the boot menu for me I just spam f10 until I get there but for you it may be a different button there you will be asked what device you should boot to find your usb and boot to it. It should boot if not have the os display something like:
mov ah, 0x0e
mov al, 'X'
int 0x10
To see if it is booting if not add this to the top of the file AFTER bits 16
:
jmp short start
nop
OEMLabel db "Contoso" ; OEM Label
BytesPerSector dw 512 ; There are 512b per sector
SectorsPerCluster db 1 ; Sectors per cluster
ReservedForBoot dw 1 ; # of sectors reserved for boot
NumberOfFats db 2 ; # of fats
RootDirEntries dw 224 ; # of root directory entries
LogicalSectors dw 2880 ; # of sectors
MediumByte db 0x0f0 ; Medium descriptor byte
SectorsPerFat dw 9 ; # of sectors per fat
SectorsPerTrack dw 18 ; # of sectors per track
Sides dw 2 ; # of sides
HiddenSectors dd 0 ; # of hidden sectors
LargeSectors dd 0 ; # of large sectors
DriveNo dw 0 ; The drive number
Signature db 41 ; The drive signature
VolumeID dd 0xdeadbeef ; The volume id
VolumeLabel db "Windows9 "; This can be any 11 characters
FileSystem db "FAT12 " ; File system of the floppy DONT CHANGE
If for any reason the code doesn't work check for any errors and make sure your motherboard has an on board speaker.
For more info go here as said above.
Base of the source code here.
For some tips on assembly here, this is a very well documented open source OS to help beginners learn assembly.
Hope this helps!
EDIT: Some Typos and help from Peter Cordes (In the comments)