<< Previous Message Main Index Next Message >>
<< Previous Message in Thread This Month Next Message in Thread >>
Date   : Tue, 25 Jan 2000 03:07:36 +0000
From   : jgh@... (Jonathan Graham Harston)
Subject: Warning: BBC Master not Y19C compliant

"Fraser, Colin J" <Colin.Fraser@...> wrote:
> Found a fault in the Master OS last night.
> It incorrectly believes the year 1900 to be a leap year.
 
It's not really that.  It correctly believes that 2000 is a leap year, it
just neglects to return the century number correctly.
 
Osword14 has NEVER been guaranteed to return the date correctly.  You
should NEVER use it raw without actually checking what you've read.  How
often do you reach into the fridge, grab something and then put it
straight into your mouth without looking?
 
Unfortunately, the Master MOS immediately ignores the rules.  *TIME reads
the time as a string, and then dumps it straight to the VDU.
 
I posted this to csap on 22-Jul-1999:
----8<----
Osword14 has never been guaranteed to correctly return the year, most
explicitly because Osword14,1 only returns a two-digit year, so programs
have always needed to process the returned data before using it.
 
Some systems don't provide Osword14, so the returned data has to be
checked to see if there was returned data.
 
Some systems provide Osword14, but don't have a RTC, and return a default
string, which have to be checked for.
 
Some systems fetch the time&date from a server, but mess up, mixing the
year and date data, so these have to be checked for.  (Some systems
thought that 1997 was 1981.)
 
As NetFS dates represent the year as a 7-bit offset from 1981, that has
always been the recommended pivot point, so code would do something like:
       if year<81 then fullyear 00+year else year=1900+year
 
When manipulating the date as a string, it is easier to use 1980 as the
pivot point with almost the same result, as it involves checking a single
character, so making code do something like:
       if year[2]<'8' then year[0..1]="20" else year[0..1]="19"
 
So, IF using Osword14 to find the date
    THEN process the result before using it
 
The following is the function I use when I need to compatibly use Osword
14 to read the time&date as a string:
 
    DIM ctrl% 30:X%=ctrl%:Y%=X%DIV256
 
    DEFFNtime:?X%=0:A%=14:CALL&FFF1:IF?X%=0:=""
    X%?25=13:X%?15=13:A%=VALMID$($X%,5,2)DIV32
    $(X%+11)=STR$(VAL$(X%+11)+16*A%-100*(VAL$(X%+11)<1981))
    IFA%:X%?6=13:$(X%+4)=RIGHT$("0"+STR$(VAL$(X%+4)-32),2):X%?6=32
    X%?15=46:=$X%
 
This reads the RTC regardless of what machine it is running on, and will
correct for years after 1996 and 1999, or return a null string if no time
is available.  The 'Acorn Era' is defined as starting in 1981, so the
century range is 1981-2080.
 
See also:
http://mdfs.net/Docs/ManPages/O/2OSWORD14
http://mdfs.net/Docs/ManPages/T/3Time
----8<----
 
> This should mean I can render the OS Y2K compliant by replacing a '19'
> in the rom with a '20' - assuming the date is stored as 2 digits, and
> TIME$ always prepends the 19. Anyone know whereabouts I'll find this ?
 
In MOS 3.20 at &FFFF9880 (ie, rom number &F, address &9880) is the code:
FFFF9880: A9 19    LDA #&19
 
change the byte at &FFFF9881 to &20 to give:
FFFF9880: A9 20    LDA #&20
 
The code should really have been written to do something like:
FFFFxxxx: AD F7 02 LDA &02F7 ; get year number from workspace
          C9 81    CMP #&81  ; check against pivot year
          A9 19    LDA #&19  ; 1981...1999
          B0 02    BCS P%+4
          A9 20    LDA #&20  ; 2000...2080
 
Yeah gods, only an addition 9 bytes!
And there's 65 spare bytes at &FFFFB8BF!  It would have fitted!
 
-- 
J.G.Harston (JGH BBC PD Library) 70 Camm Street, Walkley, SHEFFIELD S6 3TR
jgh@...                - Running on BBCs & Masters with SJ MDFS FileServer
            Z80+6502/CoPro+Tubes/Econet+SJ -- http://mdfs.net
            A TRUE Klingon Warrior does not comment his code!
<< Previous Message Main Index Next Message >>
<< Previous Message in Thread This Month Next Message in Thread >>