Fresh IDE . Artifact [2b14feeaba]
Not logged in

This repository is a mirror!

The original is located on: https://fresh.flatassembler.net/fossil/repo/fresh
If you want to follow the project, please update your remote-url

Artifact 2b14feeaba46193724fc38d7e4ca03a29dcfc3e5:


     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
   100
   101
   102
   103
   104
   105
   106
   107
   108
   109
   110
   111
   112
   113
   114
   115
   116
   117
   118
   119
   120
   121
   122
   123
   124
   125
   126
   127
   128
   129
   130
   131
   132
   133
   134
   135
   136
   137
   138
   139
   140
   141
   142
   143
   144
   145
   146
   147
   148
   149
   150
   151
   152
   153
   154
   155
   156
   157
   158
   159
   160
   161
   162
   163
   164
   165
   166
   167
   168
   169
   170
   171
   172
   173
   174
   175
   176
   177
   178
   179
   180
   181
   182
   183
   184
   185
   186
   187
   188
   189
   190
   191
   192
   193
   194
   195
   196
   197
   198
   199
   200
   201
   202
   203
   204
   205
   206
   207
   208
   209
   210
   211
   212
   213
   214
   215
   216
   217
   218
   219
   220
   221
   222
   223
   224
   225
   226
   227
   228
   229
   230
   231
__sys_time_slice = 10 ;[ms]


uglobal
  if used TimerCreate
    __InternalTimerID     dd ?
    __InternalTimerThread dd ?
  end if
endg



if used TimerCreate

initialize InitLinuxTimers
  .action lnx_sigaction
  .timer lnx_sigevent
  .time  lnx_itimerspec
begin
; set the signal handler.
        mov     eax, sys_sigaction
        mov     ebx, SIGALRM

        lea     ecx, [.action]
        mov     [ecx+lnx_sigaction.sa_handler], __TimerProc
        mov     [ecx+lnx_sigaction.sa_mask], 0
        mov     [ecx+lnx_sigaction.sa_flags], 0
        xor     edx, edx

        int $80

; create the interval timer
        mov     eax, sys_timer_create
        mov     ebx, CLOCK_REALTIME

        lea     ecx, [.timer]
        mov     [ecx+lnx_sigevent.notify], SIGEV_SIGNAL
        mov     [ecx+lnx_sigevent.signo], SIGALRM
        mov     [ecx+lnx_sigevent.value], 0             ; not used but must be set - the function fails without it...
        mov     edx, __InternalTimerID

        int $80
;        stdcall OutputRegister, regEAX, 16
; then start a thread that will process timer expiration events.

        stdcall ThreadCreate, __TimerHandler, 0
        mov     [__InternalTimerThread], eax

; start the timer
        mov     ebx, [__InternalTimerID]
        mov     eax, sys_timer_settime
        lea     edx, [.time]
        mov     [edx+lnx_itimerspec.it_interval.tv_sec], 0
        mov     [edx+lnx_itimerspec.it_interval.tv_nsec], __sys_time_slice*1000000
        mov     [edx+lnx_itimerspec.it_value.tv_sec], 0
        mov     [edx+lnx_itimerspec.it_value.tv_nsec], __sys_time_slice*1000000
        xor     esi, esi

        int $80
;        stdcall OutputRegister, regEAX, 16
        return
endp



finalize FreeLinuxTimers
begin
; stop the timer
        mov     eax, sys_timer_delete
        mov     ebx, [__InternalTimerID]
        int $80

; then stop the handling thread
        mov     eax, sys_kill
        mov     ebx, [__InternalTimerThread]
        mov     ecx, SIGTERM
        int $80

        return
endp

end if


; This procedure is called by the system on every time quantum.
;

proc __TimerProc, .signal
begin
        push    ebx esi edi

        mov     eax, sys_signal


        lea     eax, [__ptrFirstTimer]
        xor     edi, edi

.loop:
        mov     eax, [eax+TTimer.next]
        test    eax, eax
        jz      .end_timers

        test    [eax+TTimer.flags], tmfRunning
        jz      .loop

        mov     ecx, [eax+TTimer.value]
        add     ecx, __sys_time_slice
        mov     [eax+TTimer.value], ecx
        cmp     ecx, [eax+TTimer.interval]
        jl     .loop

; call event handler
        cmp     [eax+TTimer.Callback], 0
        je      .handlerok

        push    eax

        mov     ecx, [eax+TTimer.flags]
        and     ecx, $0f
        cmp     eax, tmfDoNothing
        je      .end_event

; run the timer event in separate thread:
        inc     [eax+TTimer.Expired]
        inc     edi

.end_event:
        pop     eax
        test    [eax+TTimer.flags], tmfSyncDestroy
        jz      .handlerok

        stdcall TimerDestroy, eax

.handlerok:
; jump to loop
        mov     ecx, [eax+TTimer.interval]
        sub     [eax+TTimer.value], ecx
        jmp     .loop

.end_timers:

        test    edi, edi
        jz      @f

        mov     eax, sys_kill
        mov     ebx, [__InternalTimerThread]
        mov     ecx, SIGCONT
        int $80

@@:
        pop     edi esi ebx
        xor     eax, eax
        cret
endp




proc __TimerHandler, .dummy
.remain dd ?
.action lnx_sigaction
begin

        mov     eax, sys_sigaction
        mov     ebx, SIGCONT
        lea     ecx, [.action]
        mov     [ecx+lnx_sigaction.sa_handler], __dummy_proc
        mov     [ecx+lnx_sigaction.sa_mask], 0
        mov     [ecx+lnx_sigaction.sa_flags], SA_NODEFER
        xor     edx, edx
        int $80

.from_begin:

        mov     [.remain], 0
        lea     eax, [__ptrFirstTimer]

.listloop:
        mov     eax, [eax+TTimer.next]

.listloop2:
        test    eax, eax
        jz      .end_list

        mov     ecx, [eax+TTimer.Expired]
        jecxz   .listloop

        dec     ecx
        mov     [eax+TTimer.Expired], ecx
        add     [.remain], ecx

        cmp     [eax+TTimer.Callback], 0
        je      .listloop

        mov     ecx, [eax+TTimer.flags]
        and     ecx, $0f
        cmp     ecx, tmfDoNothing
        je      .end_event

        cmp     ecx, tmfFireEvent
        je      .end_event            ;.fire_event ; still not supported

; call the callback procedure.
        pushad
        stdcall [eax+TTimer.Callback], eax
        popad

.end_event:
        test    [eax+TTimer.flags], tmfSyncDestroy
        jz      .listloop

        push    eax
        mov     eax, [eax+TTimer.next]  ; after the destruction, this pointer will be lost.
        stdcall TimerDestroy ; pointer from the stack.
        jmp     .listloop2


.end_list:
        cmp     [.remain], 0
        jne     .from_begin

        mov     eax, sys_pause
        int $80

        jmp     .from_begin
endp

proc __dummy_proc, .dummy
begin
        cret
endp