Hi,
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 http://www.vcfed.org/forum/showthread.php?36527-AST-clock-software-question). 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.
1982 ASTCLOCK.COM AST SIXPAK PLUS Y2K ISSUE PATCH
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)
View attachment ASTCLOCK_V100-1982.zip
PATCHED V1.21 (newest)
View attachment ASTCLOCK_V121.zip
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
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.
Explanation:
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.
Disassembly:
View attachment ASTCLOCK.TXT
Screenshot:
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 http://www.vcfed.org/forum/showthread.php?36527-AST-clock-software-question). 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.
1982 ASTCLOCK.COM AST SIXPAK PLUS Y2K ISSUE PATCH
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)
View attachment ASTCLOCK_V100-1982.zip
PATCHED V1.21 (newest)
View attachment ASTCLOCK_V121.zip
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
Code:
DEBUG ASTCLOCK.COM
-E017A
1088:017A B0.2C 63.64
-W
-Q
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.
Explanation:
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.
Disassembly:
View attachment ASTCLOCK.TXT
Screenshot:
Last edited: