Back to home page

DOS ain't dead

Forum index page

Log in | Register

Back to the forum
Board view  Mix view

How to keep resident only a part of the program (Developers)

posted by CandyMan, 27.08.2021, 17:46

If you want to write resident programs then use assembler. Here is my old program, replacement for the DOS keyboard driver, written in fasm. The resident part is between KeyStart and KeybSize.
Here code:
                org     100h
                mov     dx,Information+1
                call    Print
                mov     ax,3509h
                int     21h
                mov     word [KeyStart+Old09h+0],bx
                mov     word [KeyStart+Old09h+2],es

                mov     ah,$AD          ; Disable Controller
                call    SetStat

                in      al,21h          ;\
                or      al,00000010b    ;  > Disable IRQ1
                out     21h,al          ;/

                mov     ah,20h          ; Read Command Byte
                call    GetEcho
                push    ax

                mov     ah,$AA          ; Keyboard Self Test
                call    GetEcho
                jnz     NotAnswer
                cmp     al,55h
                jnz     NotAnswer

                mov     ah,$F4          ; Enable Keyboard
                call    SetOut

                mov     ah,$F3          ; Set Typematic Rate&Delay
                call    SetOut
                mov     ah,0            ; Max Rate&Delay
                call    SetOut

NotAnswer:      pop     bx              ; Restore Command Byte
                or      bl,1
                mov     ah,60h          ; Set Command Byte
                call    SetEcho

                mov     ah,$AE          ; Enable Controller
                call    SetStat

                in      al,21h          ;\
                and     al,11111101b    ;  > Enable IRQ1
                out     21h,al          ;/

                call    GetMem
                jc      Quit
                xor     di,di
                mov     cx,KeybSize
                mov     si,KeyStart
                rep movsb

                push    es
                pop     ds

                mov     ax,2509h
                mov     dx,New09h
                int     21h
                ret
Quit:           mov     dx,NoMem
Print:          mov     ah,9
                int     21h
                ret

Allocate:       mov     ah,48h
                mov     bx,Paragraphs
                int     21h
                ret

GetMem:         mov     ax,5802h
                int     21h
                xor     ah,ah
                mov     si,ax
                cmp     al,1
                je      LoadUpper
                mov     ax,5803h
                mov     bx,1
                int     21h
                jc      NoUpper
LoadUpper:      call    Allocate
                pushf
                push    ax
                mov     ax,5803h
                mov     bx,si
                int     21h
                pop     ax
                popf
                jnc     IsOK

NoUpper:        mov     ah,4Ah
                mov     bx,-1
                push    ds
                pop     es
                int     21h
                sub     bx,Paragraphs+1
                jc      MemEnd
                mov     ah,4Ah
                int     21h
                jc      MemEnd
                call    Allocate
                jc      MemEnd
IsOK:           push    ax
                dec     ax
                mov     es,ax
                inc     ax
                mov     di,1
                cld
                stosw
                add     di,5
                mov     si,Information
                movsw
                movsw
                movsw
                movsw
                pop     es
MemEnd:         ret

; Wait Not Data in port 60h\64h
WaitNoData:     xor     cx,cx
.WaitRetry:     in      al,64h
                out     $EB,al
                test    al,00000010b
                jz      .Ok
                loop    .WaitRetry
                inc     cx
.Ok:            ret

; Wait No TimeOut (Data transmit completed)
WaitNoTime:     xor     cx,cx
.WaitTime:      in      al,64h
                test    al,00100000b
                jz      .Ok
                loop    .WaitTime
                inc     cx
.Ok:            ret

; Wait Data in port 60h
WaitOutput:     mov     ah,0Ch
.CheckAgain:    xor     cx,cx
.CheckOutput:   in      al,64h
                out     $EB,al
                test    al,00000001b
                jnz     .IsOutput    ; Ok!
                loop    .CheckOutput
                dec     ah           ; \ Wait error!
                jnz     .CheckAgain  ; / Wait again
.IsOutput:      lahf                 ; \
                xor     ah,40h       ;   > Negate ZF
                sahf                 ; /
                ret

; Set Command in AH to Status Register
SetStat:        cli
                call    WaitNoData
                jnz     .Err
                mov     al,ah
                out     64h,al
                call    WaitNoData
.Err:           sti
                ret

; Set Command in AH to Output Register
SetOut:         cli
                call    WaitNoTime
                jnz     .Err
                in      al,60h
                call    WaitNoData
                jnz     .Err
                mov     al,ah
                out     60h,al
                call    WaitNoData
                call    WaitOutput
                jnz     .Err
                in      al,60h
                cmp     al,$FA
.Err:           sti
                ret

; Set Command in AH to Status Register &
; get echo\command from Output Register
GetEcho:        cli
                call    SetStat
                jnz     .Err
                call    WaitOutput
                jnz     .Err
                in      al,60h
.Err:           sti
                ret

; Set Command in AH to Status Register &
; set echo\command in BL from Output Register
SetEcho:        cli
                call    SetStat
                jnz     .Err
                call    WaitNoData
                jnz     .Err
                mov     al,bl
                out     60h,al
                call    WaitNoData
.Err:           sti
                ret

ReadInput:      cli
                mov     bx,$FF0F
                call    WaitNoData
                jnz     .Err
.Retry:         mov     ah,$C0
                call    GetEcho
                jnz     .Err
                cmp     al,bh
                je      .Ok
                mov     bh,al
                xor     cx,cx
                loop    $
                dec     bl
                jnz     .Retry
.Err:           inc     cx
.Ok:            sti
                ret

Information     db      '$KEYB-PL v1.1',13,10,36
NoMem           db      13,10,'Not enough memory',13,10,36

KeyStart:       org     0
KeyTable:       db      $1E,$2E,$12,$26,$31,$18,$1F,$2C,$2D
                db      $A5,$86,$A9,$88,$E4,$A2,$98,$BE,$AB
                db      $A4,$8F,$A8,$9D,$E3,$E0,$97,$BD,$8D
New09h:         push    ax bx ds si
                push    40h
                pop     ds
                mov     ax,[1Ch]
                mov     si,ax
                inc     ax
                inc     ax
                cmp     ax,[82h]
                jne     @1
                mov     ax,[80h]
@1:             cmp     ax,[1Ah]
                je      Return
                xchg    bx,ax

                mov     ax,[17h]
                test    al,8
                je      Return
                xchg    ah,al
                test    al,2
                jne     Return

                in      al,60h
                cmp     al,31h  ; Max z KeyTable
                ja      Return
                push    di
                push    cx
                push    es
                push    cs
                pop     es
                cld
                mov     cx,9
                xor     di,di   ; mov di,KeyTable
                repnz scasb
                pop     es
                pop     cx
                jne     Exit
                xchg    ah,al

                test    al,40h
                je      @2
                and     al,3    ; test al,3
                jne     @4
                jmp     @3
@2:             and     al,3    ; test al,3
                je      @4
@3:             add     di,9
@4:             cbw             ; xor ah,ah
                mov     al,[cs:di+8]
                mov     [si],ax
                mov     [1Ch],bx
                mov     al,20h
                out     20h,al
                pop     di si ds bx ax
                iret
Exit:           pop     di
Return:         pop     si ds bx ax
                db      $EA
Old09h          dd      ?
KeybSize:
Paragraphs      = ($+15)/16

 

Complete thread:

Back to the forum
Board view  Mix view
22049 Postings in 2034 Threads, 396 registered users, 64 users online (0 registered, 64 guests)
DOS ain't dead | Admin contact
RSS Feed
powered by my little forum