Форум программистов, компьютерный форум, киберфорум
Assembler: DOS/Real Mode/16-bits
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.93/15: Рейтинг темы: голосов - 15, средняя оценка - 4.93
0 / 0 / 0
Регистрация: 01.06.2012
Сообщений: 8

Будильник на ассемблере исправить

01.06.2012, 12:29. Показов 3209. Ответов 14
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
есть код будильника,должна воспроизводится мелодия ,но этого не происходит,необходимо исправить!так же где идет ввод значения часов и минут переписать код покороче и попонятней и прокомментировать этот кусок кода!срочно!
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
01.06.2012, 12:29
Ответы с готовыми решениями:

Как исправить будильник? (см. внутри)
Уже неделю делаю будильник, а он гад никак не звенит. Я и условия менял... Никак. Помогите сделать!!! Может какие-то библиотеки надо...

Будильник
Создать приложение Будильник в назначенное время демонстрационная панель приобретает красный цвет и поддерживает его в течение нескольких...

Будильник
Создать приложение Будильник в назначенное время демонстрационная панель приобретает красный цвет и поддерживает его в течение нескольких...

14
33 / 33 / 3
Регистрация: 24.05.2012
Сообщений: 156
01.06.2012, 12:36
какой код?
1
0 / 0 / 0
Регистрация: 01.06.2012
Сообщений: 8
01.06.2012, 12:40  [ТС]
Assembler
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
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
CODE SEGMENT PARA PUBLIC 'CODE'
    ASSUME CS:CODE,DS:CODE,SS:CODE
    org 100h
MAIN proc far 
    jmp INIT
;-------------Раздел описания переменных------------
 
    NewLineCode db 13,10,'$'     ;переход на новую строку
    WelcomeMsg db 'Welcome to Alarm Program!!!',13,10,'$'  
    Msg1 db 'Enter Hours: $'
    Msg2 db 'Enter Minutes: $'
    Msg3 db 'Enter Seconds: $'
    MsgOkAlarm db 'Operation successful!..',13,10,'$'  ;Установился
    MsgFailedAlarm db 'Operation failed!..(((',13,10,'$';Не установился
    MsgInstalledAlarm db 'Alarm already installed!!!',13,10,'Reset alarm? Yes/No - Y/N ',13,10,'$'; Сообщение о том, что будильник установлен 
    ASCIITime db '00:00:00$' ;Шаблон времени
    Msg4 db 'Alarm was set at $' ;Будильник был установлен на(время)
    MsgRTC db 'Real time: $' ;Реальное время
    MsgQuestion db 'Do you want to set alarm? Yes/No - Y/N ',13,10,'$'
    
    AlarmTime db 6 dup(0) ;Массив в котором храниться время будильника 
    buf db 2 dup(0)       ;Для ввода значении времени 
    def_cur_position db ? ;Начальная позиция курсора
    
    SYS_KEY_HANDLER dd 0 ;Системный (стандартный) обработчик перерывания 4Аh(будильника)
    old_2Fh dd 0 
    
    music dw 9119,8609,8125,7671,7240,6834,6450,6088,5746,5424,5119,4832
    dw 4559,4304,4062,3835,3620,3416,3224,3043,2873,2711,2559,2415
    dw 2280,2152,2031,1918,1810,1708,1612,1522,1437,1356,1280,1208    ; массив частот мелодии
    
NextLine PROC NEAR
    mov ah, 9h
    mov dx, offset NewLineCode
    int 21h
    ret
NextLine ENDP
 
Sound PROC FAR          ;------------------------------Процедура воспроизведения заданной частоты---------------
    port_b equ 61h       ;Порт динамика 
    command_reg equ 43h  ;Командный регистр
    latch2 equ 42h       ;registr-chetchik port vv/viv 2
    in al,port_b         ;Получаем текущий статус
    or al,00000011b      ;разрешаем динамик и таймер
    out port_b,al        ;заменяем байт
    mov al,0b6h          ;установка для канала 2
    out command_reg,al  ;посылаем в командный регистр
 
    mov al,dl   ;готовим младший байт частоты
    out latch2,al   ;посылаем его
    mov al,dh   ;готовим старший байт частоты
    out latch2,al   ;посылаем его
    
    mov ah,0    ;номер функции чтения счетчика  
    int 1ah    ;пoлучaeм знaчeниe cчeтчикa
    mov cx,3     ;длительность нот
    ; mov bx,0000
    mov bx,dx   ;берем младшее слово счетчика
    add bx,cx   ;определяем момент окончания
    ;---пocтoяннaя пpoвepкa знaчeния cчeтчикa вpeмeни cутoк BIOS
delay_sound: int 1ah    ;берем значение счетчика
    cmp dx,bx   ;сравниваем с окончанием
    jne delay_sound   ;ecли нepaвeн, тo пoвтopяeм cнoвa
                         ;инaчe, зaдepжкa oкoнчeнa
    in al,port_b    ;получаем статус порта b
    and al,0fch     ;выключаем динамик
    out 61h,al 
    ret
Sound ENDP
;--------------------------------Процедура проигрывания мелодии-----------------------------------------
PlayMelody PROC FAR
    mov cx, 36   ;Счетчик цикла
    xor si, si
play:
    push cx
    mov dx, music[si]  ; звгружаем si частоту
    inc si
    inc si
    call Sound
    pop cx
    loop play
    RET
PlayMelody ENDP
;----------------------Процедура преобразования времени из BCD- формата в ASCII------------------------
DecodeBCD PROC FAR          
    mov ah,  al              ;Ввходной параметр al 
    and al,  15              ;Применяем маску 
    shr ah,  4
    add al,  '0'             ;Вторая цифра
    add ah,  '0'             ;Первая цифра 
    mov ASCIITime[bx],  ah
    mov ASCIITime[bx+1],  al
    ret
DecodeBCD ENDP
;---------------------Процедура преобразования ASCII- строки в число BCD- формата----------------
CodeASCIIToBCD PROC FAR
    ; sub ah, '0'
    ; sub al, '0'
    shl ah, 4
    and al, 15
    or al, ah
    ret
CodeASCIIToBCD ENDP
 
PrintRealTime PROC FAR   ;Процедура вывода времени 
    mov ah, 2h           ;Получить время из часов рельного времени(RTC)
    int 1Ah              ;Прерывание получения реального времени
    jc read_time_err     ;Переход при не удачном чтении времени
    xor ax, ax           
    mov al, ch           ;Ch-Часы    
    xor bx, bx
    call DecodeBCD       ; Запуск процедуры преобразования часов из BCD формата в формат ASCII- строки и одновременно записи в строку для вывода на экран
    mov al, cl
    add bx, 3            ;Сl-минуты
    call DecodeBCD
    mov al, dh           ;Dh-секунды
    add bx, 3
    call DecodeBCD
read_time_err:             ; 
    mov ah, 9h
    lea dx, MsgRTC ; Загрузка адреса сообщения о текущем времени
    int 21h
    lea dx, ASCIITime ; Загрузка адреса текущего времени в формате строки ASCII
    int 21h
    call NextLine
    ret
PrintRealTime ENDP
 
;-----------------Резидентная программа-----------------
MY_ALARM_HANDLER PROC FAR
    ;pushf ; Создание в стеке структуры для вызова IRET
    ; Сохранение модифицируемых регистров
    push es
    push si
    push di
    push ax
    push bx
    push cx
    push dx
    push ds
    push cs
    pop ds
    
    call PlayMelody
    
    mov AH,07h  ;Сброс будильника
    int 1Ah
    mov ax,0C801h   ; - освобождаем память
    int 2Fh
    
end_interupt:
    mov al, 20h    ;завершение прерывания будильника
    out 20h, al
    pop ds
    pop dx
    pop cx
    pop bx
    pop ax
    pop di
    pop si
    pop es
    iret
old_handler:
    ; Извлечение старых значений модифицируемых регистров
    pop ds
    pop dx
    pop cx
    pop bx
    pop ax
    pop di
    pop si
    pop es
    ; Переход к старому обработчику нажатия клавиши (старому обработчику прерывания 09h)
    jmp CS:SYS_KEY_HANDLER
MY_ALARM_HANDLER ENDP
;--------------2F вектор---------------------------------
new_2Fh proc
    cmp ah,0C8h ; - наша функция?
    jne out_2fh 
    cmp al,0    ; - анализируем номер подфункции в al
    je qq       ; - если программа уже в памяти
    cmp al,1    
    je uninst   ; - выгружаем программу
    ;jmp out_2fh
qq: 
    mov al,0FFh     ; - уже в памяти
    iret
out_2fh: jmp  cs:old_2Fh    
    iret
uninst:
    push ds     ; - сохраним используемые регистры
    push es
    push dx   
    mov ax,254Ah    ; - восстановим 4A вектор,вход - ds:dx
    lds dx,cs:SYS_KEY_HANDLER
    int 21h
    mov ax,252Fh    ; - восстановим мультиплексор
    lds dx,cs:old_2Fh
    int 21h
    
    mov es,cs:[2Ch] ; - освобождаем блок, выделенный под переменные окружения(psp)
    mov ah,49h
    int 21h
            ; - теперь освобождаем программный блок
    push cs  ;сохраняем сегмент кода
    pop es   ; 
    mov ah,49h
    int 21h
            ; - восстановим регистры
    pop dx
    pop es
    pop ds
    iret    ; - возврат в вызывающую программу
new_2Fh endp
 
MAIN endp
;----------------Программа инициализации--------------
INIT PROC NEAR
 
    mov ax,0C800h   ; - ah=C8 - id программы, al=00h - проверка на наличие в памяти
    int 2Fh
    cmp al,0FFh
    jne setup_alarm
    mov ah, 9h
    lea dx, MsgInstalledAlarm
    int 21h
    
    ;mov ax,0C801h  ; - освобождаем память
    ;int 2Fh
    
    ; mov ah,4Ch        ; - завершаем программу обычным образом, без оставления в памяти
    ; int 21h
    
read_loop_reset_msg:
    mov ah, 8h
    int 21h
    cmp al, 'y'
    je reset
    cmp al, 'Y'
    je reset
    cmp al, 'n'
    je no_reset
    cmp al, 'N'
    jne read_loop_reset_msg
no_reset:
    mov ah, 4ch
    int 21h
reset:
    mov ax,0C801h ;
    int 2Fh
    mov AH,07h  ;Сброс будильника
    int 1Ah
setup_alarm:
    xor ax, ax
    xor dx, dx
    
    mov ah, 9h           ;Вывод сообщения приветствия
    lea dx, WelcomeMsg
    int 21h
    
    call PrintRealTime ; Процедура вывода текущего времени на экран
    
    mov ah, 9h
    lea dx, MsgQuestion
    int 21h
    
read_loop:
    mov ah, 8h
    int 21h
    cmp al, 'y'
    je yes
    cmp al, 'Y'
    je yes
    cmp al, 'n'
    je end_alarm
    cmp al, 'N'
    jne read_loop
end_alarm:
    mov ah, 4ch
    int 21h
yes:
    
;----------------------ВВОД ЗНАЧЕНИЯ ЧАСОВ-------------------------    
 
    mov  ah,03h ; Определяем текущее
    int  10h ; положение курсора
    mov def_cur_position, dl
    
    mov ah, 9h
    lea dx, Msg1
    int 21h
    
    mov  ah,03h ; Определяем текущее
    int  10h ; положение курсора
    mov def_cur_position, dl     ;Запоминаем в переменную
    
    
    xor si, si
enter_hours:
    mov ah, 8h
    int 21h
    ; cmp al, 13
    ; je end_of_enter_hours
    cmp al, 8           
    jne no_backspace1
    mov ah,3h ; определяем текущее
    int 10h ; положение курсора
    cmp dl, def_cur_position
    jbe no_backspace1   ;меньше либо равно
    mov ah,2h ; перемещаем его назад
    dec dl ; на одну позицию
    push dx ; Запоминаем положение курсора
    int 10h
    mov ah, 2h
    mov dl, ' '
    int 21h
    pop dx    ;положение курсора из стека
    int 10h
    cmp si, 2
    jne check_si_one_h
    mov ah, buf[0]
    mov buf[1], ah
    mov buf[0], 0
    dec si ; Уменьшаем счётчик введённых цифр(разрядов)
    jmp enter_hours
check_si_one_h:
    cmp si, 1
    jb enter_hours
    mov buf[1], 0
    dec si
no_backspace1:
    cmp al, 13
    je end_of_enter_hours
    cmp al, '0'
    jb enter_hours     ;меньше 0
    cmp al, '9'       
    ja enter_hours     ;больше 9
    cmp si, 1
    ja enter_hours
    cmp si, 0
    ja low_h
    mov buf[si+1], al    ;положили в единицы часов
    sub buf[si+1], '0'
    mov dl, al
    mov ah, 2h
    int 21h
    jmp end_h
low_h:
    mov ah, byte ptr buf[si]
    cmp ah, 1
    jbe normal_h  ;меньше либо равно
    cmp ah, 2
    ja enter_hours
    cmp al, '3'
    ja enter_hours
normal_h:
    mov byte ptr buf[si-1], ah       ;был мл. стал старший
    mov buf[si], al                ;кладем младший разряд
    sub buf[si], '0'
    mov dl, al
    mov ah, 2h
    int 21h
end_h:
    inc si
    jmp enter_hours
end_of_enter_hours:
    cmp si, 0              ;считает количество введенных символов
    jnz h_result_ok        ;если не равно 0
    mov ah, 2h
    mov dl, '0'
    int 21h
    int 21h
h_result_ok:
    push word ptr buf[0]  ;часы в стек
    pop word ptr AlarmTime[0]
    
    call NextLine
    
;----------------------ВВОД ЗНАЧЕНИЯ МИНУТ-------------------------    
    xor dx, dx
    mov ah, 9h
    lea dx, Msg2
    int 21h
    
    mov  ah,03h ; Определяем текущее
    int  10h ; положение курсора
    mov def_cur_position, dl
    
    mov word ptr buf, 0
    xor si, si
enter_minutes:
    mov ah, 8h
    int 21h
    cmp al, 8
    jne no_backspace_m
    mov  ah,3h ; определяем текущее
    int  10h ; положение курсора
    cmp dl, def_cur_position
    jbe no_backspace_m
    mov  ah,2h ; перемещаем его назад
    dec  dl ; на одну позицию
    push dx
    int  10h
    ; mov ah, 2h
    mov dl, ' '
    int 21h
    pop dx
    int 10h
    cmp si, 2
    jne check_si_one_m
    mov ah, buf[0]
    mov buf[1], ah
    mov buf[0], 0
    dec si
    jmp enter_minutes
check_si_one_m:
    cmp si, 1
    jb enter_minutes
    mov buf[1], 0
    dec si
no_backspace_m:
    cmp al, 13
    je end_of_enter_minutes
    cmp al, '0'
    jb enter_minutes
    cmp al, '9'
    ja enter_minutes
    cmp si, 1
    ja enter_minutes
    cmp si, 0
    ja low_m
    mov buf[si+1], al
    sub buf[si+1], '0'
    mov dl, al
    mov ah, 2h
    int 21h
    jmp end_m
low_m:
    mov ah, byte ptr buf[si]
    cmp ah, 5
    ja enter_minutes
    mov byte ptr buf[si-1], ah
    mov buf[si], al
    sub buf[si], '0'
    mov dl, al
    mov ah, 2h
    int 21h
end_m:
    inc si
    jmp enter_minutes
end_of_enter_minutes:
    cmp si, 0
    jnz m_result_ok
    mov ah, 2h
    mov dl, '0'
    int 21h
    int 21h
m_result_ok:
    push word ptr buf[0] ; кидаем слово с 0 
    pop word ptr AlarmTime[2]    
    
    call NextLine
    
    mov al, AlarmTime[1]    ;
    mov ah, AlarmTime[0]
    call CodeASCIIToBCD
    mov ch, al           ;часы уже bcd
    mov al, AlarmTime[3]
    mov ah, AlarmTime[2]
    call CodeASCIIToBCD
    mov cl, al         ;минуты  bcd
    xor ax, ax
    mov ah, 06h ;Установим будильник на это время
    mov dh, 00h ;секунды
    int 1Ah
    jnc all_ok ;cf =0
    mov ah, 9h
    lea dx, MsgFailedAlarm
    int 21h
    RET
all_ok:   ;0
    xor dx, dx
    mov ah, 9h
    lea dx, MsgOkAlarm
    int 21h
    mov ah, 9h
    lea dx, Msg4
    int 21h
    
    push word ptr AlarmTime[0]   ;В стек два байта часов
    pop word ptr ASCIITime[0]    
    push word ptr AlarmTime[2]   
    pop word ptr ASCIITime[3]
    push word ptr AlarmTime[4]
    pop word ptr ASCIITime[6]
    
    add ASCIITime[0], '0'
    add ASCIITime[1], '0'
    add ASCIITime[3], '0'
    add ASCIITime[4], '0'
    add ASCIITime[6], '0'
    add ASCIITime[7], '0'
    
    mov ah, 9h
    lea dx, ASCIITime ;выводим шаблон который заполнили
    int 21h
    
    mov ax,354Ah                 ;сохраняем
    int 21h
    mov word ptr SYS_KEY_HANDLER, bx      ;Адрес старого обработчика
    mov word ptr SYS_KEY_HANDLER+2, es    ;Сегмент старого обработчика
    
    mov ax, 254Ah                 ;подменяем
    lea dx, MY_ALARM_HANDLER  ;адрес нач. команды нового обработчика
    int 21h
    
    
    mov ax,352Fh    ; - чтение и сохранение 2Fh вектора
    int 21h
    mov word ptr cs:old_2Fh,bx  
    mov word ptr cs:old_2Fh+2,es
    mov ax,252Fh    ; - записываем новый вектор
    mov dx,offset new_2Fh 
    int 21h
    
    mov ax, 3100h   ;оставить резидент в памяти
    mov dx, (INIT-MAIN+10Fh)/16
    int 21h
    
INIT ENDP
CODE ENDS
    END MAIN
0
33 / 33 / 3
Регистрация: 24.05.2012
Сообщений: 156
01.06.2012, 12:45
добавь код в теги asm для лучшего просмотра
0
0 / 0 / 0
Регистрация: 01.06.2012
Сообщений: 8
01.06.2012, 12:47  [ТС]
как это сделать?
0
33 / 33 / 3
Регистрация: 24.05.2012
Сообщений: 156
01.06.2012, 12:49
добавляешь в теги ASM и /ASM, есть кнопка в редакторе сообщений
0
0 / 0 / 0
Регистрация: 01.06.2012
Сообщений: 8
01.06.2012, 12:49  [ТС]
Assembler
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
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
CODE SEGMENT PARA PUBLIC 'CODE'
    ASSUME CS:CODE,DS:CODE,SS:CODE
    org 100h
MAIN proc far 
    jmp INIT
;-------------Раздел описания переменных------------
 
    NewLineCode db 13,10,'$'     ;переход на новую строку
    WelcomeMsg db 'Welcome to Alarm Program!!!',13,10,'$'  
    Msg1 db 'Enter Hours: $'
    Msg2 db 'Enter Minutes: $'
    Msg3 db 'Enter Seconds: $'
    MsgOkAlarm db 'Operation successful!..',13,10,'$'  ;Установился
    MsgFailedAlarm db 'Operation failed!..(((',13,10,'$';Не установился
    MsgInstalledAlarm db 'Alarm already installed!!!',13,10,'Reset alarm? Yes/No - Y/N ',13,10,'$'; Сообщение о том, что будильник установлен 
    ASCIITime db '00:00:00$' ;Шаблон времени
    Msg4 db 'Alarm was set at $' ;Будильник был установлен на(время)
    MsgRTC db 'Real time: $' ;Реальное время
    MsgQuestion db 'Do you want to set alarm? Yes/No - Y/N ',13,10,'$'
    
    AlarmTime db 6 dup(0) ;Массив в котором храниться время будильника 
    buf db 2 dup(0)       ;Для ввода значении времени 
    def_cur_position db ? ;Начальная позиция курсора
    
    SYS_KEY_HANDLER dd 0 ;Системный (стандартный) обработчик перерывания 4Аh(будильника)
    old_2Fh    dd 0 
    
    music dw 9119,8609,8125,7671,7240,6834,6450,6088,5746,5424,5119,4832
    dw 4559,4304,4062,3835,3620,3416,3224,3043,2873,2711,2559,2415
    dw 2280,2152,2031,1918,1810,1708,1612,1522,1437,1356,1280,1208    ; массив частот мелодии
    
NextLine PROC NEAR
    mov ah,    9h
    mov dx, offset NewLineCode
    int 21h
    ret
NextLine ENDP
 
Sound PROC FAR          ;------------------------------Процедура воспроизведения заданной частоты---------------
    port_b equ 61h         ;Порт динамика 
    command_reg equ 43h     ;Командный регистр
    latch2 equ 42h         ;registr-chetchik port vv/viv 2
    in al,port_b          ;Получаем текущий статус
    or al,00000011b      ;разрешаем динамик и таймер
    out port_b,al          ;заменяем байт
    mov al,0b6h          ;установка для канала 2
    out command_reg,al     ;посылаем в командный регистр
 
    mov al,dl     ;готовим младший байт частоты
    out latch2,al     ;посылаем его
    mov al,dh     ;готовим старший байт частоты
    out latch2,al     ;посылаем его
    
    mov ah,0     ;номер функции чтения счетчика  
    int 1ah    ;пoлучaeм знaчeниe cчeтчикa
    mov cx,3     ;длительность нот
    ; mov bx,0000
    mov bx,dx     ;берем младшее слово счетчика
    add bx,cx     ;определяем момент окончания
    ;---пocтoяннaя пpoвepкa знaчeния cчeтчикa вpeмeни cутoк BIOS
delay_sound: int 1ah     ;берем значение счетчика
    cmp dx,bx     ;сравниваем с окончанием
    jne delay_sound   ;ecли нepaвeн, тo пoвтopяeм cнoвa
                         ;инaчe, зaдepжкa oкoнчeнa
    in al,port_b     ;получаем статус порта b
    and al,0fch     ;выключаем динамик
    out 61h,al 
    ret
Sound ENDP
;--------------------------------Процедура проигрывания мелодии-----------------------------------------
PlayMelody PROC FAR
    mov cx, 36   ;Счетчик цикла
    xor si, si
play:
    push cx
    mov dx, music[si]  ; звгружаем si частоту
    inc si
    inc si
    call Sound
    pop cx
    loop play
    RET
PlayMelody ENDP
;----------------------Процедура преобразования времени из BCD- формата в ASCII------------------------
DecodeBCD PROC FAR          
    mov ah,  al              ;Ввходной параметр al 
    and al,  15              ;Применяем маску 
    shr ah,  4
    add al,  '0'             ;Вторая цифра
    add ah,  '0'             ;Первая цифра 
    mov ASCIITime[bx],  ah
    mov ASCIITime[bx+1],  al
    ret
DecodeBCD ENDP
;---------------------Процедура преобразования ASCII- строки в число BCD- формата----------------
CodeASCIIToBCD PROC FAR
    ; sub ah, '0'
    ; sub al, '0'
    shl ah, 4
    and al, 15
    or al, ah
    ret
CodeASCIIToBCD ENDP
 
PrintRealTime PROC FAR   ;Процедура вывода времени 
    mov ah, 2h           ;Получить время из часов рельного времени(RTC)
    int 1Ah              ;Прерывание получения реального времени
    jc read_time_err     ;Переход при не удачном чтении времени
    xor ax, ax           
    mov al, ch           ;Ch-Часы    
    xor bx, bx
    call DecodeBCD       ; Запуск процедуры преобразования часов из BCD формата в формат ASCII- строки и одновременно записи в строку для вывода на экран
    mov al, cl
    add bx, 3            ;Сl-минуты
    call DecodeBCD
    mov al, dh           ;Dh-секунды
    add bx, 3
    call DecodeBCD
read_time_err:             ; 
    mov ah, 9h
    lea dx, MsgRTC ; Загрузка адреса сообщения о текущем времени
    int 21h
    lea dx, ASCIITime ; Загрузка адреса текущего времени в формате строки ASCII
    int 21h
    call NextLine
    ret
PrintRealTime ENDP
 
;-----------------Резидентная программа-----------------
MY_ALARM_HANDLER PROC FAR
    ;pushf ; Создание в стеке структуры для вызова IRET
    ; Сохранение модифицируемых регистров
    push es
    push si
    push di
    push ax
    push bx
    push cx
    push dx
    push ds
    push cs
    pop ds
    
    call PlayMelody
    
    mov AH,07h    ;Сброс будильника
    int 1Ah
    mov ax,0C801h    ; - освобождаем память
    int 2Fh
    
end_interupt:
    mov al, 20h    ;завершение прерывания будильника
    out 20h, al
    pop ds
    pop dx
    pop cx
    pop bx
    pop ax
    pop di
    pop si
    pop es
    iret
old_handler:
    ; Извлечение старых значений модифицируемых регистров
    pop ds
    pop dx
    pop cx
    pop bx
    pop ax
    pop di
    pop si
    pop es
    ; Переход к старому обработчику нажатия клавиши (старому обработчику прерывания 09h)
    jmp CS:SYS_KEY_HANDLER
MY_ALARM_HANDLER ENDP
;--------------2F вектор---------------------------------
new_2Fh    proc
    cmp ah,0C8h    ; - наша функция?
    jne out_2fh    
    cmp al,0    ; - анализируем номер подфункции в al
    je qq        ; - если программа уже в памяти
    cmp al,1    
    je uninst    ; - выгружаем программу
    ;jmp out_2fh
qq:    
    mov al,0FFh        ; - уже в памяти
    iret
out_2fh: jmp  cs:old_2Fh    
    iret
uninst:
    push ds         ; - сохраним используемые регистры
    push es
    push dx   
    mov ax,254Ah    ; - восстановим 4A вектор,вход - ds:dx
    lds dx,cs:SYS_KEY_HANDLER
    int 21h
    mov ax,252Fh    ; - восстановим мультиплексор
    lds    dx,cs:old_2Fh
    int 21h
    
    mov es,cs:[2Ch]    ; - освобождаем блок, выделенный под переменные окружения(psp)
    mov ah,49h
    int 21h
            ; - теперь освобождаем программный блок
    push cs  ;сохраняем сегмент кода
    pop es   ; 
    mov ah,49h
    int 21h
            ; - восстановим регистры
    pop dx
    pop es
    pop ds
    iret    ; - возврат в вызывающую программу
new_2Fh    endp
 
MAIN endp
;----------------Программа инициализации--------------
INIT PROC NEAR
 
    mov ax,0C800h    ; - ah=C8 - id программы, al=00h - проверка на наличие в памяти
    int 2Fh
    cmp al,0FFh
    jne setup_alarm
    mov ah, 9h
    lea dx, MsgInstalledAlarm
    int 21h
    
    ;mov ax,0C801h    ; - освобождаем память
    ;int 2Fh
    
    ; mov ah,4Ch        ; - завершаем программу обычным образом, без оставления в памяти
    ; int 21h
    
read_loop_reset_msg:
    mov ah, 8h
    int 21h
    cmp al, 'y'
    je reset
    cmp al, 'Y'
    je reset
    cmp al, 'n'
    je no_reset
    cmp al, 'N'
    jne read_loop_reset_msg
no_reset:
    mov ah, 4ch
    int 21h
reset:
    mov ax,0C801h ;
    int 2Fh
    mov AH,07h    ;Сброс будильника
    int 1Ah
setup_alarm:
    xor ax, ax
    xor dx, dx
    
    mov ah, 9h           ;Вывод сообщения приветствия
    lea dx, WelcomeMsg
    int 21h
    
    call PrintRealTime ; Процедура вывода текущего времени на экран
    
    mov ah, 9h
    lea dx, MsgQuestion
    int 21h
    
read_loop:
    mov ah, 8h
    int 21h
    cmp al, 'y'
    je yes
    cmp al, 'Y'
    je yes
    cmp al, 'n'
    je end_alarm
    cmp al, 'N'
    jne read_loop
end_alarm:
    mov ah, 4ch
    int 21h
yes:
    
;----------------------ВВОД ЗНАЧЕНИЯ ЧАСОВ-------------------------    
 
    mov  ah,03h ; Определяем текущее
    int  10h ; положение курсора
    mov def_cur_position, dl
    
    mov ah, 9h
    lea dx, Msg1
    int 21h
    
    mov  ah,03h ; Определяем текущее
    int  10h ; положение курсора
    mov def_cur_position, dl     ;Запоминаем в переменную
    
    
    xor si, si
enter_hours:
    mov ah, 8h
    int 21h
    ; cmp al, 13
    ; je end_of_enter_hours
    cmp al, 8           
    jne no_backspace1
    mov ah,3h ; определяем текущее
    int 10h ; положение курсора
    cmp dl, def_cur_position
    jbe no_backspace1   ;меньше либо равно
    mov ah,2h ; перемещаем его назад
    dec dl ; на одну позицию
    push dx ; Запоминаем положение курсора
    int 10h
    mov ah, 2h
    mov dl, ' '
    int 21h
    pop dx    ;положение курсора из стека
    int 10h
    cmp si, 2
    jne check_si_one_h
    mov ah, buf[0]
    mov buf[1], ah
    mov buf[0], 0
    dec si ; Уменьшаем счётчик введённых цифр(разрядов)
    jmp enter_hours
check_si_one_h:
    cmp si, 1
    jb enter_hours
    mov buf[1], 0
    dec si
no_backspace1:
    cmp al, 13
    je end_of_enter_hours
    cmp al, '0'
    jb enter_hours     ;меньше 0
    cmp al, '9'       
    ja enter_hours     ;больше 9
    cmp si, 1
    ja enter_hours
    cmp si, 0
    ja low_h
    mov buf[si+1], al    ;положили в единицы часов
    sub buf[si+1], '0'
    mov dl, al
    mov ah, 2h
    int 21h
    jmp end_h
low_h:
    mov ah, byte ptr buf[si]
    cmp ah, 1
    jbe normal_h  ;меньше либо равно
    cmp ah, 2
    ja enter_hours
    cmp al, '3'
    ja enter_hours
normal_h:
    mov byte ptr buf[si-1], ah       ;был мл. стал старший
    mov buf[si], al                ;кладем младший разряд
    sub buf[si], '0'
    mov dl, al
    mov ah, 2h
    int 21h
end_h:
    inc si
    jmp enter_hours
end_of_enter_hours:
    cmp si, 0              ;считает количество введенных символов
    jnz h_result_ok        ;если не равно 0
    mov ah, 2h
    mov dl, '0'
    int 21h
    int 21h
h_result_ok:
    push word ptr buf[0]  ;часы в стек
    pop word ptr AlarmTime[0]
    
    call NextLine
    
;----------------------ВВОД ЗНАЧЕНИЯ МИНУТ-------------------------    
    xor dx, dx
    mov ah, 9h
    lea dx, Msg2
    int 21h
    
    mov  ah,03h ; Определяем текущее
    int  10h ; положение курсора
    mov def_cur_position, dl
    
    mov word ptr buf, 0
    xor si, si
enter_minutes:
    mov ah, 8h
    int 21h
    cmp al, 8
    jne no_backspace_m
    mov  ah,3h ; определяем текущее
    int  10h ; положение курсора
    cmp dl, def_cur_position
    jbe no_backspace_m
    mov  ah,2h ; перемещаем его назад
    dec  dl ; на одну позицию
    push dx
    int  10h
    ; mov ah, 2h
    mov dl, ' '
    int 21h
    pop dx
    int 10h
    cmp si, 2
    jne check_si_one_m
    mov ah, buf[0]
    mov buf[1], ah
    mov buf[0], 0
    dec si
    jmp enter_minutes
check_si_one_m:
    cmp si, 1
    jb enter_minutes
    mov buf[1], 0
    dec si
no_backspace_m:
    cmp al, 13
    je end_of_enter_minutes
    cmp al, '0'
    jb enter_minutes
    cmp al, '9'
    ja enter_minutes
    cmp si, 1
    ja enter_minutes
    cmp si, 0
    ja low_m
    mov buf[si+1], al
    sub buf[si+1], '0'
    mov dl, al
    mov ah, 2h
    int 21h
    jmp end_m
low_m:
    mov ah, byte ptr buf[si]
    cmp ah, 5
    ja enter_minutes
    mov byte ptr buf[si-1], ah
    mov buf[si], al
    sub buf[si], '0'
    mov dl, al
    mov ah, 2h
    int 21h
end_m:
    inc si
    jmp enter_minutes
end_of_enter_minutes:
    cmp si, 0
    jnz m_result_ok
    mov ah, 2h
    mov dl, '0'
    int 21h
    int 21h
m_result_ok:
    push word ptr buf[0] ; кидаем слово с 0 
    pop word ptr AlarmTime[2]    
    
    call NextLine
    
    mov al, AlarmTime[1]    ;
    mov ah, AlarmTime[0]
    call CodeASCIIToBCD
    mov ch, al           ;часы уже bcd
    mov al, AlarmTime[3]
    mov ah, AlarmTime[2]
    call CodeASCIIToBCD
    mov cl, al         ;минуты  bcd
    xor ax, ax
    mov ah, 06h    ;Установим будильник на это время
    mov dh, 00h ;секунды
    int 1Ah
    jnc all_ok ;cf =0
    mov ah, 9h
    lea dx, MsgFailedAlarm
    int 21h
    RET
all_ok:   ;0
    xor dx, dx
    mov ah, 9h
    lea dx, MsgOkAlarm
    int 21h
    mov ah, 9h
    lea dx, Msg4
    int 21h
    
    push word ptr AlarmTime[0]   ;В стек два байта часов
    pop word ptr ASCIITime[0]    
    push word ptr AlarmTime[2]   
    pop word ptr ASCIITime[3]
    push word ptr AlarmTime[4]
    pop word ptr ASCIITime[6]
    
    add ASCIITime[0], '0'
    add ASCIITime[1], '0'
    add ASCIITime[3], '0'
    add ASCIITime[4], '0'
    add ASCIITime[6], '0'
    add ASCIITime[7], '0'
    
    mov ah, 9h
    lea dx, ASCIITime ;выводим шаблон который заполнили
    int 21h
    
    mov ax,354Ah                 ;сохраняем
    int 21h
    mov word ptr SYS_KEY_HANDLER, bx      ;Адрес старого обработчика
    mov word ptr SYS_KEY_HANDLER+2, es    ;Сегмент старого обработчика
    
    mov ax, 254Ah                 ;подменяем
    lea dx, MY_ALARM_HANDLER  ;адрес нач. команды нового обработчика
    int 21h
    
    
    mov ax,352Fh    ; - чтение и сохранение 2Fh вектора
    int 21h
    mov word ptr cs:old_2Fh,bx    
    mov word ptr cs:old_2Fh+2,es
    mov ax,252Fh    ; - записываем новый вектор
    mov dx,offset new_2Fh 
    int 21h
    
    mov ax, 3100h   ;оставить резидент в памяти
    mov dx, (INIT-MAIN+10Fh)/16
    int 21h
    
INIT ENDP
CODE ENDS
    END MAIN
0
0 / 0 / 0
Регистрация: 01.06.2012
Сообщений: 8
01.06.2012, 13:10  [ТС]
можете помочь?
0
202 / 168 / 11
Регистрация: 30.05.2012
Сообщений: 703
01.06.2012, 13:17
Цитата Сообщение от SNasty Посмотреть сообщение
переписать код покороче и попонятней
Надо CMOS Timer юзать. 01,03,05 - сигнальные секуда, минута, час. А свой обработчик звонка ставишь на Int 4Ah - это прерывание вызывается, когда CMOS будильник работает.
0
0 / 0 / 0
Регистрация: 01.06.2012
Сообщений: 8
01.06.2012, 13:21  [ТС]
вы можете переделать так чтоб все работало?
0
202 / 168 / 11
Регистрация: 30.05.2012
Сообщений: 703
01.06.2012, 13:32
Слегка код исправил и прокомментировал:
Assembler
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
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
CODE SEGMENT PARA PUBLIC 'CODE';сегмент кода
    ASSUME CS:CODE,DS:CODE,SS:CODE;задаем сегменты
    org 100h;точка входа
MAIN proc far ;главная процедура
    jmp INIT;на инициализацию
;-------------Раздел описания переменных------------
 
    NewLineCode db 13,10,'$'     ;переход на новую строку
    WelcomeMsg db 'Welcome to Alarm Program!!!',13,10,'$'  ;
    Msg1 db 'Enter Hours: $'
    Msg2 db 'Enter Minutes: $'
    Msg3 db 'Enter Seconds: $'
    MsgOkAlarm db 'Operation successful!..',13,10,'$'  ;Установился
    MsgFailedAlarm db 'Operation failed!..(((',13,10,'$';Не установился
    MsgInstalledAlarm db 'Alarm already installed!!!',13,10,'Reset alarm? Yes/No - Y/N ',13,10,'$'; Сообщение о том, что будильник установлен 
    ASCIITime db '00:00:00$' ;Шаблон времени
    Msg4 db 'Alarm was set at $' ;Будильник был установлен на(время)
    MsgRTC db 'Real time: $' ;Реальное время
    MsgQuestion db 'Do you want to set alarm? Yes/No - Y/N ',13,10,'$';строки запроса
    
    AlarmTime db 6 dup(0) ;Массив в котором храниться время будильника 
    buf db 2 dup(0)       ;Для ввода значении времени 
    def_cur_position db ? ;Начальная позиция курсора
    
    SYS_KEY_HANDLER dd 0 ;Системный (стандартный) обработчик перерывания 4Аh(будильника)
    old_2Fh    dd 0 ;место для старого обработчика
    
    music dw 9119,8609,8125,7671,7240,6834,6450,6088,5746,5424,5119,4832
    dw 4559,4304,4062,3835,3620,3416,3224,3043,2873,2711,2559,2415
    dw 2280,2152,2031,1918,1810,1708,1612,1522,1437,1356,1280,1208    ; массив частот мелодии
    
NextLine PROC NEAR
    mov ah,    9h
    mov dx, offset NewLineCode
    int 21h
    ret
NextLine ENDP;процедура перевода строки
 
Sound PROC FAR          ;------------------------------Процедура воспроизведения заданной частоты---------------
jmp qwerty
    port_b equ 61h         ;Порт динамика 
    command_reg equ 43h     ;Командный регистр
    latch2 equ 42h         ;registr-chetchik port vv/viv 2
qwerty:
    in al,port_b          ;Получаем текущий статус
    or al,00000011b      ;разрешаем динамик и таймер
    out port_b,al          ;заменяем байт
    mov al,0b6h          ;установка для канала 2
    out command_reg,al     ;посылаем в командный регистр
 
    mov al,dl     ;готовим младший байт частоты
    out latch2,al     ;посылаем его
    mov al,dh     ;готовим старший байт частоты
    out latch2,al     ;посылаем его
    
    mov ah,0     ;номер функции чтения счетчика  
    int 1ah    ;пoлучaeм знaчeниe cчeтчикa
    mov cx,3     ;длительность нот
    ; mov bx,0000
    mov bx,dx     ;берем младшее слово счетчика
    add bx,cx     ;определяем момент окончания
    ;---пocтoяннaя пpoвepкa знaчeния cчeтчикa вpeмeни cутoк BIOS
delay_sound: int 1ah     ;берем значение счетчика
    cmp dx,bx     ;сравниваем с окончанием
    jne delay_sound   ;ecли нepaвeн, тo пoвтopяeм cнoвa
                         ;инaчe, зaдepжкa oкoнчeнa
    in al,port_b     ;получаем статус порта b
    and al,0fch     ;выключаем динамик
    out 61h,al 
    ret
Sound ENDP
;--------------------------------Процедура проигрывания мелодии-----------------------------------------
PlayMelody PROC FAR
    mov cx, 36   ;Счетчик цикла
    xor si, si
play:
    push cx
    mov dx, music[si]  ; звгружаем si частоту
    inc si
    inc si
    call Sound
    pop cx
    loop play
    RET
PlayMelody ENDP
;----------------------Процедура преобразования времени из BCD- формата в ASCII------------------------
DecodeBCD PROC FAR          
    mov ah,  al              ;Ввходной параметр al 
    and al,  15              ;Применяем маску 
    shr ah,  4
    add al,  '0'             ;Вторая цифра
    add ah,  '0'             ;Первая цифра 
    mov ASCIITime[bx],  ah
    mov ASCIITime[bx+1],  al
    ret
DecodeBCD ENDP
;---------------------Процедура преобразования ASCII- строки в число BCD- формата----------------
CodeASCIIToBCD PROC FAR
    ; sub ah, '0'
    ; sub al, '0'
    shl ah, 4
    and al, 15
    or al, ah
    ret
CodeASCIIToBCD ENDP
 
PrintRealTime PROC FAR   ;Процедура вывода времени 
    mov ah, 2h           ;Получить время из часов рельного времени(RTC)
    int 1Ah              ;Прерывание получения реального времени
    jc read_time_err     ;Переход при не удачном чтении времени
    xor ax, ax           
    mov al, ch           ;Ch-Часы    
    xor bx, bx
    call DecodeBCD       ; Запуск процедуры преобразования часов из BCD формата в формат ASCII- строки и одновременно записи в строку для вывода на экран
    mov al, cl
    add bx, 3            ;Сl-минуты
    call DecodeBCD
    mov al, dh           ;Dh-секунды
    add bx, 3
    call DecodeBCD
read_time_err:             ; 
    mov ah, 9h
    lea dx, MsgRTC ; Загрузка адреса сообщения о текущем времени
    int 21h
    lea dx, ASCIITime ; Загрузка адреса текущего времени в формате строки ASCII
    int 21h
    call NextLine
    ret
PrintRealTime ENDP
 
;-----------------Резидентная программа-----------------
MY_ALARM_HANDLER PROC FAR
    ;pushf ; Создание в стеке структуры для вызова IRET
    ; Сохранение модифицируемых регистров
    push es
    push si
    push di
    push ax
    push bx
    push cx
    push dx
    push ds
    push cs
    pop ds
    
    call PlayMelody
    
    mov AH,07h    ;Сброс будильника
    int 1Ah
    mov ax,0C801h    ; - освобождаем память
    int 2Fh
    
end_interupt:
    mov al, 20h    ;завершение прерывания будильника
    out 20h, al
    pop ds
    pop dx
    pop cx
    pop bx
    pop ax
    pop di
    pop si
    pop es
    iret
old_handler:
    ; Извлечение старых значений модифицируемых регистров
    pop ds
    pop dx
    pop cx
    pop bx
    pop ax
    pop di
    pop si
    pop es
    ; Переход к старому обработчику нажатия клавиши (старому обработчику прерывания 09h)
    jmp CS:SYS_KEY_HANDLER
MY_ALARM_HANDLER ENDP
;--------------2F вектор---------------------------------
new_2Fh    proc
    cmp ah,0C8h    ; - наша функция?
    jne out_2fh    
    cmp al,0    ; - анализируем номер подфункции в al
    je qq        ; - если программа уже в памяти
    cmp al,1    
    je uninst    ; - выгружаем программу
    ;jmp out_2fh
qq:    
    mov al,0FFh        ; - уже в памяти
    iret
out_2fh: jmp  cs:old_2Fh  ;иначе на старый обработчик  
    iret
uninst:;деинсталляция вектора
    push ds         ; - сохраним используемые регистры
    push es
    push dx   
    mov ax,254Ah    ; - восстановим 4A вектор,вход - ds:dx
    lds dx,cs:SYS_KEY_HANDLER
    int 21h
    mov ax,252Fh    ; - восстановим мультиплексор
    lds    dx,cs:old_2Fh
    int 21h
    
    mov es,cs:[2Ch]    ; - освобождаем блок, выделенный под переменные окружения(psp)
    mov ah,49h
    int 21h
            ; - теперь освобождаем программный блок
    push cs  ;сохраняем сегмент кода
    pop es   ; 
    mov ah,49h
    int 21h
            ; - восстановим регистры
    pop dx
    pop es
    pop ds
    iret    ; - возврат в вызывающую программу
new_2Fh    endp
 
MAIN endp
;----------------Программа инициализации--------------
INIT PROC NEAR
 
    mov ax,0C800h    ; - ah=C8 - id программы, al=00h - проверка на наличие в памяти
    int 2Fh
    cmp al,0FFh
    jne setup_alarm
    mov ah, 9h
    lea dx, MsgInstalledAlarm
    int 21h;ставим мьютекс
    
    ;mov ax,0C801h    ; - освобождаем память
    ;int 2Fh
    
    ; mov ah,4Ch        ; - завершаем программу обычным образом, без оставления в памяти
    ; int 21h
    
read_loop_reset_msg:
    mov ah, 8h
    int 21h;ждем клавишу
    cmp al, 'y'
    je reset
    cmp al, 'Y'
    je reset
    cmp al, 'n'
    je no_reset
    cmp al, 'N'
    jne read_loop_reset_msg
no_reset:
    mov ah, 4ch
    int 21h;выход если не ставим
reset:
    mov ax,0C801h ;
    int 2Fh
    mov AH,07h    ;Сброс будильника
    int 1Ah
setup_alarm:;установка будильника
    xor ax, ax
    xor dx, dx
    
    mov ah, 9h           ;Вывод сообщения приветствия
    lea dx, WelcomeMsg
    int 21h
    
    call PrintRealTime ; Процедура вывода текущего времени на экран
    
    mov ah, 9h
    lea dx, MsgQuestion
    int 21h
    
read_loop:;цикл чтения
    mov ah, 8h
    int 21h
    cmp al, 'y'
    je yes
    cmp al, 'Y'
    je yes
    cmp al, 'n'
    je end_alarm
    cmp al, 'N'
    jne read_loop
end_alarm:
    mov ah, 4ch;если будильник пропел, то выход
    int 21h
yes:
    
;----------------------ВВОД ЗНАЧЕНИЯ ЧАСОВ-------------------------    
 
    mov  ah,03h ; Определяем текущее
    int  10h ; положение курсора
    mov def_cur_position, dl
    
    mov ah, 9h
    lea dx, Msg1
    int 21h;вывод мессаги
    
    mov  ah,03h ; Определяем текущее
    int  10h ; положение курсора
    mov def_cur_position, dl     ;Запоминаем в переменную
    
    
    xor si, si
enter_hours:;процедуры ввода часов, минут, секунд
    mov ah, 8h
    int 21h
    ; cmp al, 13
    ; je end_of_enter_hours
    cmp al, 8           
    jne no_backspace1
    mov ah,3h ; определяем текущее
    int 10h ; положение курсора
    cmp dl, def_cur_position
    jbe no_backspace1   ;меньше либо равно
    mov ah,2h ; перемещаем его назад
    dec dl ; на одну позицию
    push dx ; Запоминаем положение курсора
    int 10h
    mov ah, 2h
    mov dl, ' '
    int 21h;пробел выводим
    pop dx    ;положение курсора из стека
    int 10h
    cmp si, 2
    jne check_si_one_h
    mov ah, buf[0]
    mov buf[1], ah
    mov buf[0], 0
    dec si ; Уменьшаем счётчик введённых цифр(разрядов)
    jmp enter_hours
check_si_one_h:
    cmp si, 1
    jb enter_hours
    mov buf[1], 0
    dec si
no_backspace1:
    cmp al, 13
    je end_of_enter_hours
    cmp al, '0'
    jb enter_hours     ;меньше 0
    cmp al, '9'       
    ja enter_hours     ;больше 9
    cmp si, 1
    ja enter_hours
    cmp si, 0
    ja low_h
    mov buf[si+1], al    ;положили в единицы часов
    sub buf[si+1], '0'
    mov dl, al
    mov ah, 2h
    int 21h
    jmp end_h
low_h:
    mov ah, byte ptr buf[si]
    cmp ah, 1
    jbe normal_h  ;меньше либо равно
    cmp ah, 2
    ja enter_hours
    cmp al, '3'
    ja enter_hours
normal_h:
    mov byte ptr buf[si-1], ah       ;был мл. стал старший
    mov buf[si], al                ;кладем младший разряд
    sub buf[si], '0'
    mov dl, al
    mov ah, 2h
    int 21h
end_h:
    inc si
    jmp enter_hours
end_of_enter_hours:
    cmp si, 0              ;считает количество введенных символов
    jnz h_result_ok        ;если не равно 0
    mov ah, 2h
    mov dl, '0'
    int 21h
    int 21h
h_result_ok:
    push word ptr buf[0]  ;часы в стек
    pop word ptr AlarmTime[0]
    
    call NextLine
    
;----------------------ВВОД ЗНАЧЕНИЯ МИНУТ-------------------------    
    xor dx, dx
    mov ah, 9h
    lea dx, Msg2
    int 21h
    
    mov  ah,03h ; Определяем текущее
    int  10h ; положение курсора
    mov def_cur_position, dl
    
    mov word ptr buf, 0
    xor si, si
enter_minutes:
    mov ah, 8h
    int 21h
    cmp al, 8
    jne no_backspace_m
    mov  ah,3h ; определяем текущее
    int  10h ; положение курсора
    cmp dl, def_cur_position
    jbe no_backspace_m
    mov  ah,2h ; перемещаем его назад
    dec  dl ; на одну позицию
    push dx
    int  10h
    ; mov ah, 2h
    mov dl, ' '
    int 21h
    pop dx
    int 10h
    cmp si, 2
    jne check_si_one_m
    mov ah, buf[0]
    mov buf[1], ah
    mov buf[0], 0
    dec si
    jmp enter_minutes
check_si_one_m:
    cmp si, 1
    jb enter_minutes
    mov buf[1], 0
    dec si
no_backspace_m:
    cmp al, 13
    je end_of_enter_minutes
    cmp al, '0'
    jb enter_minutes
    cmp al, '9'
    ja enter_minutes
    cmp si, 1
    ja enter_minutes
    cmp si, 0
    ja low_m
    mov buf[si+1], al
    sub buf[si+1], '0'
    mov dl, al
    mov ah, 2h
    int 21h
    jmp end_m
low_m:
    mov ah, byte ptr buf[si]
    cmp ah, 5
    ja enter_minutes
    mov byte ptr buf[si-1], ah
    mov buf[si], al
    sub buf[si], '0'
    mov dl, al
    mov ah, 2h
    int 21h
end_m:
    inc si
    jmp enter_minutes
end_of_enter_minutes:
    cmp si, 0
    jnz m_result_ok
    mov ah, 2h
    mov dl, '0'
    int 21h
    int 21h
m_result_ok:
    push word ptr buf[0] ; кидаем слово с 0 
    pop word ptr AlarmTime[2]    
    
    call NextLine
    
    mov al, AlarmTime[1]    ;
    mov ah, AlarmTime[0]
    call CodeASCIIToBCD
    mov ch, al           ;часы уже bcd
    mov al, AlarmTime[3]
    mov ah, AlarmTime[2]
    call CodeASCIIToBCD
    mov cl, al         ;минуты  bcd
    xor ax, ax
    mov ah, 06h    ;Установим будильник на это время
    mov dh, 00h ;секунды
    int 1Ah
    jnc all_ok ;cf =0
    mov ah, 9h
    lea dx, MsgFailedAlarm
    int 21h
    RET
all_ok:   ;0
    xor dx, dx
    mov ah, 9h
    lea dx, MsgOkAlarm
    int 21h
    mov ah, 9h
    lea dx, Msg4
    int 21h
    
    push word ptr AlarmTime[0]   ;В стек два байта часов
    pop word ptr ASCIITime[0]    
    push word ptr AlarmTime[2]   
    pop word ptr ASCIITime[3]
    push word ptr AlarmTime[4]
    pop word ptr ASCIITime[6]
    
    add ASCIITime[0], '0'
    add ASCIITime[1], '0'
    add ASCIITime[3], '0'
    add ASCIITime[4], '0'
    add ASCIITime[6], '0'
    add ASCIITime[7], '0'
    
    mov ah, 9h
    lea dx, ASCIITime ;выводим шаблон который заполнили
    int 21h
    
    mov ax,354Ah                 ;сохраняем
    int 21h
    mov word ptr SYS_KEY_HANDLER, bx      ;Адрес старого обработчика
    mov word ptr SYS_KEY_HANDLER+2, es    ;Сегмент старого обработчика
    
    mov ax, 254Ah                 ;подменяем
    lea dx, MY_ALARM_HANDLER  ;адрес нач. команды нового обработчика
    int 21h
    
    
    mov ax,352Fh    ; - чтение и сохранение 2Fh вектора
    int 21h
    mov word ptr cs:old_2Fh,bx    
    mov word ptr cs:old_2Fh+2,es
    mov ax,252Fh    ; - записываем новый вектор
    mov dx,offset new_2Fh 
    int 21h
    
    mov ax, 3100h   ;оставить резидент в памяти
    mov dx, (INIT-MAIN+10Fh)/16
    int 21h
    
INIT ENDP
CODE ENDS
    END MAIN
0
0 / 0 / 0
Регистрация: 01.06.2012
Сообщений: 8
01.06.2012, 14:27  [ТС]
а где исправляли?

Добавлено через 58 секунд
я запускаю у меня кучу ошибок выдает
0
202 / 168 / 11
Регистрация: 30.05.2012
Сообщений: 703
01.06.2012, 17:30
Цитата Сообщение от SNasty Посмотреть сообщение
а где исправляли?
Да у Вас получалось что данные выполнялись.

Добавлено через 6 минут
Все работает, проверил, вводятся часы и минуты и звенит.
0
0 / 0 / 0
Регистрация: 01.06.2012
Сообщений: 8
01.06.2012, 23:26  [ТС]
А на чем вы запускаете!у меня через досбокс на win7-64 не проигрывается!
0
202 / 168 / 11
Регистрация: 30.05.2012
Сообщений: 703
02.06.2012, 06:16
Цитата Сообщение от SNasty Посмотреть сообщение
А на чем вы запускаете!у меня через досбокс на win7-64 не проигрывается!
Новые вини стали блокировать, запускай в досовом окне в 32-битной винде.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
02.06.2012, 06:16
Помогаю со студенческими работами здесь

Будильник на C++
Помогите разобраться, нужно сделать будильник на C++

Будильник
Здравствуйте помогите пожалуйста составить код в паскале "Будильника"...Заранее спасибо большое

будильник
есть у кого код? у меня на форме есть procedure TForm1.Timer1Timer(Sender: TObject); begin label1.Caption:=TimeToStr(Now); ...

Будильник
Может у кого-то есть программа с будильником, который звучал бы в заданное время. Сам постарался сделать из аналоговых часов, добавив пару...

Будильник
Всем привет может у кого-нибудь есть пример будильника в LabView самого простого , пока совсем не понимаю что и как, буду очень благодарен


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Новые блоги и статьи
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Символьное дифференцирование
igorrr37 13.02.2026
/ * Программа принимает математическое выражение в виде строки и выдаёт его производную в виде строки и вычисляет значение производной при заданном х Логарифм записывается как: (x-2)log(x^2+2) -. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL3_image
8Observer8 10.02.2026
Содержание блога Библиотека SDL3_image содержит инструменты для расширенной работы с изображениями. Пошагово создадим проект для загрузки изображения формата PNG с альфа-каналом (с прозрачным. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru