Image Map Image Map
Results 1 to 10 of 10

Thread: Astclock y2k fix!

  1. #1

    Default ASTCLOCK.COM Y2K Fix!


    I just bought my first IBM PC two weeks ago and got it all working, except the ASTCLOCK Y2K issue was really bothering me, even though it was only "visual" (see I have decided to work on the "forever /99" year issue with ASTCLOCK.COM. This is my first disassembly reverse engineering project so feel free to share your comments and/or concerns.


    I included the patched V?1.0? (1982, no version number) and V1.21 in the attachments. If you do not have a way to transfer data into your PC, you can patch it "by hand" using DEBUG and the instructions below.

    PATCHED V1.0 (1982, no version number)

    PATCHED V1.21 (newest)

    WARNING: This procedure was written for ASTCLOCK.COM from 1982. If you suspect you might be running a different version, see Notes below the DEBUG. Make sure to backup your ASTCLOCK.COM before attempting this. If you write over some other piece of code, it might cause the program not to function properly. Simply, COPY ASTCLOCK.COM ASTCLOCK.BAK.

    Navigate to where your ASTCLOCK.COM is and run

    1088:017A  B0.2C  63.64
    Note: After you enter -E017A, you need to enter 2C<spacebar>64<return>

    Note: You can check the bytes of the ASTCLOCK.COM by using -D0100 option in DEBUG. If you do not see the bytes B0 63 at offset 017A, you might have a different version of ASTCLOCK.COM. Look for these two bytes and replace them with 2C 64.

    AST programmer(s) programmed the ASTCLOCK.COM to force anything higher than 99 (3 digits long) not to show in the print out of the program. This might somewhat make sense because it was 1982 and there were only two places for two decimal digits. Internally, the RTC onboard AST SIXPAK PLUS works with Y2K. ASTCLOCK.COM also does system calls to DOS with Y2K date correctly. The only issue is the subroutine which coverts the time from the chip into a two digit print out.

    I went through the code, disassembled it, and found the crucial place where the date gets checked against 99. AST decided to save the year in the RTC chips memory as a one byte of the year minus 80. To make sure the year fits in a byte, 1996 becomes 96-80=16 and 2018 becomes 118("rolls over 99")-80=38.

    The way the code maps integer values to digits is as follows. Assume our year is 1996. The value stored in the RTC chip is therefore 16. The code adds 80. When it gets to the print out subroutine, the code checks if it's greater than 99 and then the value 96 gets divided by ten using the DIV instruction. The result of the division is stored in register AL and the remainder is stored in register AH. 96/10 = 9 remainder 6. Then the code adds ASCII offset for character 0 to these numbers and the numbers are now ASCII numbers. If we skipped the check for 99 and our year is 118 (2018), the following will happen. 118/10 = 11 remainder 8. So 11 gets added with ASCII offset for '0' to obtain the first character of the year and the 8 gets added with ASCII offset for '0' to obtain the second. The results in the following print out ";8". We crossed the ASCII '9' and went to ';' since the value is greater than 99. Therefore, it is necessary to subtract 100 from the value which will give us 118-100 = 18 and now 18/10 = 1 remainder 8 so the resulting characters in the print out are "18". If you are interested in more, see the attached disassembly.

    The original line of code at offset 0x017A:

    B0 63 ---> MOV AL, 63H ; force value to 99 if greater than 99

    can be now replaced with

    2C 64 ---> SUB AL, 64H ; subtract 100 from the value if greater than 99

    This fixes the ASTCLOCK.COM Y2K issue.


    Last edited by jakeh12; March 9th, 2018 at 03:14 PM.

  2. #2
    Join Date
    Jan 2012
    Connecticut, USA


    this is great!

  3. #3
    Join Date
    Jan 2013
    Marietta, GA


    Nice work. I had just been redirecting the output to NUL, but it would get confusing when running it manually. It would display 99 but actually set the DOS clock correctly.

    I believe these were the last version:
    And it still had that issue. But I haven't compared the different versions off hand.

  4. #4


    Thank you for your feedback! I included patched executables of V1.0 (1982, no version number) and V1.21 in the original post if you do not want to patch "by hand".

    This is the change in 1.21:

    FROM: 02C6: B0 63 ---> MOV AL, 63H
    TO: 02C6: 2C 64 ---> SUB AL, 64H

  5. #5


    Slick. I like your coding style. Thanks for the fix!

  6. #6


    This is the change in 1.10:

    From: 0237: B0 63 ---> MOV AL, 63H
    To: 0237: 2C 64 ---> SUB AL, 64H

  7. #7


    Quote Originally Posted by p.giaquinto View Post
    This is the change in 1.10:

    From: 0237: B0 63 ---> MOV AL, 63H
    To: 0237: 2C 64 ---> SUB AL, 64H
    I write a patch to show date in dd/mm/yyyy format in the printout of ASTCLOCK.COM 1.10 Version (1984)
    NOTE: it will works until year 2099, but it should be enough for me

     06E4  BA 71 03     MOV  DX,0371    ;moved in 075F because I need more space
     06E4  EB 58        JMP  073E       ;jump out of code, where is my patch
     06E6  90           NOP             ; that add 38 bytes to the program
    then add:
     073E  A1 81 03     MOV  AX,[0381]  ;get <month> value from 'mm/dd' format,
     0741  87 06 84 03  XCHG AX,[0384]  ; exchange it with <day> value that then
     0745  A3 81 03     MOV  [0381],AX  ; put in 1st place to have 'dd/mm' format
     0748  A1 87 03     MOV  AX,[0387]  ;move forward the two digits of <year>
     074B  A3 89 03     MOV  [0389],AX  ; to have more space for 'yyyy' format,
     074E  B8 32 30     MOV  AX,3032    ; then add "20" in the first two places
     0751  A3 87 03     MOV  [0387],AX  ; to have 'dd/mm/20yy' format as required
     0754  B8 20 0D     MOV  AX,0D20    ;need to overwrite a useless "/$" with
     0757  A3 8B 03     MOV  [038B],AX  ; a space and a CR code, then
     075A  B0 0A        MOV  AL,0A      ; overwrite a useless " " with a LF.
     075C  A2 6D 03     MOV  [036D],AL  ; I like one more blank after the printout
     075F  BA 71 03     MOV  DX,0371    ;now execute the moved instruction, then
     0762  EB 83        JMP  06E7       ; return to the original code

  8. #8


    Great work and writeup. Thanks!

  9. #9


    you are the man! That's bugged me for years! Many thanks!

  10. #10
    Join Date
    Jul 2010
    Silicon Forest, Oregon, USA


    Thanks! Works perfectly on my Compaq Portable


Tags for this Thread


Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts