home *** CD-ROM | disk | FTP | other *** search
/ CD Actual 15 / CDACTUAL15.iso / cdactual / program / asm / OKTIMDAT.ZIP / DBD.ASM < prev    next >
Encoding:
Assembly Source File  |  1988-12-07  |  16.8 KB  |  340 lines

  1.         DOSSEG
  2.         .MODEL  SMALL
  3.         .STACK  100H
  4.         .DATA
  5. Program DB  13,10,"Days Between Dates calculation",13,10
  6. Version DB  "1.11 (c) 1988 by Tom Gilbert's Heart&Mind",13,10
  7. Usage   DB  "ONLY NON-Commercial useage authorized",13,10,10
  8. Syntax  DB  "Syntax >DBD mm/dd/yyyy[bc] [MM/DD/YYYY[BC]]",13,10
  9. Limits  DB  "Limits from 01/01/4004BC to 12/31/9999",7,7,13,10,0
  10. Report  DB  13,10,10 DUP(' ')
  11. DateS1  DB  12 DUP(' ')," is "
  12. DBDStr  DB  12 DUP(' ')," days "
  13. BeOrAf  DB  "after",12 DUP(' ')
  14. DateS2  DB  "  /  /",7 DUP(' '),13,10,0
  15. Before  DB  "before"
  16. SameAs  DB  "the same date as"
  17. DayTbl  DB  "   Sunday","   Monday","  Tuesday","Wednesday"
  18.         DB  " Thursday","   Friday"," Saturday"
  19. Y1Huns  DB  ?
  20. Y1Ones  DB  ?                           ; Year
  21. Mon1No  DB  ?                           ; Month
  22. Day1No  DB  ?                           ; DayOfMonth
  23. Y2Huns  DB  ?                           ; Array
  24. Y2Ones  DB  ?                           ; for 2
  25. Mon2No  DB  ?                           ; Dates
  26. Day2No  DB  ?
  27. MaxDay  DB  0,31,29,31,30,31,30,31,31,30,31,30,31
  28. PSP     DW  ?;JanFebMarAprMayJunJulAugSepOctNovDec
  29. MonDay  DW  0,31,59,90,120,151,181,212,243,273,304,334
  30. D1Days  DD  ?
  31. D2Days  DD  ?
  32.         .CODE
  33. EXTRN   ArgC:Proc,ArgV:Proc,B2Dec:Proc
  34. Main    Proc    Far
  35.         Mov     AX,@data                ; Make Data
  36.         Mov     DS,AX                   ; Addressable
  37.         Mov     PSP,ES                  ; Preserve PSP
  38.         Mov     ES,AX                   ; for later use
  39.         Mov     AH,2Ah                  ; Get Current
  40.         Int     21h                     ; DOS Date and
  41.         Mov     BX,OFFSET DateS2        ; Position to
  42.         Mov     AL,DH                   ; Store ASCII
  43.         Call    B2Dec                   ; Decimal Month
  44.         Add     BX,3                    ; Position to
  45.         Mov     AL,DL                   ; Store ASCII
  46.         Call    B2Dec                   ; Decimal Day of Month
  47.         Add     BX,3                    ; Position to Store
  48.         Mov     AX,100                  ; Hundreds
  49.         Xchg    AX,CX                   ; and the
  50.         Xor     DX,DX                   ; Remaining
  51.         Div     CX                      ; Years
  52.         Call    B2Dec                   ; Store Century and
  53.         Add     BX,2                    ; Position to Store
  54.         Mov     AL,DL                   ; Remaining Years
  55.         Call    B2Dec                   ; Decimal Digits
  56.         Mov     ES,PSP                  ; Restore PSP to
  57.         Mov     BX,80h                  ; Get Command Line
  58.         Call    ArgC                    ; Argument Count
  59.         Dec     AX                      ; If Any Dates
  60.         Jnz     OneTwo                  ; Then How Many?
  61.         Jmp     HelpM                   ; Else Give Help
  62. OneTwo: Cmp     AX,1                    ; If Only One
  63.         Mov     AX,10                   ; Then Use 10
  64.         Jz      S2Date                  ; Byte DOS Date 2
  65.         Mov     DI,OFFSET DateS2        ; Else Get Date 2
  66.         Mov     AX,2                    ; from Command
  67.         Call    GetArg                  ; Line Argument
  68. S2Date: Mov     SI,OFFSET DateS2        ; Set Source
  69.         Mov     CX,AX                   ; Date length
  70.         Push    DS                      ; and Extra
  71.         Pop     ES                      ; Segment for
  72.         Mov     DI,OFFSET Mon2No        ; Destination
  73.         Call    ValDate                 ; If Valid Date
  74.         Jz      Valid2                  ; Then Continue
  75.         Jmp     HelpM                   ; Else Give Help
  76. Valid2: Mov     DI,Offset DateS2        ; If Date
  77.         Mov     CX,12                   ; string
  78.         Mov     AL,"B"                  ; has
  79.         RepNE   ScaSB                   ; "BC"
  80.         Je      DDate2                  ; Then Do Date 2
  81.         Mov     Word Ptr D2Days[2],16h  ; Else Initialize
  82.         Mov     Word Ptr D2Days[0],509Eh; Days AnoDomenei
  83. DDate2: Mov     DI,OFFSET D2Days        ; Set Destination
  84.         Mov     BP,OFFSET DateS2-2      ; Day and DayName
  85.         Mov     SI,OFFSET Y2Huns        ; and Source Pointers
  86.         Call    DoDays                  ; Get Days and DayName
  87.         Mov     ES,PSP                  ; Set ES to PSP
  88.         Mov     AX,1                    ; to Call 4 Date 1
  89.         Mov     DI,OFFSET DateS1        ; from Command
  90.         Call    GetArg                  ; Line Argument
  91.         Mov     SI,OFFSET DateS1        ; Set Source
  92.         Mov     CX,AX                   ; Date length
  93.         Push    DS                      ; and Extra
  94.         Pop     ES                      ; Segment for
  95.         Mov     DI,OFFSET Mon1No        ; Destination
  96.         Call    ValDate                 ; If Valid Date
  97.         Jz      Valid1                  ; Then Continue
  98.         Jmp     HelpM                   ; Else Give Help
  99. Valid1: Mov     DI,Offset DateS1        ; If Date
  100.         Mov     CX,12                   ; string
  101.         Mov     AL,"B"                  ; has
  102.         RepNE   ScaSB                   ; "BC"
  103.         Je      DDate1                  ; Then Do Date 1
  104.         Mov     Word Ptr D1Days[2],16h  ; Else Initialize
  105.         Mov     Word Ptr D1Days[0],509Eh; Days AnoDomenei
  106. DDate1: Mov     DI,OFFSET D1Days        ; Set Destination
  107.         Mov     BP,OFFSET DateS1-2      ; Day and DayName
  108.         Mov     SI,OFFSET Y1Huns        ; and Source Pointers
  109.         Call    DoDays                  ; Get Days and DayName
  110.         Mov     AX,Word Ptr D1Days[0]   ; If First Date
  111.         Mov     DX,Word Ptr D1Days[2]   ; MSW Less Than
  112.         Sub     DX,Word Ptr D2Days[2]   ; Second Date
  113.         Jb      BefStr                  ; Then is "before"
  114.         Sub     AX,Word Ptr D2Days[0]   ; Else If LSW Less
  115.         Jb      DecMSW                  ; Then Borrow
  116.         Jnz     DoTot                   ; Else "after" Ok
  117.         Mov     SI,OFFSET SameAs        ; Else "the same
  118.         Mov     DI,OFFSET BeOrAf-11     ;       date as"
  119.         Mov     CX,16                   ; String to move
  120.         Rep     MovSB                   ; and exit with
  121.         Jmp     SHORT ReptM             ; NO Days Between
  122. DecMSW: Sub     DX,1                    ; If Borrow is Ok
  123.         Jnc     DoTot                   ; Then "after" Ok
  124. BefStr: Mov     SI,OFFSET Before        ; Move "before" to
  125.         Mov     DI,OFFSET BeOrAf        ; replace "after "
  126.         Mov     CX,6                    ; six bytes
  127.         Rep     MovSB
  128.         Mov     AX,Word Ptr D2Days[0]   ; Get Larger
  129.         Mov     DX,Word Ptr D2Days[2]   ; Days in DX:AX
  130.         Sub     AX,Word Ptr D1Days[0]   ; Subtract the
  131.         Sbb     DX,Word Ptr D1Days[2]   ; Lesser for Total
  132. DoTot:  Mov     CX,10                   ; Put Decimal ASCII
  133.         Mov     BP,9                    ; 9 Place String in
  134.         Mov     DI,OFFSET DBDStr        ; Display Area
  135. DDLoop: Call    Divide                  ; Divide by 10
  136.         Add     BL,"0"                  ; Make Result
  137.         Mov     ES:[DI+BP],BL           ; ASCII and Store
  138.         Dec     BP                      ; Move Index Left
  139.         Cmp     BP,6                    ; After Each
  140.         Jnz     CkBP2                   ; Three Digits
  141. CkAX0:  Or      AX,DX                   ; Unless
  142.         Jz      ReptM                   ; Done -
  143.         Mov     Byte Ptr ES:[DI+BP],"," ; Comma
  144.         Dec     BP                      ; Count and
  145.         Jmp     SHORT DDLoop            ; Continue
  146. CkBP2:  Cmp     BP,2                    ; If nnn,nnn
  147.         Jz      CkAX0                   ; Then Comma/Done?
  148.         Or      AX,DX                   ; Else Continue
  149.         Jnz     DDLoop                  ; Until 0 Remains
  150. ReptM:  Mov     SI,OFFSET Report        ; Show DBD Report
  151.         Jz      BytL                    ; Unless Error and
  152. HelpM:  Mov     SI,OFFSET Program       ; Then Give Help
  153. BytL:   LodSB                           ; If NOT
  154.         Cmp     AL," "                  ; Space
  155.         Jnz     Ck40                    ; Then Done?
  156.         Cmp     AL,DL                   ; Else If Double
  157.         Jz      BytL                    ; Then Skip
  158. Ck40:   Or      AL,AL                   ; Else If 0
  159.         Jz      Exit                    ; Then Done
  160.         Mov     DL,AL                   ; Else Send
  161.         Mov     AH,2                    ; Byte to
  162.         Int     21h                     ; Console
  163.         Jmp     SHORT BytL              ; Until 0
  164. Exit:   Mov     AH,4Ch                  ; Exit to
  165.         Int     21h                     ; MS-DOS
  166. Main    EndP
  167.  
  168. GetArg  Proc
  169.         Mov     BX,80h                  ; Get Command
  170.         Call    ArgV                    ; Line Argument
  171.         Push    DS                      ; for Transfer
  172.         Push    ES                      ; into ES:DI
  173.         Pop     DS                      ; from DS:SI
  174.         Pop     ES
  175.         Mov     SI,BX
  176.         Mov     CX,AX                   ; Set Number of
  177.         Rep     MovSB                   ; Bytes to Move
  178.         Mov     CX,10                   ; If All 10
  179.         Sub     CX,AX                   ; Places Used
  180.         Jcxz    EndSpc                  ; Then NO Spaces
  181.         Push    AX                      ; Are Necessary
  182.         Mov     AL," "                  ; Else Store
  183.         Rep     StoSB                   ; Spaces to Fill-
  184.         Pop     AX                      ; Out Date String
  185. EndSpc: Push    DS                      ; Swap
  186.         Push    ES                      ; Segments
  187.         Pop     DS                      ; Back to
  188.         Pop     ES                      ; Original
  189.         Ret
  190. GetArg  EndP
  191.  
  192. Divide  Proc Near
  193.         Push AX                 ;Preserve Dividend LSW
  194.         Mov  AX,DX              ;While Process MSW
  195.         Xor  DX,DX              ;Zero Divide Extension
  196.         Div  CX                 ;Divide MSW and
  197.         Mov  BX,AX              ;Save Remainder
  198.         Pop  AX                 ;Restore LSW and
  199.         Div  CX                 ;Get its Remainder
  200.         Xchg BX,DX              ;Restore and Return
  201.         Ret                     ;DX:AX remainder & BX Result
  202. Divide  EndP
  203.  
  204. ValDate Proc
  205.         Mov     BP,10                   ; Set Decimal Base
  206. NewNum: Xor     BX,BX                   ; Zero Accumulator
  207. GVNNLp: LodSB                           ; If Byte
  208.         Sub     AL,"0"                  ; is NOT
  209.         Jc      EndNum                  ; Decimal
  210.         Cmp     AL,10                   ; Digit
  211.         Jnc     EndNum                  ; Then End Number
  212.         Sub     AH,AH                   ; Else Calculate
  213.         Xchg    AX,BX                   ; accumulated
  214.         Mul     BP                      ; places plus
  215.         Add     BX,AX                   ; new value
  216.         Loop    GVNNLp                  ; Until AD
  217. EndNum: Jcxz    StorYr                  ; Date Ends
  218.         Mov     AH,"0"                  ; Or Until
  219.         Add     AH,AL                   ; High and
  220.         Mov     AL,[SI]                 ; Low Byte
  221.         And     AX,5F5Fh                ; UpperCase
  222.         Cmp     AX,"BC"                 ; is "BC"
  223.         Je      BC_Era                  ; Then BC Ends
  224.         Mov     AL,BL                   ; Else Store
  225.         StoSB                           ; Month or Day
  226.         Loop    NewNum                  ; Loop Until End
  227.         Cmp     CX,1                    ; Or an Error
  228.         Jmp     SHORT ExitVD            ; is Detected
  229. BC_Era: Cmp     BX,4004                 ; If > 4004 BC
  230.         Ja      ExitVD                  ; Then Error Exit
  231.         Neg     BX                      ; Else Make BC
  232.         Add     BX,4005                 ; Reciprocal
  233.         And     Word Ptr [SI-1],5F5Fh   ; Insure "yyyyBC"
  234. StorYr: Mov     AX,BX                   ; Convert Years
  235.         Mov     CX,100                  ; into Hundreds
  236.         Xor     DX,DX                   ; and Remaining
  237.         Div     CX                      ; years and
  238.         Mov     [DI-4],AL               ; Store Century
  239.         Mov     [DI-3],DL               ; and Remainder
  240.         Mov     DX,[DI-2]               ; If Month
  241.         Cmp     DL,1                    ; Is < 1
  242.         Jc      ExitVD                  ; Or If Day
  243.         Cmp     DH,1                    ; of Month < 1
  244.         Jc      ExitVD                  ; Or If Month
  245.         Cmp     DL,12                   ; Is > 12
  246.         Ja      ExitVD                  ; Then Error Exit
  247.         Mov     AX,BX                   ; Else Get Year
  248.         Push    BX                      ; Preserve Year
  249.         Mov     CX,4                    ;  and MOD 4 to
  250.         Xor     DX,DX                   ; Check 4 Leap
  251.         Call    Divide                  ; If Year MOD 4
  252.         Or      BX,BX                   ; is Zero for
  253.         Mov     AX,0                    ; a Leap Year
  254.         Jz      LeapY                   ; Or If Month
  255.         Cmp     Byte Ptr [DI-2],2       ; NOT February
  256.         Jnz     LeapY                   ; Then Table Ok
  257.         Dec     AX                      ; Else Feb = 28
  258. LeapY:  Mov     BL,[DI-2]               ; Set Pointer to
  259.         Xor     BH,BH                   ; MaxDay Offset
  260.         Add     AL,MaxDay[BX]           ; Get MAXimum
  261.         Pop     BX                      ; Restore Year
  262.         Cmp     [DI-1],AL               ; If DayOfMonth > MAX
  263.         Ja      ExitVD                  ; Then Error Exit
  264.         Xor     AX,AX                   ; Else ZR Flag Ok
  265. ExitVD: Ret
  266. ValDate EndP
  267.  
  268. DoDays  Proc                            ; Preserve DayName
  269.         Push    BP                      ; Storage Pointer
  270.         Dec     BX                      ; Year - 1 =
  271.         Mov     BP,BX                   ; Years Past
  272.         Mov     AX,365                  ; Days/Year
  273.         Xchg    AX,BX                   ; Calculate and
  274.         Mul     BX                      ; Store Days
  275.         Add     Word Ptr [DI+0],AX      ; Except for
  276.         Adc     Word Ptr [DI+2],DX      ; Leap Years
  277.         Cmp     Byte Ptr [SI+2],3       ; If Month < 3
  278.         Jc      AdDays                  ; Then Don't
  279.         Mov     AX,BP                   ; Else Restore
  280.         Inc     AX                      ; Current Year
  281.         Mov     CX,4                    ; Check MOD 4
  282.         Call    Divide                  ; If Year MOD 4
  283.         Or      BX,BX                   ; is NOT 0
  284.         Jnz     AdDays                  ; Then Add Days
  285.         Inc     BP                      ; Else Inc Year
  286. AdDays: Mov     BL,[SI+2]               ; Get mm/dd
  287.         Xor     BH,BH                   ; Month Word
  288.         Shl     BX,1                    ; Pointer to
  289.         Mov     AX,MonDay[BX-2]         ; Days to Month
  290.         Add     AL,[SI+3]               ; + Day of Month
  291.         Adc     AH,0                    ; = Days in Year
  292.         Add     Word Ptr [DI+0],AX      ; Total the
  293.         Adc     Word Ptr [DI+2],0       ; Days to Date
  294.         Mov     AX,BP                   ; Get Year
  295.         Mov     BX,4                    ; For Each
  296.         Xor     DX,DX                   ; 4 Years
  297.         Div     BX                      ; Add a
  298.         Add     Word Ptr [DI+0],AX      ; Leap
  299.         Adc     Word Ptr [DI+0],0       ; Year
  300.         Mov     AX,BP                   ; Except
  301.         Mov     BX,100                  ; Years
  302.         Xor     DX,DX                   ; in even
  303.         Div     BX                      ; Centuries
  304.         Sub     Word Ptr [DI+0],AX      ; Are NOT
  305.         Sbb     Word Ptr [DI+2],0       ; Leap Years
  306.         Mov     AX,BP                   ; Unless Even
  307.         Mov     BX,400                  ; 4th Century
  308.         Xor     DX,DX
  309.         Div     BX
  310.         Add     Word Ptr [DI+0],AX
  311.         Adc     Word Ptr [DI+0],0
  312.         Mov     AX,BP                   ; Except
  313.         Mov     BX,4000                 ; Years
  314.         Xor     DX,DX                   ; in even
  315.         Div     BX                      ; 4000 years
  316.         Sub     Word Ptr [DI+0],AX      ; Are NOT
  317.         Sbb     Word Ptr [DI+2],0       ; Leap Years
  318.         Mov     AX,Word Ptr [DI+0]      ; Get 32 bit
  319.         Mov     DX,Word Ptr [DI+2]      ; Days for Date
  320.         Cmp     DX,16h                  ; If < for 4004
  321.         Jc      Ok4Day                  ; Then Ready
  322.         Sub     DX,16h                  ; Else Subtract
  323.         Sub     AX,509Eh                ; days for 4004
  324.         Sbb     DX,0
  325. Ok4Day: Mov     CX,7                    ; Calculate
  326.         Call    Divide                  ; Day Code
  327.         Mov     AX,BX                   ; for Day
  328.         Mov     CX,9                    ; Name
  329.         Mov     SI,OFFSET DayTbl-1      ; Table
  330.         Std                             ; Backward
  331.         Pop     DI                      ; Transfer
  332.         Add     SI,CX                   ; from end
  333.         Mul     CL                      ; of Name
  334.         Add     SI,AX                   ; in Table
  335.         Rep     MovSB                   ; to DayName
  336.         Cld                             ; Destination
  337.         Ret
  338. DoDays  EndP
  339.         End     Main
  340.