×   Main Menu ALL The 8BS News Manuals (New menu) Links Worth a Look Tools Disc and Basic Webring Site Map 8BS Guestbook Old Guest Book Me The Barnsley Rovers   
8-Bit Software

The BBC and Master Computer Public Domain Library

Y2K Fix BASIC Listing Debugged Version

10 REM Y2K REPAIR for CMOS clock
20 REM Copyright (C) Mark Bush, Raffaele Giaccio
30 REM For BBC Micros with CMOS clock
40 :
50 REM Uses 2 bytes of zero page at
60 REM &70, &71, preserving contents
70 REM and a page of dynamic filing system RAM (only
80 REM 4 bytes are used) and preserving PAGE
90 :
100 ZP=&70
110 ZP1=&71
120 OSASCI=&FFE3
130 OSBYTE=&FFF4
140 OSNEWL=&FFE7
150 DIM C% 1000
160 FOR D% = 4 TO 7 STEP 3
170 P%=&8000
180 O%=C%
190 [OPT D%
200 \ setup ROM header
210 EQUB &00
220 EQUW &00
230 JMP SERVICE
240 EQUB &82 \ code for a normal ROM
250 EQUB COPY-&8000
260 EQUB &02
270.title
280 EQUS "Y2K REPAIR"
290 EQUB &00
300 EQUS "2.10"
310 .COPY
320 EQUB &00
330 EQUS "(C)2002-03 Mark Bush, Raffaele Giaccio"
340 EQUB &00
350 .SERVICE
360 CMP #&22 \ claim dynamic filing system workspace
370 BEQ WKSP
380 CMP #&27 \ a reset has occurred
390 BEQ RESET
400 CMP #&24 \ count dynamic filing system workspace RAM
410 BNE out
420 DEY:RTS
430 .out CMP #&09 \ respond to *HELP
440 BEQ helpjmp:RTS
450 .helpjmp JMP help
460 .WKSP
470 TYA
480 STA &0DF0,X \ save our workspace page number
490 LDA #&22
500 INY \ claim 1 page for our use
510 RTS
520 .RESET
530 \ after a reset, the MOS vectors will have been reset
540 \ so we need to redo the redirection of OSWORD through
550 \ our routine
560 TYA
570 PHA
580 \ save zero page locations
590 LDA ZP
600 PHA
610 LDA ZP1
620 PHA
630 \ OSBYTE &A8 retrieves start of extended vector area
640 LDX #&00
650 LDY #&FF
660 LDA #&A8
670 JSR OSBYTE
680 \ (X;Y) returned
690 STX ZP
700 STY ZP1
710 \ each vector is 3 bytes long and OSWORD is the 7th so
720 \ we need to offset 18 bytes (6 vectors) to reach it
730 LDY #&12
740 \ save new vector as:
750 \ byte 1 target low byte
760 \ byte 2 target high byte
770 \ byte 3 ROM number to page in to access target
780 LDA #TIM MOD 256
790 STA (ZP),Y
800 INY
810 LDA #TIM DIV 256
820 STA (ZP),Y
830 INY
840 LDX &F4 \ our ROM number
850 TXA
860 STA (ZP),Y
870 \ retrieve our saved workspace page number
880 LDA &0DF0,X
890 STA ZP1
900 LDA #&00
910 STA ZP
920 \ get current address of the OSWORD routine (which may
930 \ already be redirected) and save 1 less in our workspace
940 \ (we use the trick of pushing the address on the stack
950 \ and using RTS to go there which adds 1 to the address)
960 LDA &020C
970 SEC
980 SBC #&01
990 STA (ZP)
1000 INC ZP
1010 LDA &020D
1020 SBC #&00
1030 STA (ZP)
1040 \ do the same for the address we want OSWORD to return to
1050 \ for call &0E so we can process the output
1060 INC ZP
1070 LDA #RET MOD 256
1080 SEC
1090 SBC #&01
1100 STA (ZP)
1110 INC ZP
1120 LDA #RET DIV 256
1130 SBC #&00
1140 STA (ZP)
1150 \ restore the zero page locations
1160 PLA
1170 STA ZP1
1180 PLA
1190 STA ZP
1200 \ set WORDV to now redirect through extended vectors
1210 LDA #&12
1220 STA &020C
1230 LDA #&FF
1240 STA &020D
1250 \ restore state and return
1260 PLA
1270 TAY
1280 LDA #&27
1290 RTS
1300 .TIM
1310 \ OSWORD now always redirects here first
1320 \ check if it is call &0E for the CMOS
1330 \ clock routine
1340 CMP #&0E
1350 BEQ CLOCK
1360 \ save call number
1370 PHA
1380 \ keep 2 stack places for the OSWORD address
1390 \ to return to
1400 PHA
1410 PHA
1420 \ preserve X
1430 TXA
1440 PHA
1450 \ preserve zero page locations
1460 LDA ZP
1470 PHA
1480 LDA ZP1
1490 PHA
1500 \ get our ROM number, retrieve our workspace page and
1510 \ extract the saved OSWORD address and put it in the
1520 \ stack over the 2 places saved for it above
1530 LDX &F4
1540 LDA &0DF0,X
1550 STA ZP1
1560 LDA #&00
1570 STA ZP
1580 TSX
1590 LDA (ZP)
1600 STA &0105,X
1610 INC ZP
1620 LDA (ZP)
1630 STA &0106,X
1640 \ restore zero page
1650 PLA
1660 STA ZP1
1670 PLA
1680 STA ZP
1690 \ restore X and A
1700 PLA
1710 TAX
1720 PLA
1730 \ stack now has the address (less 1) of OSWORD
1740 \ so RTS will go there as if it had been called
1750 \ normally
1760 RTS
1770 .CLOCK
1780 \ we now know that we are in the CMOS clock OSWORD (&0E)
1790 \ preserve Y and X
1800 TYA
1810 PHA
1820 TXA
1830 PHA
1840 \ keep 1 space to hold the type of call this is (X;Y);
1850 \ 0 - return string of date and time
1860 \ 1 - return BCD format not including the century
1870 \ 2 - turn BCD format into string format
1880 PHA
1890 \ keep 4 stack places
1900 \ these will be the OSWORD address and our address of
1910 \ RET so that a return from the real OSWORD comes back to us
1920 PHA
1930 PHA
1940 PHA
1950 PHA
1960 \ preserves zero page locations
1970 LDA ZP
1980 PHA
1990 LDA ZP1
2000 PHA
2010 \ as before, get the OSWORD and RET addresses and
2020 \ put them into their places in the stack
2030 LDX &F4
2040 LDA &0DF0,X
2050 STA ZP1
2060 LDA #&00
2070 STA ZP
2080 TSX
2090 \ OSWORD address
2100 LDA (ZP)
2110 STA &0103,X
2120 INC ZP
2130 LDA (ZP)
2140 STA &0104,X
2150 \ RET address
2160 INC ZP
2170 LDA (ZP)
2180 STA &0105,X
2190 INC ZP
2200 LDA (ZP)
2210 STA &0106,X
2220 \ save (X;Y)
2230 STY ZP1
2240 LDA &0108,X
2250 STA ZP
2260 LDA (ZP)
2270 STA &0107,X
2280 \ restore X
2290 LDA &0108,X
2300 TAX
2310 \ restore zero page
2320 PLA
2330 STA ZP1
2340 PLA
2350 STA ZP
2360 \ restore A
2370 LDA #&0E
2380 \ "return" to OSWORD
2390 RTS
2400 .RET
2410 \ OSWORD will return to this point
2420 \ retrieve the call type (X;Y)
2430 PLA
2440 \ if it is 1 then we are done
2450 CMP #&01
2460 BEQ DONE
2470 \ otherwise preserve zero page locations
2480 LDA ZP
2490 PHA
2500 LDA ZP1
2510 PHA
2520 \ get X and Y to access the return string
2530 TSX
2540 LDA &0103,X
2550 STA ZP
2560 LDA &0104,X
2570 STA ZP1
2580 \ set century to "20"
2590 LDA #ASC("2")
2600 LDY #&0B
2610 STA (ZP),Y
2620 LDA #ASC("0")
2630 INY
2640 STA (ZP),Y
2650 \ restore zero page
2660 PLA
2670 STA ZP1
2680 PLA
2690 STA ZP
2700 .DONE
2710 \ we are done
2720 \ restore X, Y and A and return
2730 PLA
2740 TAX
2750 PLA
2760 TAY
2770 LDA #&0E
2780 RTS
2790 \
2800 .help
2810 \ preserve all registers and check syntax
2820 PHP:PHA:TXA:PHA:TYA:PHA
2830 JSR OSNEWL
2840 LDX#0:.loop LDA (&F2),Y:CMP#0D:BEQ proceed:CMP#ASC("."):BEQ nextbit
2850 AND #&DF:CMP#63:BMI next:CMP title,X:BNE stop
2860 .next CMP#&0D:BEQ proceed:INY:INX:CPX#10:BNE loop
2870 .proceed CPX#0:BEQ nextbit:CPX#10:BEQ nextchr:JMP stop
2880 .nextchr DEX:DEY:LDA (&F2),Y:AND #&DF:CMP title,X:BNE stop
2890 INY:LDA (&F2),Y:CMP#&0D:BEQ nextbit:CMP#ASC(" "):BNE stop
2900 \
2910 .nextbit
2940 LDX#0:.loophlp LDA string,X:BEQ out2:JSR OSASCI
2950 INX:JMP loophlp
2960 .out2 JSR OSNEWL
2970 \ restore registers and return
2980 .stop PLA:TAY:PLA:TAX:PLA:PLP:RTS
2990 \
3000 .string EQUB&0D
3010 EQUS"Y2K REPAIR":EQUB&0D
3020 EQUS"  Y2KROM 2.10":EQUB&0D
3030 EQUS"  CMOS clock millenium correction"
3040 EQUB&0D:EQUB&0D:EQUB&00
3050 .DNE
3060 \
3070 ]:NEXT
3080 S$=STR$ ~C%
3090 E$=STR$ ~(DNE-&8000+C%)
3100 OSCLI "SAVE Y2KROM "+S$+" "+E$
3110 OSCLI "SRLOAD Y2KROM 8000 7 Q"
3120 REM ** Save this program before running unless using 2nd/co-processor **
3130 REM Remove 'Q' from line 3110 if not compatible with your machine
3140 REM Remember to press 'CTRL and BREAK' after running.
3150 REM SAVE"CLOCKSC"