>L. 100REM Read & Write M128 CMOS Chip Directly 150REM (C) Ian Wolstenholme 2022 200REM Except Assembler RTC Clock access code 250REM adapted from New AUG (C)Dickens&Holmes 1986 300REM Version 1.2 13/VII/2022 350REM Add option 7 to show & toggle regs A-D 400REM To do: 1. Test for 23:59:59 bug 450IFPAGE>&1000 OSCLI"KEY0*TAPE|MFORB%=0TOTOP-PAGE STEP4:!(B%+&1000)=!(B%+PAGE):N.:PAGE=&1000|MOLD|MRUN|M":OSCLI"FX138,0,128":END 500DIMcode 240 550DIMbaud$(7):FORB%=0TO7:READbaud$(B%):NEXT 600DIMprinter$(4):FORB%=0TO4:READprinter$(B%):NEXT 650DIMregs$(9):FORB%=0TO9:READregs$(B%):NEXT 700Y$=" 20":REM For century 750PROCassemble 800M%=128 850ONERRORM%=M%+1 900MODE M% 950ONERRORREPORT:PRINT" at ";ERL:OSCLI"FX4,0":COLOUR128:COLOUR1:END 1000REPEAT 1050CLS:VDU23,1;0;0;0;0; 1100COLOUR129:COLOUR0:PRINT"Master CMOS/RTC Chip Settings v1.2":COLOUR128:COLOUR1 1150PRINT'"1. Show all CMOS settings" 1200PRINT"2. Show time/date" 1250PRINT"3. Test CMOS chip" 1300PRINT"4. Show all time registers" 1350PRINT"5. Test BST function" 1400PRINT"6. Set Econet station number" 1450PRINT"7. Show Registers A to D" 1500PRINT'"0. Exit" 1550REPEATK%=GET:UNTILK%>47ANDK%<56 1600IFK%=49PROCdisplaycmos 1650IFK%=50PROCdisplaytime 1700IFK%=51PROCtestchip 1750IFK%=52PROCdisplayregs 1800IFK%=53PROCbsttest 1850IFK%=54PROCsetstation 1900IFK%=55PROCshowregisters 1950UNTILK%=48 2000VDU23,1,3;0;0;0;0; 2050END 2100DATA75,150,300,1200,2400,4800,9600,19200 2150DATANo printer,Parallel,Serial,User,Econet 2200DATASeconds,Seconds Alarm,Minutes,Minutes Alarm,Hours,Hours Alarm,Day of Week,Day of Month,Month,Year 2250DEFPROCassemble 2300FORB%=0TO2STEP2 2350P%=code 2400oswrch=&FFEE 2450slowbus=&FE4F :REM System VIA port A output 2500regb=&FE40 :REM System VIA port B control 2550ddra=&FE43 :REM System VIA port A direction 2600[OPTB% 2650.read JSRaddress 2700LDA#&49 \select read 2750STAregb 2800LDA#0:STAddra \ WasSTZ ddra, make 6502 compatible 2850LDA#&4A \set DS active 2900STAregb 2950LDYslowbus \value to be read in Y register 3000JMPfinish 3050.write JSR address 3100LDA#&41 \select WR on addressable latch 3150STAregb 3200LDA#&4A \take DS active 3250STAregb 3300STYslowbus 3350JMPfinish \ Was BRA, make 6502 compatible 3400.address LDA #2\enter with X=selected address 3450STAregb \Write CE & DS inactive to system via 3500LDA#&82 \AS active 3550STAregb 3600LDA#&FF \slow databus as output 3650STAddra 3700STXslowbus \write register address 3750LDA#&C2 \Take CE active 3800STAregb 3850LDA#&42 \strobe AS low to latch data 3900STAregb 3950RTS 4000.finish LDA#&42 \deactivate DS 4050STAregb 4100LDA#&02 \deactivate CE 4150STAregb 4200RTS 4250.readregister 4300LDXreg:LDY#0:JSRread:STYcmos:RTS 4350.writeregister 4400LDXreg:LDYcmos:JSRwrite:RTS 4450.readall 4500LDX#0 4550.readloop 4600LDY#0 4650JSRread 4700TYA 4750STAcmos,X 4800INX 4850CPX#65 4900BNEreadloop 4950RTS 5000.printromtitle 5050LDA#&80:STA&F7 5100LDA#9:STA&F6 \ Rom title at &8009 5150.romloop 5200LDYreg \ Re-use register number byte - must be within loop to work on BBCB 5250JSR&FFB9 \ OSRDRM 5300CMP#31 5350BMIskipprint 5400JSR&FFE3 \ Print if sensible char 5450.skipprint 5500CMP#0 5550BEQromfinish 5600INC&F6 5650LDA&F6 5700CMP#9+16 \ 16 chars printed only (in case rubbish) 5750BNEromloop 5800.romfinish 5850RTS 5900.reg EQUB0 5950.cmos EQUS STRING$(14,CHR$0) 6000.cmosram EQUS STRING$(50,CHR$0) 6050] 6100NEXT 6150ENDPROC 6200DEFFNreadreg(R%) 6250REMStore register number in .reg 6300?reg=R% 6350REM Call read code, result in Y register 6400CALLreadregister:=?cmos 6450DEFPROCwritereg(R%,V%) 6500REM Store register number in .reg 6550?reg=R% 6600?cmos=V%:REMStore value to write in .write 6650CALLwriteregister 6700ENDPROC 6750DEFFNtime 6800T%=TIME:REPEATUNTIL(FNreadreg(&A)AND128)=0ORTIME>T%+20:REM Wait till no update in progress 6850=STRING$(2-LENSTR$~FNreadreg(4),"0")+STR$~FNreadreg(4)+":"+STRING$(2-LENSTR$~FNreadreg(2),"0")+STR$~FNreadreg(2)+":"+STRING$(2-LENSTR$~FNreadreg(0),"0")+STR$~FNreadreg(0) 6900DEFFNdate 6950T%=TIME:REPEATUNTIL(FNreadreg(&A)AND128)=0ORTIME>T%+20:REM Wait till no update in progress 7000=MID$("SunMonTueWedThuFriSat",FNreadreg(6)*3-2,3)+","+STRING$(2-LENSTR$~FNreadreg(7),"0")+STR$~FNreadreg(7)+" "+MID$("JanFebMarAprMayJunJulAugSepOctNovDec",FNreadreg(8)*3-2,3)+Y$+STRING$(2-LENSTR$~FNreadreg(9),"0")+STR$~FNreadreg(9) 7050DEFFNtimestring 7100=FNdate+"."+FNtime 7150DEFFNtestcmos 7200REM Read byte 26 of CMOS (keyboard delay setting) to check 6818 presence 7250R%=FNreadreg(26):W%=255:IFR%=255 W%=128 7300PROCwritereg(26,W%) 7350N%=FNreadreg(26) 7400PROCwritereg(26,R%):REM restore old value if possible 7450IFN%=W% =TRUE ELSE =FALSE 7500DEFFNreaddse 7550=(FNreadreg(&B)AND1)=1 7600DEFPROCwritedse 7650PROCwritereg(&B,(FNreadreg(&B)OR1)) 7700ENDPROC 7750DEFFNtestbst 7800PROCwritedse 7850T%=TIME:REPEATCALLreadall:UNTIL?cmos<&54 ORTIME>T%+600:REM do all this within the current minute 7900REPEATUNTILFNreadreg(0)<>FNreadreg(0):REM wait till second ticks 7950PRINT"Current time: "TAB(20);FNtimestring 8000FORB%=0TO9:?(cmos+B%+20)=?(cmos+B%):NEXT:REM Store old time 8050PROCwritereg(&B,(FNreadreg(&B)OR128)):REM stop the clock 8100U%=TIME:REM Record time elapsed during routine 8150PROCwritereg(8,&4):PROCwritereg(7,&30):PROCwritereg(6,1):PROCwritereg(4,&1):PROCwritereg(2,&59):PROCwritereg(0,&58):REM set time to Sun,30/4 1:59:58 8200PRINT"Setting time to:"TAB(20);FNtimestring 8250PROCwritereg(&B,(FNreadreg(&B)MOD128)):REM start the clock 8300PRINT"Waiting 2 seconds till 3am..." 8350T%=TIME:REPEATUNTILTIME>T%+200:REM Wait 2 seconds 8400B%=(FNreadreg(4)=&3):REM hours should be 3 if BST active 8450PRINT"Reading time..."TAB(20);FNtimestring 8500PROCwritereg(&B,(FNreadreg(&B)OR128)):REM stop the clock 8550FORC%=1TO9:PROCwritereg(C%,?(cmos+C%+20)):NEXT:REM Restore prev time exc.s 8600REPEATUNTILTIME>U%+300:Q%=EVAL(STR$~cmos?20):Q%=Q%+(TIME-U%)/100:Q%=EVAL("&"+STR$Q%):PROCwritereg(0,Q%):REM Need round no of seconds 8650PROCwritereg(&B,(FNreadreg(&B)MOD128)):REM start the clock 8700PRINT"Restoring time to:"TAB(20);FNtimestring 8750=B% 8800DEFPROCshowcmos 8850CLS 8900COLOUR129:COLOUR0:PRINT"CMOS RAM Settings:":COLOUR128:COLOUR1 8950CALLreadall 9000PRINT"Econet Station Number"TAB(23);?cmosram 9050PRINT"Econet Servers"TAB(23)"File server: ";cmosram?2;".";cmosram?1;", Printer Server: ";cmosram?4;".";cmosram?3 9100PRINT"Default filing system"TAB(23);cmosram?5 MOD16;" (";:?reg=cmosram?5 MOD16:CALLprintromtitle:PRINT")" 9150PRINT"Default language"TAB(23);cmosram?5 DIV16;" (";:?reg=cmosram?5 DIV16:CALLprintromtitle:PRINT")" 9200IFM% MOD128=3 PROCshortplug ELSEPROClongplug 9250PRINT"EDIT settings"TAB(23);"Mode: ";:IF(cmosram?8 AND7)=2PRINT"K";ELSEIF(cmosram?8 AND7)=5PRINT"D";ELSEPRINT;(cmosram?8 AND7); 9300PRINT", TAB to ";:IFcmosram?8 AND8 PRINT"Words";ELSEPRINT"Columns"; 9350PRINT", ";:IFcmosram?8 AND16 PRINT"Insert";ELSEPRINT"Overwrite"; 9400PRINT", ";:IFcmosram?8 AND32 PRINT"Show";ELSEPRINT"Hide"; 9450PRINT" Returns" 9500PRINT"Telecoms settings"TAB(23);cmosram?9 9550PRINT"Screen settings"TAB(23);"Mode: ";128*((cmosram?10 AND8)/8)+(cmosram?10 AND7);", TV "; 9600T%=(cmosram?10 AND 128)/128*4+(cmosram?10 AND 64)/64*2+(cmosram?10 AND 32)/32*1:IFT%>3 T%=T%+248 9650PRINT;T%;",";(cmosram?10 AND16)/16;" (";:IFcmosram?10 AND16 PRINT"Interlace on)";ELSEPRINT"Interlace off)"; 9700PRINT", ";:IFcmosram?16 AND 8 PRINT"No scroll"ELSEPRINT"Scroll" 9750PRINT"Floppy drive timings"TAB(23);cmosram?11 AND7 9800PRINT"ADFS Defaults"TAB(23);:IFcmosram?11 AND64 PRINT"No d";ELSEPRINT"D"; 9850PRINT"irectory, ";:IFcmosram?11 AND128 PRINT"Floppy"ELSEPRINT"Winchester" 9900PRINT"Keyboard settings"TAB(23);"Repeat Delay: ";cmosram?12;", Repeat Rate: ";cmosram?13;", "; 9950IFcmosram?11 AND8PRINT"SHIFT-CAPS "; 10000IFcmosram?11 AND16PRINT"No CAPS "; 10050IFcmosram?11 AND32PRINT"CAPS Lock "; 10100PRINT'"Second processor"TAB(23);:IFcmosram?16 AND4 PRINT"External ";ELSEPRINT"Internal "; 10150IFcmosram?15 AND1 PRINT"(Enabled) "ELSEPRINT"(Disabled)" 10200PRINT"Serial settings"TAB(23);"Baud rate: ";1+(cmosram?15 AND 16)/16*4+(cmosram?15 AND 8)/8*2+(cmosram?15 AND 4)/4*1;" (";baud$((cmosram?15 AND 16)/16*4+(cmosram?15 AND 8)/8*2+(cmosram?15 AND 4)/4*1);"), Data format: "; 10250PRINT;(cmosram?16 AND 128)/128*4+(cmosram?16 AND 64)/64*2+(cmosram?16 AND 32)/32*1 10300S%=(cmosram?15 AND 128)/128*4+(cmosram?15 AND 64)/64*2+(cmosram?15 AND 32)/32*1:PRINT"Printer settings"TAB(23);"Type: ";S%;" (";:IFS%<5 PRINTprinter$(S%); ELSEPRINT"Unknown"; 10350PRINT"), Ignore character: ";cmosram?14;" (";:IFcmosram?15 AND2 PRINT"Not i";ELSEPRINT"I"; 10400PRINT"n use)" 10450PRINT"Beep"TAB(23);:IFcmosram?16 AND 2 PRINT"Loud"ELSEPRINT"Quiet" 10500PRINT"Autoboot"TAB(23);:IFcmosram?16 AND16 PRINT"Boot" ELSE PRINT"No boot" 10550PRINT"ANFS Settings"TAB(23);:IFcmosram?17 AND 1 PRINT"Space";ELSEPRINT"No space"; 10600PRINT", FindLib ";:IFcmosram?17 AND2 PRINT"on";ELSEPRINT"off"; 10650PRINT", Workspace ";:IFcmosram?17 AND4 PRINT"&E/F";ELSEPRINT"&B/C"; 10700PRINT", Protection ";:IFcmosram?17 AND64PRINT"on";ELSEPRINT"off"; 10750PRINTTAB(23)"Display versions ";:IFcmosram?17 AND 128 PRINT"on"ELSEPRINT"off" 10800PRINT"Joystick Settings"TAB(23)"Speed: ";cmosram?18 AND7;", ";:IFcmosram?18 AND 32 PRINT"Switched"ELSEPRINT"Proportional" 10850ENDPROC 10900DEFFNromtitle(?reg) 10950CALLprintromtitle 11000=TRUE:REM Doesn't need to be FN, could be PROc 11050DEFPROCdisplaycmos 11100PROCshowcmos:PRINT'"Press a key to return to menu" 11150REPEATPRINTTAB(50,0)"Time: ";FNtimestring:UNTILINKEY(10)<>-1 11200ENDPROC 11250DEFPROCdisplaytime 11300CLS:COLOUR129:COLOUR0:PRINT"Display RTC Time and Date":COLOUR128:COLOUR1:PRINT'''"Press a key to return to menu" 11350REPEATPRINTTAB(0,2)FNtimestring:UNTILINKEY(10)<>-1 11400ENDPROC 11450DEFPROCtestchip 11500CLS:COLOUR129:COLOUR0:PRINT"Test Presence of CMOS Chip"':COLOUR128:COLOUR1 11550IFFNtestcmos PRINT"6818 chip present"ELSEPRINT"No 6818 chip" 11600PRINT'"Press a key to return to menu" 11650REPEATUNTILGET 11700ENDPROC 11750DEFPROCdisplayregs 11800CLS:COLOUR129:COLOUR0:PRINT"Show Time Registers":COLOUR128:COLOUR1 11850*FX225,128 11900REPEAT 11950CALLreadall 12000bcd=(cmos?&B AND4)=0 12050PRINTTAB(0,2); 12100FORB%=0TO13 12150PRINT;B%;" - ";:IFB%<10 PRINTregs$(B%); ELSE PRINT"Register ";~B%; 12200PRINTTAB(23);:IFB%<10 ANDbcd PRINT~cmos?B% ELSE PRINTcmos?B% 12250NEXT 12300PRINT'"Register B Settings (toggle with f0-f3):" 12350PRINT"Daylight saving"TAB(23);:IFFNreaddse PRINT"Enabled "ELSEPRINT"Disabled" 12400PRINT"12/24 Hour Clock"TAB(23);:IFcmos?&B AND2 PRINT"24-hour clock"ELSEPRINT"12-hour clock" 12450PRINT"Data mode"TAB(23);:IFbcd PRINT"Binary coded decimal"ELSEPRINT"Decimal " 12500PRINT"Clock set"TAB(23);:IFcmos?&B AND 128 PRINT"Clock halted "ELSEPRINT"Clock running" 12550PRINT'"Press f0-f3 or any other key to return to menu" 12600PRINTTAB(50,0)"Time: ";FNtimestring 12650K%=INKEY(10) 12700IFK%=128 PROCwritereg(&B,FNreadreg(&B) EOR1):K%=-1 12750IFK%=129 PROCwritereg(&B,FNreadreg(&B)EOR2):K%=-1 12800IFK%=130 PROCwritereg(&B,FNreadreg(&B)EOR4):K%=-1 12850IFK%=131 PROCwritereg(&B,FNreadreg(&B)EOR128):K%=-1 12900UNTILK%<>-1 12950K%=0 13000*FX225,1 13050ENDPROC 13100DEFPROClongplug 13150FORB%=0TO7 13200PRINT"ROM ";B%;" ";:IFcmosram?6 AND2^B% PRINT"Inserted"; ELSEPRINT"Unplugged"; 13250PRINTTAB(23)"ROM ";B%+8;" ";:IFcmosram?7 AND2^B% PRINT"Inserted" ELSEPRINT"Unplugged" 13300NEXT 13350ENDPROC 13400DEFPROCshortplug 13450PRINT"ROMs Unplugged"TAB(23); 13500FORC%=6TO7 13550FORB%=0TO7 13600IFcmosram?C% AND2^B% ELSE PRINT;B%+(C%-6)*8;" "; 13650NEXT, 13700PRINT'"ROMS Inserted"TAB(23); 13750FORC%=6TO7 13800FORB%=0TO7 13850IFcmosram?C% AND2^B% PRINT;B%+(C%-6)*8;" "; 13900NEXT, 13950PRINT 14000ENDPROC 14050DEFPROCbsttest 14100CLS:COLOUR129:COLOUR0:PRINT"Testing BST function of 6818 chip...."':COLOUR128:COLOUR1 14150IFNOTFNtestcmos PRINT"No 6818 chip":GOTO14250 14200IFFNtestbst PRINT'"BST function present"ELSEPRINT'"No BST Function" 14250PRINT''"Press a key to return to menu" 14300REPEATUNTILGET 14350ENDPROC 14400DEFPROCsetstation 14450VDU23,1,3;0;0;0;0; 14500CLS:COLOUR129:COLOUR0:PRINT"Set Econet station number"':COLOUR128:COLOUR1 14550PRINT"Current station number: ";FNreadreg(14) 14600REPEAT 14650PRINT"Input new station number: ";:INPUT""S% 14700IFS%<0 OR S%>254 PRINT"Bad station number" 14750UNTILS%>=0 AND S%<255 14800IFS%=0 PRINT"Unchanged"ELSEPRINT"Setting station number to ";S%:PROCwritereg(14,S%) 14850PRINT'"Press a key to return to menu"; 14900REPEATUNTILGET 14950ENDPROC 15000DEFPROCshowregisters 15050regsel=65:bitsel=7 15100*FX4,1 15150CLS 15200COLOUR129:COLOUR0:PRINT"Show Registers A-D":COLOUR128:COLOUR1 15250COLOUR129:COLOUR0:PRINTTAB(0,28)"Arrow keys";:COLOUR128:COLOUR1:PRINT" to change highlighted selection":COLOUR129:COLOUR0:PRINT"RETURN";:COLOUR128:COLOUR1:PRINT" to toggle bit":COLOUR129:COLOUR0:PRINT"TAB";:COLOUR128:COLOUR1:PRINT" to return to menu" 15300COLOUR129:COLOUR0:PRINTTAB(0,13)"Register A (R/W except bit 7)":COLOUR128:COLOUR1:PRINT"Update in progress (7)"'"Divider bits (6-4)"'"Rate selection bits (3-0)" 15350COLOUR129:COLOUR0:PRINTTAB(40,13)"Register B (R/W)":COLOUR128:COLOUR1:PRINTTAB(40,14)"Set (Halt RTC)"TAB(40,15)"Periodic Interrupt Enable"TAB(40,16)"Alarm Interrupt Enable"TAB(40,17)"Update-Ended Interrupt Enable" 15400PRINTTAB(40,18)"Square Wave Enable"TAB(40,19)"Data Mode"TAB(40,20)"24/12 Hr Clock"TAB(40,21)"Daylight Saving Enable" 15450COLOUR129:COLOUR0:PRINTTAB(0,18)"Register C (R/O bits 7-4)":COLOUR128:COLOUR1:PRINT"Interrupt Request Flag"'"Periodic Interrupt Flag"'"Alarm Interrupt Flag"'"Update-Ended Interrupt Flag" 15500COLOUR129:COLOUR0:PRINTTAB(0,24)"Register D (R/O bit 7)":COLOUR128:COLOUR1:PRINT"Valid RAM and Time - Power sense pin" 15550PRINTTAB(8,2)"128 64 32 16 8 4 2 1 Total" 15600REPEAT 15650PRINTTAB(50,0)"Time: ";FNtimestring 15700FORB%=65TO68 15750PRINTTAB(0,-126+(B%*2))CHR$B%; 15800K%=INKEY(1):IFK%=-1 ELSEPROCdokeypress 15850FORC%=7TO0STEP-1 15900IFregsel=B% AND bitsel=C% COLOUR129:COLOUR0:ELSE COLOUR128:COLOUR1 15950PRINTTAB(ABS(-55+(C%*7)),-126+(B%*2));" ";:IFFNreadreg(B%-55)AND2^C% PRINT"1";ELSEPRINT"0"; 16000PRINT" "; 16050NEXT 16100COLOUR128:COLOUR1:PRINTTAB(66,-126+(B%*2));FNreadreg(B%-55);" "; 16150NEXT 16200IFFNreadreg(&A)AND128PRINTTAB(28,14)"Set "ELSEPRINTTAB(28,14)"Clear" 16250PRINTTAB(28,15);((FNreadreg(&A)AND64)+(FNreadreg(&A)AND32)+(FNreadreg(&A)AND16))/16;" " 16300PRINTTAB(28,16);FNreadreg(&A)AND15;" " 16350FORB%=7TO3STEP-1:IFFNreadreg(&B)AND2^B% PRINTTAB(70,ABS(-21+B%))"Set "ELSEPRINTTAB(70,ABS(-21+B%))"Clear" 16400NEXT 16450PRINTTAB(70,19);:IFFNreadreg(&B)AND2^2 PRINT"Decimal"ELSEPRINT"BCD " 16500PRINTTAB(70,20);:IFFNreadreg(&B)AND2^1 PRINT"24-hr"ELSEPRINT"12-hr" 16550PRINTTAB(70,21);:IFFNreadreg(&B)AND2^0 PRINT"Enabled "ELSEPRINT"Disabled" 16600FORB%=7TO4STEP-1:IFFNreadreg(&C)AND2^B% PRINTTAB(28,ABS(-26+B%))"Set "ELSEPRINTTAB(28,ABS(-26+B%))"Clear" 16650NEXT 16700IFFNreadreg(&D)AND2^7 PRINTTAB(37,25)"High"ELSEPRINTTAB(37,25)"Low " 16750UNTILK%=9 16800*FX4,0 16850ENDPROC 16900DEFPROCdokeypress 16950IFK%=139 regsel=regsel-1:IFregsel<65 regsel=68 17000IFK%=136 bitsel=bitsel+1:IFbitsel>7 bitsel=0 17050IFK%=137 bitsel=bitsel-1:IFbitsel<0 bitsel=7 17100IFK%=138 regsel=regsel+1:IFregsel>68 regsel=65 17150IFK%=13 PROCwritereg(regsel-55,(FNreadreg(regsel-55)EOR2^bitsel)) 17200*FX15,1 17250ENDPROC >*SPOOL