;================================= DOSTIME V0.01 =======================================;
; Author: Manfredas Zabarauskas,                                                        ;
;         Vilnius University,                                                           ;
;         Software Engineering I y.                                                     ;
;                                                                                       ;
; Date:   2005 12 12                                                                    ;
;=======================================================================================;
.model small                                                                            ;
.stack 100h                                                                             ;
                                                                                        ;
intr = 15h                                                                              ; interrupt number
                                                                                        ;
.data                                                                                   ;
  dkey       db 0058h                                                                   ; F12 press
  ukey       db 00d8h                                                                   ; F12 release
  symbols    dw 26 dup(?)                                                               ; symbol buffer
  position   dw 0                                                                       ; cursor position
  msg        db 13,10,'DosTime v0.01 loaded into memory successfully!',10,13,'Press '   ; information
             db 'and hold F12 to see the current time.',10,13,'$'                       ;
;=======================================================================================;

.code
  oldseg    dw 0
  oldoffs   dw 0

  ;========= INT 15H INTERRUPT PROCEDURE ==========;
  newhandle proc                                   ;
                                                   ;
    ;------------- initialization ------------;    ;
    push ds                                   ;    ;
    push dx
    mov dx, @data                             ;    ;
    mov ds, dx                                ;    ;
    ;-----------------------------------------;    ;
                                                   ;
    ;------- keyboard interrupt handler ------;    ;
    cmp ah, 4fh                               ;    ;           
    jne endhandle                             ; int 15, 4fh
    ;-----------------------------------------;    ;
                                                   ;
    ;----------- key press handler -----------;    ;
    cmp al, ds:dkey                           ;    ;
    jne skip                                  ;    ;
                                              ;    ; 
    call onkeypress                           ;    ;
                                              ;    ;
    mov al, 00h                               ;    ;
    jmp endhandle                             ;    ;
    ;-----------------------------------------;    ;
                                                   ;
    ;---------- key release handler ----------;    ;
   skip:                                      ;    ;
    cmp al, ukey                              ;    ;
    jne endhandle                             ;    ;
                                              ;    ;
    call onkeyrelease                         ;    ;
    mov al, ukey                              ;    ;
    ;-----------------------------------------;    ;            
                                                   ;
   endhandle:                                      ;
    ;- end of new keyboard interrupt handler -;    ;
    cmp [position], 00h                       ;    ;
    je oldint;                                ;    ;
    mov al, dkey                              ;    ;
   oldint:                                    ;    ;
    pop dx                                    ;    ;
    pop ds                                    ;    ;
    push cs:[oldseg]                          ;    ;
    push cs:[oldoffs]                         ;    ;
    retf                                      ; return, loading [cs:ip] address from stack
    ;-----------------------------------------;    ;
                                                   ;
  newhandle endp                                   ;
  ;================================================;


  ;================================================;
  onkeypress proc                                  ;
                                                   ;
    ;--------- saving register values --------;    ;
    push ax                                   ;    ;
    push bx                                   ;    ;
    push cx                                   ;    ;
    push dx                                   ;    ;
    push si                                   ;    ;
    push di                                   ;    ;
    ;-----------------------------------------;    ;
                                                   ;
    cmp position, 00h                              ;
    jne return                                     ;
                                                   ;
    ;-------- saving cursor position ---------;    ;
    mov ah, 03h                               ;    ;
    mov bh, 00h                               ;    ;
    int 10h                                   ;    ;
    mov [position], dx                        ;    ;
    ;-----------------------------------------;    ;
                                                   ;
    ;---------- saving characters ------------;    ;
    mov cx, 0dh                               ;    ;
   getchars:                                  ;    ;
    mov bx, 000dh                             ; loop for 13 symbols
    sub bx, cx                                ;    ;
                                              ;    ;
    mov ah, 02h                               ; int 10h, 02h call for getting the next symbol
    mov dh, 00h                               ;    ;
    mov dl, bl                                ;    ;
    mov bh, 00h                               ;    ;
    int 10h                                   ;    ;
                                              ;    ;
    mov ax, 000dh                             ; calculating memory space address
    sub ax, cx                                ;    ;
    mov bx, 0002h                             ;    ;
    mul bx                                    ;    ;
    mov bx, ax                                ;    ;
                                              ;    ;
    mov ah, 08h                               ; saving symbol
    mov bh, 00h                               ;    ;
    int 10h                                   ;    ;
    mov [symbols+bx], ax;                     ;    ;
    loop getchars                             ;    ;
    ;-----------------------------------------;    ;
                                                   ;
   return:                                         ;
    ;---- changing cursor position to the ----;    ;
    ;      top left corner of the screen      ;    ;
    mov ah, 02h                               ;    ;
    mov dh, 00h                               ;    ;
    mov dl, 00h                               ;    ;
    mov bh, 00h                               ;    ;
    int 10h                                   ;    ;
    ;-----------------------------------------;    ;
                                                   ;
                                                   ;
    ;--------- printing current time ---------;    ;
    call writetime                            ;    ; call for time print
    ;-----------------------------------------;    ;
                                                   ;
    ;-------- reseting register values -------;    ;
    pop di                                    ;    ;
    pop si                                    ;    ;
    pop dx                                    ;    ;
    pop cx                                    ;    ;
    pop bx                                    ;    ;
    pop ax                                    ;    ;
    ;-----------------------------------------;    ;
                                                   ;
    ret                                            ;
  onkeypress endp                                  ;
  ;================================================;


  ;=========== KEY RELEASE PROCEDURE ==============;
  onkeyrelease proc                                ;
                                                   ;
    ;--------- saving register values --------;    ;
    push ax                                   ;    ;
    push bx                                   ;    ;
    push cx                                   ;    ;
    push dx                                   ;    ;
    push si                                   ;    ;
    push di                                   ;    ;
    ;-----------------------------------------;    ;
                                                   ;
    ; ------ restoring changed symbols -------;    ;
    mov cx, 0dh                               ;    ;
   setchars:                                  ;    ;
    mov bx, 000dh                             ;    ;
    sub bx, cx                                ;    ;
                                              ;    ;
    mov ah, 02h                               ; changing cursor position
    mov dh, 00h                               ;    ;
    mov dl, bl                                ;    ;
    mov bh, 00h                               ;    ;
    int 10h                                   ;    ;
                                              ;    ;
    mov ax, 000dh                             ; calculating the offset in the memory
    sub ax, cx                                ;    ;
    mov bx, 0002h                             ;    ;
    mul bx                                    ;    ;
    mov bx, ax                                ;    ;
                                              ;    ;
    mov ax, [symbols+bx]                      ; restoring the symbols
    mov bl, ah                                ;    ;
    mov ah, 09h                               ;    ;
    mov bh, 00h                               ;    ;
    push cx                                   ;    ;
    mov cx, 01h                               ;    ;
    int 10h                                   ;    ;
    pop cx                                    ;    ;
    loop setchars                             ;    ;
    ;-----------------------------------------;    ;
                                                   ;
    ;------ restoring cursor position --------;    ;
    mov dx, [position]                        ;    ;
    mov ah, 02h                               ;    ;
    mov bh, 00h                               ;    ;
    int 10h                                   ;    ;
    ;-----------------------------------------;    ;
                                                   ;
    ;-------- reseting register values -------;    ;
    pop di                                    ;    ;
    pop si                                    ;    ;
    pop dx                                    ;    ;
    pop cx                                    ;    ;
    pop bx                                    ;    ;
    pop ax                                    ;    ;
    ;-----------------------------------------;    ;
                                                   ;
    mov [position], 00h                            ; clearing cursor position
    ret                                            ;
  onkeyrelease endp                                ;
  ;================================================;


  ;============ PRINTING CURRENT TIME =============;
  writetime proc                                   ;
                                                   ;
    ;--------- saving register values --------;    ;
    push ax                                   ;    ;
    push bx                                   ;    ;
    push cx                                   ;    ;
    push dx                                   ;    ;
    push si                                   ;    ;
    push di                                   ;    ;
    ;-----------------------------------------;    ;
                                                   ;
    ; -------- printing space symbol ---------;    ;
    mov ah, 09h                               ;    ;
    mov al, ' '                               ;    ;
    mov bh, 00h                               ;    ;
    mov bl, 00001100b                         ;    ;
    mov cx, 01h                               ;    ;
    int 10h                                   ;    ;
    ;-----------------------------------------;    ;
                                                   ;
    ;------------- moving cursor -------------;    ;
    mov ah, 03h                               ;    ;
    mov bh, 00h                               ;    ;
    int 10h                                   ;    ;
                                              ;    ;
    mov ah, 02h                               ;    ;
    inc dx                                    ;    ;
    mov bh, 00h                               ;    ;
    int 10h                                   ;    ;
    ;-----------------------------------------;    ;
                                                   ;
    ;---------- getting system time ----------;    ;
    push ax                                   ;    ;
    push bx                                   ;    ;
    push si                                   ;    ;
    push di                                   ;    ;
    mov ah, 2ch                               ;    ;
    int 21h                                   ;    ;
    pop di                                    ;    ;
    pop si                                    ;    ;
    pop bx                                    ;    ; 
    pop ax                                    ;    ;
                                              ;    ;
    push dx                                   ;    ;
    push cx                                   ;    ;
    ;-----------------------------------------;    ;
                                                   ;    
    ;------------ printing hours -------------;    ;
    mov al, ch                                ;    ;
    mov ah, 00h                               ;    ;
                                              ;    ;
    call writeal                              ;    ;
    ;-----------------------------------------;    ;
                                                   ;    
    ;------------- moving cursor -------------;    ;
    mov ah, 03h                               ;    ;
    mov bh, 00h                               ;    ;
    int 10h                                   ;    ;
                                              ;    ;
    mov ah, 02h                               ;    ;
    inc dx                                    ;    ;
    mov bh, 00h                               ;    ;
    int 10h                                   ;    ;
    ;-----------------------------------------;    ;
                                                   ;
    ; ---------- printing separator ----------;    ;
    mov ah, 09h                               ;    ;
    mov al, ':'                               ;    ;
    mov bh, 00h                               ;    ;
    mov bl, 00001100b                         ;    ;
    mov cx, 01h                               ;    ;
    int 10h                                   ;    ;
    ;-----------------------------------------;    ;
                                                   ;
    ;------------- moving cursor -------------;    ;
    mov ah, 03h                               ;    ;
    mov bh, 00h                               ;    ;
    int 10h                                   ;    ;
                                              ;    ;
    mov ah, 02h                               ;    ;
    inc dx                                    ;    ;
    mov bh, 00h                               ;    ;
    int 10h                                   ;    ;
    ;-----------------------------------------;    ;
                                                   ;
    ;----------- printing minutes ------------;    ;
    pop cx                                    ;    ;
    mov al, cl                                ;    ;
    mov ah, 00h                               ;    ;
    call writeal                              ;    ;
    ;-----------------------------------------;    ;
                                                   ;
    ;------------- moving cursor -------------;    ;
    mov ah, 03h                               ;    ;
    mov bh, 00h                               ;    ;
    int 10h                                   ;    ;
                                              ;    ;
    mov ah, 02h                               ;    ;
    inc dx                                    ;    ;
    mov bh, 00h                               ;    ;
    int 10h                                   ;    ;
    ;-----------------------------------------;    ;
                                                   ;
    ; ---------- printing separator ----------;    ;
    mov ah, 09h                               ;    ;
    mov al, ':'                               ;    ;
    mov bh, 00h                               ;    ;
    mov bl, 00001100b                         ;    ;
    mov cx, 01h                               ;    ;
    int 10h                                   ;    ;
    ;-----------------------------------------;    ;
                                                   ;
    ;------------- moving cursor -------------;    ;
    mov ah, 03h                               ;    ;
    mov bh, 00h                               ;    ;
    int 10h                                   ;    ;
                                              ;    ;
    mov ah, 02h                               ;    ;
    inc dx                                    ;    ;
    mov bh, 00h                               ;    ;
    int 10h                                   ;    ;
    ;-----------------------------------------;    ;
                                                   ;
    ;------------ printing seconds -----------;    ;
    pop cx                                    ;    ;
    push cx                                   ;    ;
    mov al, ch                                ;    ;
    mov ah, 00h                               ;    ;
    call writeal                              ;    ;
    ;-----------------------------------------;    ;
                                                   ;
    ;------------- moving cursor -------------;    ;
    mov ah, 03h                               ;    ;
    mov bh, 00h                               ;    ;
    int 10h                                   ;    ;
                                              ;    ;
    mov ah, 02h                               ;    ;
    inc dx                                    ;    ;
    mov bh, 00h                               ;    ;
    int 10h                                   ;    ;
    ;-----------------------------------------;    ;
                                                   ;
    ; ---------- printing separator ----------;    ;
    mov ah, 09h                               ;    ;
    mov al, '.'                               ;    ;
    mov bh, 00h                               ;    ;
    mov bl, 00001100b                         ;    ;
    mov cx, 01h                               ;    ;
    int 10h                                   ;    ;
    ;-----------------------------------------;    ;
                                                   ;
    ;------------- moving cursor -------------;    ;
    mov ah, 03h                               ;    ;
    mov bh, 00h                               ;    ;
    int 10h                                   ;    ;
                                              ;    ;
    mov ah, 02h                               ;    ;
    inc dx                                    ;    ;
    mov bh, 00h                               ;    ;
    int 10h                                   ;    ;
    ;-----------------------------------------;    ;
                                                   ;
    ;---------- printing miliseconds ---------;    ;
    pop cx                                    ;    ;
    mov al, cl                                ;    ;
    mov ah, 00h                               ;    ;
    call writeal                              ;    ;
    ;-----------------------------------------;    ;
                                                   ;
    ;------------- moving cursor -------------;    ;
    mov ah, 03h                               ;    ;
    mov bh, 00h                               ;    ;
    int 10h                                   ;    ;
                                              ;    ;
    mov ah, 02h                               ;    ;
    inc dx                                    ;    ;
    mov bh, 00h                               ;    ;
    int 10h                                   ;    ;
    ;-----------------------------------------;    ;
                                                   ;
    ; -------- printing space symbol ---------;    ;
    mov ah, 09h                               ;    ;
    mov al, ' '                               ;    ;
    mov bh, 00h                               ;    ;
    mov bl, 00001100b                         ;    ;
    mov cx, 01h                               ;    ;
    int 10h                                   ;    ;
    ;-----------------------------------------;    ;
                                                   ;
    ;------------- moving cursor -------------;    ;
    mov ah, 03h                               ;    ;
    mov bh, 00h                               ;    ;
    int 10h                                   ;    ;
                                              ;    ;
    mov ah, 02h                               ;    ;
    inc dx                                    ;    ;
    mov bh, 00h                               ;    ;
    int 10h                                   ;    ;
    ;-----------------------------------------;    ;
                                                   ;
    ;-------- reseting register values -------;    ;
    pop di                                    ;    ;
    pop si                                    ;    ;
    pop dx                                    ;    ;
    pop cx                                    ;    ;
    pop bx                                    ;    ;
    pop ax                                    ;    ;
    ;-----------------------------------------;    ;
                                                   ;
    ret                                            ;
  writetime endp                                   ;
  ;================================================;


  ;============= PRINTING AL REGISTER =============;
  writeal proc                                     ;
                                                   ;
    ;--------- saving register values --------;    ;
    push ax                                   ;    ;
    push bx                                   ;    ;
    push cx                                   ;    ;
    push dx                                   ;    ;
    push si                                   ;    ;
    push di                                   ;    ;
    ;-----------------------------------------;    ;
                                                   ;
    ;----- storing integer value in al,  -----;    ;
    ;         residue in ah register          ;    ;
    mov bl, 0ah                               ;    ;
    div bl                                    ;    ;
    mov cx, ax                                ;    ;
    push cx                                   ;    ;
    ;-----------------------------------------;    ;
                                                   ;
    ;-------- printing integer value ---------;    ;
    mov ah, 09h                               ;    ;
    mov al, cl                                ;    ;
    add al, 30h                               ;    ;
    mov bh, 00h                               ;    ;
    mov bl, 00001100b                         ;    ;
    mov cx, 01h                               ;    ;
    int 10h                                   ;    ;
    ;-----------------------------------------;    ;
                                                   ;
    ;------------- moving cursor -------------;    ;
    mov ah, 03h                               ;    ;
    mov bh, 00h                               ;    ;
    int 10h                                   ;    ;
                                              ;    ;
    mov ah, 02h                               ;    ;
    inc dx                                    ;    ;
    mov bh, 00h                               ;    ;
    int 10h                                   ;    ;
    ;-----------------------------------------;    ;
                                                   ;
    ;----------- printing residue ------------;    ;
    pop cx                                    ;    ;
    mov ah, 09h                               ;    ;
    mov al, ch                                ;    ;
    add al, 30h                               ;    ;
    mov bh, 00h                               ;    ;
    mov bl, 00001100b                         ;    ;
    mov cx, 01h                               ;    ;
    int 10h                                   ;    ;
    ;-----------------------------------------;    ;
                                                   ;
    ;-------- reseting register values -------;    ;
    pop di                                    ;    ;
    pop si                                    ;    ;
    pop dx                                    ;    ;
    pop cx                                    ;    ;
    pop bx                                    ;    ;
    pop ax                                    ;    ;
    ;-----------------------------------------;    ;
                                                   ;
    ret                                            ;
  writeal endp                                     ;
  ;================================================;


  ;================ DOSTIME V0.01 =================;
  main:                                            ;
                                                   ;
    ;------------- INITIALIZATION ------------;    ;
    mov ax, @data                             ;    ;
    mov ds, ax                                ;    ;
    ;-----------------------------------------;    ;
                                                   ;
    ;------------ PRINTING MESSAGE -----------;    ;
    lea dx, msg                               ;    ;
    mov ah, 09h                               ;    ;
    int 21h                                   ;    ;
    ;-----------------------------------------;    ;
                                                   ;
    mov ax, 0                                      ;
    mov es, ax                                     ;
                                                   ;
    ;------- SAVING OLD INT 15H ADDRESS ------;    ;
    mov ax, es:[intr*4]                       ;    ;
    mov cs:[oldoffs], ax                      ;    ;
    mov ax, es:[intr*4 + 2]                   ;    ;
    mov cs:[oldseg], ax                       ;    ;
    ;-----------------------------------------;    ;
                                                   ;
    ;------ LOADING NEW INT 15H ADDRESS ------;    ;
    pushf                                     ;    ;
    cli                                       ;    ;
    mov word ptr es:[intr*4], offset newhandle;    ;
    mov word ptr es:[intr*4+2], seg newhandle ;    ;
    popf                                      ;    ;
    ;-----------------------------------------;    ;
                                                   ;
    lea dx, main + 100h                            ; setting resident memory limits
    int 27h                                        ; switching into TSR mode
  end main                                         ;
  ;================================================;