AuthorMessage
Meka][Meka
Unstopable
Posts: 700

was jus looking around @ asm stuff
Code:

CODE     SEGMENT PARA
         ASSUME CS:CODE, DS:CODE, ES:CODE
         ORG 100h
START:   JMP INIT                      ; JUMP TO INITIALIZATION ROUTINE
;------- DATA STORAGE --------------------------------------------------------
FREQ     = 546                         ; TIME CHECK FREQUENCY (30 SECS)
OLDINT   DD ?                          ; OLD INTERRUPT 1Ch VECTOR
COUNT    DW FREQ-1                     ; INTERRUPT COUNTER
MINUTE   DB 00                         ; ALARM MINUTE
HOUR     DB 00                         ; ALARM HOUR
;------- RESIDENT PART OF PROGRAM --------------------------------------------
NEW_INT  PROC     FAR
         ASSUME DS:NOTHING, ES:NOTHING
BEGIN:   STI                           ; ENABLE INTERUPTS
         PUSHF                         ; SAVE FLAGS ON STACK
         PUSH   AX                     ; SAVE REGISTERS
         PUSH   BX
         PUSH   CX
         PUSH   DX
         PUSH   DI
         PUSH   SI
         PUSH   DS
         PUSH   ES
         PUSH   CS                     ; RETRIEVE DATA SEGMENT
         POP    DS
         INC    COUNT                  ; INCREMENT INTERRUPT COUNTER
         CMP    COUNT,FREQ             ; TIME TO CHECK CLOCK?
         JB     EXIT                   ; EXIT IF NOT
;        CHECK TIME
CHECK:   MOV    AH,02h                 ; GET TIME FROM BIOS
         INT    1Ah                    ;   CH=HOURS, CL=MINUTES (BCD)
         CMP    CH,HOUR                ; COMPARE WITH ALARM HOUR
         JNE    RESET                  ; RESET IF CURRENT # ALARM HOUR
         CMP    CL,MINUTE              ; HOURS ARE SAME, COMPARE MINUTES
         JE     ALARM                  ; ALARM IF CURRENT = ALARM MINUTE
                                       ; OTHERWISE RESET COUNTER
RESET:   MOV    COUNT,0000             ; RESET INTERRUPT COUNTER
         JMP    EXIT                   ; JUMP TO EXIT
;------- GENERATE ALARM ------------------------------------------------------
ALARM:   MOV    DI,400                 ; SET UP REGISTERS FOR BEEP PROCEDURE
         MOV    BX,20                  ;
         CALL   BEEP                   ; MAKE THE TONE
         MOV    DI,500                 ; SET UP REGISTERS FOR BEEP PROCEDURE
         MOV    BX,20                  ;
         CALL   BEEP                   ; MAKE THE TONE
         MOV    DI,600                 ; SET UP REGISTERS FOR BEEP PROCEDURE
         MOV    BX,20                  ;
         CALL   BEEP                   ; MAKE THE TONE
         MOV    DI,700                 ; SET UP REGISTERS FOR BEEP PROCEDURE
         MOV    BX,10                  ;
         CALL   BEEP                   ; MAKE THE TONE
         MOV    AX,2                   ; PAUSE
OUTER:   MOV    CX,0FFFFh              ; OUTER LOOP
INNER:   LOOP   INNER                  ; INNER LOOP
         DEC    AX
         JA     OUTER
         MOV    DI,600                 ; SET UP REGISTERS FOR BEEP PROCEDURE
         MOV    BX,20                  ;
         CALL   BEEP                   ; MAKE THE TONE
         MOV    DI,700                 ; SET UP REGISTERS FOR BEEP PROCEDURE
         MOV    BX,40                  ;
         CALL   BEEP                   ; MAKE THE TONE
;        MOVE JMP INSTRUCTION TO ENTRY POINT (DISABLE THIS PROGRAM)
         PUSH   CS
         POP    ES
         MOV    SI,OFFSET JUMP         ; SET SEGMENT TO 0000
         MOV    DI,OFFSET NEW_INT
         MOV    CX,05
         CLD                           ; DIRECTION = FORWARD
         CLI                           ; DISABLE INTERRUPTS
         REP    MOVSB                  ; COPY JMP INSTRUCTION
         STI                           ; ALLOW INTERRUPTS AGAIN
;------- END THIS INTERRUPT ROUTINE ------------------------------------------
EXIT:    POP    ES
         POP    DS
         POP    SI
         POP    DI
         POP    DX
         POP    CX
         POP    BX
         POP    AX
         POPF
JUMP:    JMP    CS:OLDINT
NEW_INT  ENDP
;------- PROCEDURE TO CREATE A SINGLE TONE -----------------------------------
;        DI = FREQUENCY, BX = DURATION
BEEP     PROC    NEAR
         ASSUME  DS:NOTHING, ES:NOTHING
         PUSH    AX                    ; Save registers
         PUSH    BX
         PUSH    CX
         PUSH    DX
         PUSH    DI
         MOV     AL,0B6h               ; Write timer mode register
         OUT     43h,AL
         MOV     DX,14h                ; Timer divisor =
         MOV     AX,4F38h              ;   1331000/Frequency
         DIV     DI
         OUT     42h,AL                ; Write timer 2 count low byte
         MOV     AL,AH
         OUT     42h,AL                ; Write timer 2 count high byte
         IN      AL,61h                ; Get current Port B setting
         MOV     AH,AL                 ;   and save it in AH
         OR      AL,3                  ; Turn speaker on
         OUT     61H,AL
PAUSE:   MOV     CX,2801               ; Set duration counter
SPKRON:  LOOP    SPKRON                ;
         DEC     BX                    ; Speaker on count expired?
         JNZ     PAUSE                 ; If not, keep speaker on
         MOV     AL,AH                 ; Otherwise, restore port
         OUT     61h,AL
         POP     DI                    ; Restore registers
         POP     DX
         POP     CX
         POP     BX
         POP     AX
         RET                           ; And return
BEEP     ENDP
;------- INITIALIZATION PART OF PROGRAM (REMOVED BY TSR) ---------------------
         ASSUME CS:CODE, DS:CODE, ES:CODE
INIT:    CALL   PARSE                  ; PARSE COMMAND ARGUMENTS FOR TIME
         CMP    AL,0                   ; CHECK IF SYNTAX ERROR (AL=1)
         JE     GETVEC                 ; TERMINATE IF ERROR
         MOV    AH,4Ch                 ; DOS FUNCTION TO TERMINATE
         INT    21h                    ;
;        GET TIMER TICK INTERRUPT VECTOR (INT 1Ch) FROM DOS
GETVEC:  MOV    AX,351Ch               ; CALL DOS FUNCTION 35h
         INT    21h                    ;   TO GET OLD VECTOR
                                       ; STORE IN "OLDINT"
         MOV    WORD PTR [OLDINT],BX   ; VECTOR OFFSET  RETURNED IN BX
         MOV    WORD PTR [OLDINT+2],ES ; VECTOR SEGMENT RETURNED IN ES
         CALL   DISPTIME               ; DISPLAY TIME ALARM IS SET FOR
;        RESET INTERRUPT VECTOR TO POINT TO THIS PROGRAM
         MOV    DX,OFFSET NEW_INT      ; PUT OUR OFFSET IN DX
         MOV    AX,251Ch               ; CALL DOS FUNCTION 25 HEX TO
         INT    21h                    ;    RESET TIMER INTERRUPT VECTOR
;        TERMINATE BUT STAY RESIDENT USING DOS INTERRUPT 27h
         MOV    DX,OFFSET INIT         ; SET AVAILIBLE MEMORY ADDRESS TO "INIT"
         INT    27h                    ; CALL DOS INTERUPT 27 HEX TO TERMINATE
;------- PARSE COMMAND LINE TO GET ALARM TIME -------------------------------
PARSE    PROC   NEAR
         ASSUME CS:CODE, DS:CODE, ES:CODE
         CMP    BYTE PTR DS:80h,00     ; SEE IF ANY ARGUMENTS
         JA     PARAM                  ; IF NO, PROMPT FOR IT
         MOV    DX,OFFSET PROMPT       ; DISPLAY PROMPT
         MOV    AH,09h
         INT    21h
         MOV    DX,7Fh                 ; PUT START OF INPUT BUFFER IN DX
         MOV    BYTE PTR DS:7Fh,128    ; LENGTH OF INPUT BUFFER
         MOV    AH,0Ah                 ; CALL DOS TO GET INPUT
         INT    21h
         MOV    DL,10                  ; CALL DOS TO DISPLAY LINE FEED
         MOV    AH,02
         INT    21h
PARAM:   CALL   UPCASE                 ; CHANGE ARGUMENTS TO UPPER CASE
         MOV    SI,81h                 ; SET POINTER TO COMMAND ARGUMENTS
AGAIN1:  LODSB                         ; GET NEXT CHAR
         CMP    AL,' '                 ; CHECK FOR SPACE
         JE     AGAIN1                 ; IF YES, GET ANOTHER
         CMP    AL,'0'                 ; IS IT A NUMBER?
         JB     ERROR1                 ; IF NO, SYNTAX ERROR
         CMP    AL,'9'                 ;
         JA     ERROR1                 ;
         CALL   GETBCD                 ; GET HOUR IN BCD
         CMP    BL,23h                 ; MAKE SURE IT'S VALID (<24)
         JA     ERROR2                 ; DISPLAY MESSAGE IF NOT
         MOV    HOUR,BL                ; STORE HOUR
         CMP    AL,':'                 ; CHECK FOR COLON
         JNE    PM                     ; IF NOT CHECK FOR PM
         LODSB                         ; GET NEXT CHAR
         CMP    AL,'0'                 ; IS IT A NUMBER?
         JB     ERROR1                 ; IF NO, SYNTAX ERROR
         CMP    AL,'9'                 ;
         JA     ERROR1                 ;
         CALL   GETBCD                 ; GET MINUTE IN BCD
         CMP    BL,59h                 ; MAKE SURE IT'S VALID
         JA     ERROR3                 ; DISPLAY MESSAGE IF NOT
         MOV    MINUTE,BL              ; STORE MINUTE
PM:      CMP    AL,' '                 ; CHECK FOR SPACE
         JNE    P                      ; IF NOT CHECK FOR 'PM'
         LODSB                         ;   OTHERWISE GET NEXT CHAR
         JMP    PM                     ;   AND CHECK AGAIN
P:       CMP    AL,'P'                 ; CHECK FOR 'P'
         JNE    OK                     ; END IF NOT
         LODSB                         ; OTHERWISE GET NEXT CHAR
         CMP    AL,'M'                 ; CHECK FOR 'M'
         JNE    OK                     ; END IF NOT
                                       ; OTHERWISE CHANGE TO 'PM'
         MOV    AL,HOUR                ; LOAD HOUR
         CMP    AL,00                  ; CHECK IF HOUR = 0
         JE     OK                     ; END IF IT IS ( DON'T CHANGE IT )
         CMP    AL,11h                 ; CHECK IF HOUR < 12
         JA     OK                     ; END IF NOT
         ADD    AL,12h                 ; OTHERWISE ADD 12
         DAA                           ; ADJUST FOR BCD ADDITION
         MOV    HOUR,AL                ; STORE NEW 24 HOUR FORMAT
OK:      MOV    AL,00                  ; CLEAR ERROR FLAG
         JMP    ENDSUB1                ; ALL THROUGH
;        SYNTAX ERROR : NO OR INCORRECT ALARM TIME WAS ENTERED, PRINT MESSAGE
;        AND RETURN ERROR CODE (AL=1)
ERROR1:  MOV    DX,OFFSET MSG1         ; PUT MESSAGE 1 ADDRESS IN DX
         JMP    SHORT PRNT             ; JUMP TO PRINT
ERROR2:  MOV    DX,OFFSET MSG2         ; PUT MESSAGE 2 ADDRESS IN DX
         JMP    SHORT PRNT             ; JUMP TO PRINT
ERROR3:  MOV    DX,OFFSET MSG3         ; PUT MESSAGE 3 ADDRESS IN DX
PRNT:    MOV    AH, 09h                ; CALL DOS PRINT STRING FUNCTION
         INT    21h                    ;
         MOV    AL,01                  ; AL=1 : SYNTAX ERROR
ENDSUB1: RET                           ; RETURN TO MAIN PROGRAM
PARSE    ENDP   ;------------------------------------------------------------
;------- CHANGE COMMAND LINE PARAMETERS TO UPPER CASE -----------------------
UPCASE   PROC   NEAR
         ASSUME CS:CODE, DS:CODE, ES:CODE
         MOV    CL,BYTE PTR CS:80h     ; LOAD LENGTH OF ARGUMENTS
         MOV    CH,00                  ;
         MOV    SI,0000                ; SET UP SOURCE INDEX
NEXT:    CMP    CX,SI                  ; IF SI=CX THEN ARGUMENT LIST HAS
         JE     ENDSUB2                ;    BEEN PROCESSED
         INC    SI                     ; INCREMENT INDEX
         MOV    AL,BYTE PTR [80h+SI]   ; LOAD NEXT CHAR
         CMP    AL,'a'                 ; IS IT A LOWER CASE LETTER
         JB     NEXT                   ; GET NEXT IF NOT
         CMP    AL,'z'                 ;
         JA     NEXT                   ;
         SUB    AL,20h                 ; CHANGE TO UPPER CASE
         MOV    BYTE PTR [80h+SI],AL   ; STORE NEW CHAR
         JMP    NEXT                   ; GET NEXT CHAR
ENDSUB2: RET                           ; ALL DONE, RETURN
UPCASE   ENDP   ;------------------------------------------------------------
;------- PROCEDURE TO GET NUMBER FROM COMMAND LINE & CONVERT IT TO BCD ------
GETBCD   PROC   NEAR
         XOR    BX,BX                  ; CLEAR BX TO HOLD RESULT
         SUB    AL,30h                 ; ELSE, SUBTRACT 30H
         MOV    BL,AL                  ; STORE IT IN BL
         LODSB                         ; GET NEXT CHAR
         CMP    AL,30h                 ; IS IT A NUMBER?
         JB     ENDSUB3                ; IF NO, RETURN
         CMP    AL,39h                 ;
         JA     ENDSUB3                ;
         SUB    AL,30h                 ; ELSE, SUBTRACT 30H
         MOV    CL,04                  ; SHIFT FIRST NUMERAL LEFT 4
         SHL    BL,CL
         OR     BL,AL                  ; OR IN SECOND NUMERAL
         LODSB                         ; GET NEXT CHAR AND QUIT
ENDSUB3: RET                           ; RETURN
GETBCD   ENDP   ;------------------------------------------------------------
;------- DISPLAY ALARM SET MESSAGE ------------------------------------------
DISPTIME PROC   NEAR
         MOV    AL,HOUR                ; LOAD HOUR (BCD)
         MOV    AH,AL                  ; STORE IN AH
         CMP    AL,12h                 ; CHECK IF PM
         JB     AM                     ; LEAVE MESSAGE AT AM
         MOV    BYTE PTR SETMSG[34],112 ; CHANGE AM TO PM
         CMP    AL,13h                 ; CHECK IF HOUR NEEDS ADJUSTING
         JB     AM                     ; NOT IF < 13 (1 pm)
         SUB    AL,12h                 ; CHANGE TO 12 HOUR TIME
         DAS                           ; ADJUST FOR BCD SUBTRACTION
         MOV    AH,AL                  ; STORE RESULT IN AH
AM:      MOV    CL,4                   ; LOAD COUNTER
         SHR    AL,CL                  ; GET MOST SIGNIFICANT DIGIT
         CMP    AL,0                   ; LEAVE MSD BLANK IF ZERO
         JE     NOTENS                 ;
         ADD    AL,30h                 ; CHANGE TO ASCII
         MOV    BYTE PTR SETMSG[28],AL ; STORE MSD
NOTENS:  MOV    AL,AH                  ; GET ADJUSTED HOUR FROM AH
         AND    AL,0Fh                 ; MASK LEAST SIGNIFICANT DIGIT
         ADD    AL,30h                 ; CHANGE TO ASCII
         MOV    BYTE PTR SETMSG[29],AL ; STORE LSD
         MOV    AL,MINUTE              ; LOAD MINUTE (BCD)
         MOV    CL,4                   ; LOAD COUNTER
         SHR    AL,CL                  ; GET MSD
         ADD    AL,30h                 ; CHANGE TO ASCII
         MOV    BYTE PTR SETMSG[31],AL ; NO NEED TO CHECK FOR ZERO
         MOV    AL,MINUTE              ; RELOAD MINUTE
         AND    AL,0Fh                 ; MASK LSD
         ADD    AL,30h                 ; CHANGE TO ASCII
         MOV    BYTE PTR SETMSG[32],AL ; STORE LSD
         MOV    DX,OFFSET SETMSG       ; DISPLAY ALARM SET TIME
         MOV    AH, 09h                ; CALL DOS PRINT STRING FUNCTION
         INT    21h                    ;
         RET
DISPTIME ENDP   ;------------------------------------------------------------
MSG1:    DB 7,13,10,'The correct syntax is:  ALARM hh[:mm] [PM]',13,10,36
MSG2:    DB 7,13,10,'The hour can be 0 through 23',13,10,36
MSG3:    DB 7,13,10,'The minute can be 0 through 59',13,10,36
SETMSG:  DB   13,10,'An alarm has been set for  0:00 am',13,10,36
PROMPT:  DB   13,10,'Enter alarm time ( hh[:mm] [PM] ): ',36
CODE     ENDS
         END  START


Mickey
Ametuar
Posts: 115

It is a cool program under DOS .
I have made a lot od ASM stuff under DOS if anybody is interested I can post hem.
But does anyone use DOS nowadays?
C0D3Z3R0
Pro
Posts: 166

yeah plz post them, always good to see what people have made
Mickey
Ametuar
Posts: 115

Quoted from C0D3Z3R0
yeah plz post them, always good to see what people have made

Okie dokie. I'm gonna post them.