Parsi Coders
سورس کد ساعت (اسمبلی) - نسخه قابل چاپ

+- Parsi Coders (http://parsicoders.com)
+-- انجمن: Software Development Programming (http://parsicoders.com/forumdisplay.php?fid=37)
+--- انجمن: Assembly (http://parsicoders.com/forumdisplay.php?fid=38)
+--- موضوع: سورس کد ساعت (اسمبلی) (/showthread.php?tid=2442)



سورس کد ساعت (اسمبلی) - Amin_Mansouri - 06-16-2012

کد:
ClockCGROUP  GROUP VECTOR,CODESEG
VECTOR  SEGMENT AT 0H
  DB    6CH DUP(?)     ;FILLER
TIME_LO  DW    ?      ;DOS TIME
TIME_HI  DW    ?      ;DOS TIME
VEC_IP  DW       ;CLOCK UPDATE VECTOR IP
VEC_CS  DW       ;CLOCK UPDATE VECTOR CS
VECTOR  ENDSCODESEG  SEGMENT PARA
  ASSUME CS:CODESEG,DS:CGROUP
  ORG   100H
CLK  PROC  FAR
  JMP   SETUP      ;ATTACH TO DOS
INTRPT  LABEL DWORD
INT_IP  DW    0      ;OLD UPDATE VECTOR IP
INT_CS  DW    0      ;OLD UPDATE VECROR CS
TICKS  DW    0      ;TICK COUNTER
SCR_OFF  DB    0,0      ;SCREEN OFFSET IN BUFFER
CRT_PORT DW    0      ;SCREEN STATUS PORT
flag  db    0
TIME  DB    8 DUP(':',0BH)       ;TIME SAVE AREA
CLK_INT  LABEL NEAR
  PUSH  AX      ;SAVE REGISTERS
  PUSH  CX
  PUSH  DI
  PUSH  SI
  PUSH  DS
  PUSH  ES
  PUSHF       ; AND FLAGS
  CALL  CS:[INTRPT]     ;DO OLD UPDATE INTERRUPT
  MOV   CX,0040H      ;GET SEGMENT OF DOS TABLE
  MOV   DS,CX      ;PUT IN DS
  MOV   CX,CS:TICKS     ;GET TICK COUNT
  INC   CX      ;INCREMENT IT
  CMP   CX,20     ;01F4H        ;HAS A MINUTE GONE BY?
  JB    NO_MINUTE     ;NO, MOVE ON
  CALL  UPDATE      ;YES, UPDATE CLOCK AND
  MOV   CX,0      ; RESET TICK COUNTER
NO_MINUTE:
  MOV   CS:TICKS,CX     ;SAVE UPDATED TICK COUNT
  MOV   CX,0B000H     ;GET VIDEO SEGMENT
  MOV   ES,CX      ;PUT IN ES
  MOV   DX,CS:CRT_PORT     ;GET CRT STATUS PORT ADDR
  MOV   DI,WORD PTR CS:SCR_OFF  ;GET SCREEN BUFFER OFFSET
  LEA   SI,CS:TIME     ;GET DOS TIME
  MOV   CX,16      ;SET UP TO MOVE 10 BYTES
  CLI       ;DISABLE OTHER INTERRUPTS
WAIT1:  IN    AL,DX      ;READ CRT STATUS
  TEST  AL,1      ;CHECK FOR VERTICAL RETRACE
  JNZ   WAIT1      ;WAIT FOR RETRACE LOW
  MOV   AH,CS:[SI]     ;GET FIRST BYTE TO MOVE
WAIT2:  IN    AL,DX      ;GET CRT STATUS
  TEST  AL,1      ;CHECK FOR VERTICAL RETRACE
  JZ    WAIT2      ;WAIT FOR RETRACE HIGH
  MOV   ES:[DI],AH     ;MOVE BYTE TO SCREEN
  INC   DI      ;INCREMENT INDEX
  INC   SI
  LOOP  WAIT1      ;MOVE NEXT BYTE
  STI       ;ENABLE INTERRUPTS
  POP   ES      ;RESTORE REGISTERS
  POP   DS
  POP   SI
  POP   DI
  POP   CX
  POP   AX
  IRET       ;RETURN FROM INTERRUPT
CLK  ENDP
UPDATE  PROC  NEAR
  PUSH  AX      ;SAVE REGISTERS
  PUSH  BX
  PUSH  CX
  PUSH  DX
  PUSH  DS
  MOV   AX,0040H      ;GET ADDRESS OF DOS TABLE
  MOV   DS,AX      ;PUT IN DS
  MOV   AX,TIME_HI     ;GET HIGH BYTE OF DOS TIME
  mov   flag,0      ;am flag
HOUR:  CMP   AX,0CH      ;CONVERT TO HOURS
  JLE   H1
  mov   flag,1      ;set to pm
  SUB   AX,0CH
  JMP   HOUR
H1:  AAM       ;CONVERT TO ASCII
  ADD   AX,3030H
  LEA   BX,CS:TIME     ;GET ADDRESS OF TIME AREA
  MOV   CS:[BX],AH     ;SAVE HOURS FIRST DIGIT
  MOV   CS:[BX+2],AL     ;SAVE HOURS SECOND DIGIT
  MOV   AX,TIME_LO     ;GET DOS TIME LOW BYTE
  MOV   CX,8H      ;CONVERT TO MINUTES
  SHR   AX,CL
  MOV   DX,3CH
  MUL   DL
  SHR   AX,CL
  AAM       ;CONVERT TO ASCII
  ADD   AX,3030H
  MOV   CS:[BX+6],AH     ;SAVE MINUTES FIRST DIGIT
  MOV   CS:[BX+8],AL     ;SAVE MINUTES SECOND DIGIT
  mov   byte ptr cs:[bx+12],'a'
  cmp   flag,0      ;is it am?
  jz    goahead
  mov   byte ptr cs:[bx+12],'p'
goahead:
  mov   byte ptr cs:[bx+14],'m'
  POP   DS      ;RESTORE REGISTERS
  POP   DX
  POP   CX
  POP   BX
  POP   AX
  RET
UPDATE  ENDP
SETUP:  MOV   AX,0      ;GET ADDRESS OF VECTOR TABLE
  MOV   DS,AX      ;PUT IN DS
  CLI       ;DISABLE FURTHER INTERRUPTS
  MOV   AX,[VEC_IP]     ;GET ADDRESS OF OLD UPDATE IP
  MOV   CS:[INT_IP],AX     ;SAVE IT
  MOV   AX,[VEC_CS]     ;GET ADDRESS OF OLD UPDATE CS
  MOV   CS:[INT_CS],AX     ;SAVE IT
  MOV   VEC_IP,OFFSET CLK_INT ;PUT ADDRESS OF CLK IN VECTOR IP
  MOV   VEC_CS,CS     ;PUT CS OF CLK IN VECTOR CS
  STI       ;ENABLE INTERRUPTS
  MOV   AH,0FH      ;READ VIDEO STATUS
  INT   10H
  SUB   AH,8      ;SUBTRACT 8 CHAR TIME FROM NCOLS
  SHL   AH,1      ;MULTIPLY BY 2 FOR ATTRIBUTE
  MOV   CS:SCR_OFF,AH     ;SAVE SCREEN TIME LOCATION
  MOV   WORD PTR CS:CRT_PORT,03BAH  ;SAVE MONO STATUS PORT ADDR
  TEST  AL,4      ;CHECK FOR COLOR MONITOR
  JNZ   MONO      ;IF MONO, MOVE ON
  ADD   WORD PTR CS:SCR_OFF,8000H   ;ADD COLOR OFFSET TO TIME OFFSET
  MOV   WORD PTR CS:CRT_PORT,03DAH  ;SAVE COLOR STATUS PORT ADDR
MONO:  CALL  UPDATE      ;DO FIRST UPDATE & PRINT TIME
  MOV   DX,OFFSET SETUP     ;GET END ADDRESS OF NEW INTERRUPT
  INT   27H      ;TERMINATE AND REMAIN RESIDENT
  DB    117 DUP(0)     ;FILLER
CODESEG  ENDS
  END   CLK



RE: سورس کد ساعت (اسمبلی) - yaldama15 - 07-18-2017

بسیار عالی مرسی