привет, нужна ваша помощь или подсказка, пишу для одного человека скрин-сейвер под дос, резидент, все сделал, но никак не могу доделать одну часть: при выходе из скрин-сейвера (при нажатии любой клавиши) мы должны ввести пароль, если пароль правильный, то скрин завершается, если неправильный, то не завершается (резидент остается в памяти в любом случае) вопрос в следующем: каким образом вывести надпись о вводе пароля (что-то вроде 'enter password:', 21h нельзя в обработчике юзать), считать пароль в буфер и проверить на правильность? help! Код (Text): ; ----------------------------------------------------------------- ; ; resident screen-saver ; ; ----------------------------------------------------------------- org 100h use16 _start: jmp _init ; constants shft_cnt equ 37 ; ticks between screen shifts 37 = 2 sec id db "SCRSAVER_SIGN" maxcount dw 5465 ; timer ticks for delay 2186 = 2 min old9_ofs dw ? ; old int 9 address old9_seg dw ? old1C_ofs dw ? ; old int 1C address old1C_seg dw ? old_tail dw ? ; keyboard buffer tail off_flg db 0 ; 1 = disable blanking 0 = normal operation scr_offst dw 0 ; offset for shifting screen blank db 0 ; 1 = 'blank' screen 0 = normal screen turn_on db 0 ; 1 = unblank screen 0 = nothing count dw 0 ; tick counter for blanking ; code ; keyboard hook _new9: push es ds ax cs pop ds mov ax,40h mov es,ax mov ax,[es:1Ch] mov [old_tail],ax pushf call dword [old9_ofs] cmp [blank],0 ; check for blank screen jnz _rest_scrn mov [count],0 ; reset tick counter jmp _exit_9 _rest_scrn: ; set flag to unblank screen mov [turn_on],1 mov ax,[old_tail] ; restore tail pointer to remove key from buffer mov [es:1Ch],ax _exit_9: pop ax ds es iret ; timer hook _new1C: sti ; enable interrupts push es ds dx ax cs pop ds mov ax,40h mov es,ax cmp [turn_on],0 ; check if flag set to restore screen je _if_blank ; jump to check for blank screen if flag not set _no_key: mov [turn_on],0 ; restore original video buffer start mov [blank],0 mov ax,[es:4Eh] ; get bios video buffer start (bytes) shr ax,1 ; convert to words push ax jmp _do_crt ; set crt controller _if_blank: cmp [off_flg],0 ; exit if disabled jne _exit_1C cmp [blank],0 ; check if screen already blank jne _chk_shift ; if blank then jump to check if ready to shift inc [count] ; screen not blank - check if time to blank mov ax,[maxcount] cmp [count],ax jne _exit_1C ; exit if not time to blank mov [blank],1 ; set blank screen flag jmp _do_shift ; shift screen _chk_shift: ; if screen blank - shift every shft_cnt ticks inc [count] cmp [count],shft_cnt jne _exit_1C ; exit if not time to shift _do_shift: mov ax,[scr_offst] ; get our video buffer offset (words) add ax,1003 ; shift 1003 words and ax,7FFh ; limit to first 4K of video buffer mov [scr_offst],ax ; save our new video buffer offset mov dx,[es:4Eh] ; get bios video buffer start (bytes) shr dx,1 ; convert to words add ax,dx ; add our offset push ax _do_crt: ; set crt controller mov dx,[es:63h] ; crt controller base address mov al,12 ; access register 12 out dx,al inc dx pop ax ; pop starting address xchg ah,al out dx,al ; write hi (start address) to register 12 dec dx push ax ; push starting address mov al,13 ; access register 13 out dx,al inc dx pop ax ; pop starting address xchg ah,al out dx,al ; write lo (start address) to register 13 mov [count],0 ; reset tick counter _exit_1C: pop ax dx ds es jmp dword [cs:old1C_ofs] ; messages inside segment _init_junk: szUsage db "~ Resident screen-saver ~",13,10,13,10 db "Usage: screensaver.com [delay]",13,10 db " 0 disables screen-saver",13,10 db " 1-9 re-enables",13,10,13,10 db "Default delay is two minutes",13,10,24h szDisableMsg db "Resident screen-saver disabled",13,10,24h szEnableMsg db "Resident screen-saver enabled",13,10,24h szError1 db "Invalid command line parameter",13,10,24h szError2 db "Screen-saver not in resident mode",13,10,24h ; initialization _init: mov si,81h mov dx,szError1 ; invalid command _parse_loop: ; check for number on command line lodsb cmp al," " je _parse_loop ; skip spaces cmp al,13 je _end_parse ; jump if no parameter cmp al,"9" jg _out_err ; invalid parameter cmp al,"0" jl _out_err ; invalid parameter cmp al,"0" jne _set_time mov [off_flg],1 ; set disable flag _set_time: mov ah,0 sub al,"0" mov bx,1093 mul bx mov [maxcount],ax _end_parse: cld ; search for a previous copy mov word [_start],0 ; fingerprint xor bx,bx ; bx = start segment mov ax,cs ; ax = current segment cmp ax,0A000h ; assume first load if running in high memory jae _no_copies _chk_prev: inc bx ; increment segment cmp ax,bx ; check if equals current segment jne _next mov bx,0A000h ; if yes, move search to high memory _next: cmp bx,0FFFFh ; end search if end of memory reached je _no_copies mov es,bx mov si,_start mov di,si mov cx,16 ; compare first 16 bytes of each segment repe cmpsb jne _chk_prev ; repeat if no match mov ax,[maxcount] ; copy found - set time for activation mov [es:maxcount],ax mov al,[off_flg] ; change enable/disable flag mov [es:off_flg],al mov [es:count],0 ; reset tick count mov dx,szEnableMsg ; enabled test al,al je _out_msg ; copy enabled - errorlevel = 0 mov dx,szDisableMsg ; disabled xor al,al ; errorlevel = 0 jmp _out_msg ; copy disabled _no_copies: mov dx,szError2 ; not resident cmp [off_flg],0 je _install ; ok to install _out_err: mov al,1 _out_msg: mov ah,9 ; display message int 21h mov ah,4Ch ; terminate with errorlevel = al int 21h _install: ; make program resident mov ax,3509h ; get old int 9 address int 21h mov ax,es mov [old9_seg],ax ; save old int 9 address (keyboard) mov [old9_ofs],bx mov ax,351Ch ; get old int 1C address (timer tick) int 21h mov ax,es mov [old1C_seg],ax ; save old int 1C address mov [old1C_ofs],bx mov dx,_new9 ; set int 9 to point to our code mov ax,2509h int 21h mov dx,_new1C ; set int 1C to point to our code mov ax,251Ch int 21h mov dx,szUsage ; usage mov ah,9 int 21h ; display message mov dx,(_init_junk-_start+256+16)/16 mov ax,3100h ; terminate and stay resident int 21h ; eof
да не вроде, а точно работает ) а че непонятного то.. прерывание биоса для считывания символа. на крайняк общаться с контроллером через порты ввода-вывода
А если клава USBшная? Более портабельно получится через буфер клавиатуры. Из Ralf Brown's Files: По Зубкову, 40:1A = адрес головы, +2 - адрес хвоста
То пофиг. Доступ к портам тоже эмулируется BIOS, даже если клавиатура USB. Если конечно эмуляция включена. А если не включена то USB клавиатура вообще работать не будет, и ты и в буфере ничего не получишь. Самый простой способ - int 16h Не надо сильно заморачиваться и в резиденте работать будет.