/*Asm labels can only be defined once
in a task.  <F5> will spawn a new task
each time, so you don't get redefine
error, like when repeatedly #including
it from the cmd line.
*/

asm {
//Opcodes are slightly different to make writing the x86_64 assembler easier.
//See ::/Compiler/OpCodes.DD.

                IMPORT  Beep;

_BEEPS::
//You can always clobber RAX,RBX,RCX,RDX,R8,R9.  The compiler expects that.
//See REGG_CLOBBERED and REGG_STACK_TMP.
                PUSH        RBP
                MOV         RBP, RSP
                MOV         RCX, U64 SF_ARG1[RBP]   //SF_ARG1

@@05:           PUSH        RCX
//U0 Beep(I8 ona=62,Bool busy=FALSE)
                PUSH        FALSE   //Do not busy (spin) wait
                PUSH        62          //500 Hz
                CALL        Beep
                POP         RCX
                LOOP        @@05

                POP         RBP
                RET1        8           //Use special return. Pop one arg off of stack.

//ZealC return values are in RAX.   This function has no return value.
}

//_extern binds a asm symbol to a function.
//The convention is to put an underscore
//on C callable asm routines.
_extern _BEEPS U0 Beeps(I64 count);

I64 AsmAndC1()
{
    I64 noreg i;    //Normally this would be stored in a reg
//Check by unassembling with Uf("AsmAndC1").

    i = I64Get("Num of beeps 1-5 (%d):", 3, 1, 5);
    Beeps(i);

    asm {
//You can clobber RAX, RBX, RCX, RDX.   The compiler expects that.

        IMPORT      Sound; //Import an not use & or don't import and use &Sound.
        MOV         RCX, &i[RBP] //You can clobber RAX,RBX,RCX,RDX.
                                 //You better preserve the rest.
@@05:   PUSH        RCX

                                //U0 Sound(I8 ona);
        MOV         RAX, RCX //ona=loop*10+50
        IMUL2       RAX, 10 //ZealOS uses nonstandard opcodes
                            //to avoid multiple form of the same one.
                            //See ::/Compiler/OpCodes.DD.
        ADD         RAX, 40
        PUSH        RAX
        CALL        Sound

        MOV         RCX, counts.time_stamp_freq >> 3 //JIT Const.   Simple delay loop
@@10:   LOOP        @@10

        POP         RCX
        LOOP        @@05
    }
    Sound;

    return i;
}

"Beeps:%d\n", AsmAndC1;