outp( Port_Address, value);It's a little more, though in a way simpler, when expressed in assembler:
procedure OutPort(Address,value) mov dx,Address mov ax,value out dx,ax ; address bus / data bus end;Now of course it really isn't THAT simple, because that would just make it START shrieking, and in fact I'd have to control the duration of the sound by a bit more code, such as this bit I ran across
void BeepSound(unsigned short pitch, int duration) { asm mov bx, pitch asm mov ax, 34DDh asm mov dx, 0012h asm cmp dx, bx asm jnb stop asm div bx asm mov bx, ax asm in al, 61h asm test al, 3 asm jne j1 asm or al, 3 asm out 61h, al asm mov al, 0B6h asm out 43h, al j1: asm mov al, bl asm out 42h, al asm mov al, bh asm out 42h, al stop: ; Sleep(duration); asm in al,61H asm and al, 0fcH asm out 61H, al }It's not really that complicated, but my glitch is that I wanted to use one method for both Win9x and 2K/XP.
* Play Morse code in Visual Foxpro DECLARE INTEGER Beep IN kernel32 INTEGER dwFreq, INTEGER dwDuration DECLARE Sleep IN kernel32 LONG dwMilliseconds LOCAL nKeyCode, cWindowTitle cWindowTitle = _SCREEN.CAPTION _SCREEN.CAPTION = "Press a key. ESC to exit." PRIVATE cSequences, nDinker && hide non-local vars * The following 'Dinker' value was 100 (100mS dot duration) but it became * necessary to lower it to adjust for language delay and processor speed. * Morse code should flow fast enough to hear the entire sequence of sounds * as a complete character instead of individual dits and dahs. Some people * can read code so fast they recognize entire words and not individual * characters! nDinker = 43 cSequences = ; [~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~]+; [~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~]+; [~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~]+; [~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~221122]+; [~~~~~~121212~~~~~~22222~12222~11222~11122~11112~11111~21111~22111~]+; [22211~22221~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~112211~~~~~~12~~~~2111~~]+; [2121~~211~~~1~~~~~1121~~221~~~1111~~11~~~~1222~~212~~~1211~~22~~~~]+; [21~~~~222~~~1221~~2212~~121~~~111~~~2~~~~~112~~~1112~~122~~~2112~~]+; [2122~~2211~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~]+; [~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~]+; [~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~]+; [~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~] nKeyCode =0 && variable to hold ASCII code of key pressed DO WHILE perf( @nKeyCode ) playcode( nKeyCode ) ?? CHR(nKeyCode) ENDDO CLEAR _SCREEN.CAPTION = cWindowTitle RETURN FUNCTION perf && accept a character. return .T. if not ESC LPARAMETERS berdie berdie = INKEY(0) RETURN berdie # 27 ENDFUNC FUNCTION playcode LPARAMETERS nkeycode LOCAL charsequence, nLoopCtr nkeycode = ASC(UPPER(CHR(nkeycode))) * The "non-data" portions of the data string were originally spaces, but * I made them squiggle characters for ease of handling and viewing so now * I have to accomodate that when extracting individual character sequences charsequence = ALLT(STRTRAN(SUBSTR(cSequences,((nkeycode-1)*6)+1,6),"~","")) FOR nLoopCtr = 1 TO LEN(charsequence) Beep(800, nDinker*VAL(SUBSTR(charsequence,nLoopCtr,1))) Sleep(nDinker) ENDFOR ENDFUNC PROCEDURE loaddata * This is the routine used to originally load the 'cSequences' variable * When you type a key, the program asks for the Morse sequence, i.e. * 1=dit 3=dah, C=1313. By definition, ratio between dit and dah is 1:3, but * personal preference and ability, as well as signal quality, may determine * variations of dah duration betwen 2 and 4. Space between one sound and next = 1 dit. cSequences=REPLICATE(CHR(126),635) nKeyCode =0 DO WHILE perf( @nKeyCode ) && var by reference so fnctn can modify original zack = ASC(UPPER( CHR(nKeyCode) )) @10,10 SAY SPACE(20) @10,10 SAY CHR(zack)+"?" ACCEPT "? " TO blooper && I didnt want complexity so I did this the ancient way cSequences = STUFF(cSequences, ((zack-1)*6)+1,6,PADR(ALLT(blooper),6,CHR(126))) ENDDO ENDPROC