10 REM > SoftCMOS/src
   20 REM Simple soft CMOS Config access
   30 :
   40 PROCassem(0):CLEAR:PROCassem(2):PROCsm_table
   50 A$="*SAVE "+fname$+" "+STR$~(mcode%+M%)+" "+STR$~O%+" FFFF0000 FFFBBC00"
   60 PRINTA$;:OSCLIA$:PRINT
   70 END
   80 :
   90 DEFPROCassem(pass%)
  100 OSASCI=&FFE3:OSWRCH=&FFEE:OSNEWL=&FFE7:OSWORD=&FFF1
  110 ver$="0.00":date$="01 Jan 2000":fname$="SoftCMOS"
  120 ws=&A8:tmp=ws+7:osw14=14:osw15=osw14+1:save=&D94
  130 DIM mcode% &1000, L%-1
  140 :
  150 FOR pass%=pass% TO pass%+1
  160   opt%=FNsm_pass(pass%)+8+16
  170   [OPT opt%
  180   .ROMBase
  190   EQUB &00:EQUW RelocTable
  200   JMP Service
  210   EQUB &82:EQUB copyright-ROMBase
  220   .ROMTitle
  230   EQUB VALver$*10:EQUS "SoftCMOS"
  240   EQUB &00:EQUS ver$+" "(+date$+")"
  250   .copyright
  260   EQUB &00:EQUS "(C)J.G.Harston"
  270   EQUB &00
  280   :
  290   \ SERVICE 9 - *Help
  300   \ -----------------
  310   .Serv09
  320   LDA (&F2),Y
  330   CMP #13:BNE Serv9Exit    :\ Not *Help<cr>
  340   JSR OSNEWL
  350   .Serv9a
  360   LDX #0
  370   .Serv9Lp
  380   LDA &8009,X:BNE Serv9Chk :\ Display ROM title
  390   LDA #ASC" ":BNE Serv9Char
  400   .Serv9Chk
  410   CMP #ASC" ":BEQ Serv9Done
  420   .Serv9Char
  430   JSR OSWRCH:INX:BNE Serv9Lp
  440   .Serv9Done
  450   JSR OSNEWL
  460   .Serv9Exit
  470   LDA #9:RTS
  480   :
  490   .Service
  500   CMP $&04:\BEQ Serv04     :\ *Command
  510   CMP #&07:BEQ Serv07      :\ OSBYTE
  520   CMP #&09:BEQ Serv09      :\ *Help
  530   RTS
  540   :
  550   \ SERVICE 7 - OSBYTE
  560   \ -----------------
  570   .Serv07
  580   LDY &F1:LDX &F0:LDA &EF          :\ A=num, X=byte, Y=value
  590   CMP #161:BEQ Osbyte161           :\ OSBYTE 161 - Read CMOS
  600   CMP #162:BNE P%+5:JMP Osbyte162  :\ OSWORD 162 - Write CMOS
  610   .Serv07Quit
  620   LDA #7:RTS
  630   :
  640   .Osbyte162
  650   INX:BEQ OsbyteClaim :\ Don't write size byte
  660   DEX:BEQ OsbyteClaim :\ Don't write station number
  670   TYA:STA CMOS,X
  680   .Osbyte161
  690   LDY CMOS,X
  700   .OsbyteClaim
  710   LDA #0:RTS
  720   .CMOS
  730   EQUS STRING$(128,CHR$0)
  740   EQUS STRING$(127,CHR$0)
  750   EQUB &FF :\ Size=256-1
  760   :
  770 ]:RelocTable=P%:NEXT:ENDPROC
  780 :
  790 DEFFNsm_pass(pass%)
  800 IFpass%=0:M%=0
  810 IFpass%=1:M%=O%-mcode%
  820 P%=&8100-128*(pass%AND2)
  830 O%=mcode%+M%*(pass%AND2)DIV2
  840 IFpass%=1:IF O%+M%*2.125>L%:PRINT"Code overrun":END
  850 =VALMID$("4646",pass%+1,1)
  860 :
  870 DEFPROCsm_table
  880 base80%=mcode%+M%:base81%=mcode%:byte%=0:count%=0:off%=0:REPEAT
  890   byte80%=base80%?off%:byte81%=base81%?off%:IF off%>=M%:byte80%=&80:byte81%=&80
  900   IF ((byte81%-byte80%) AND &FE)<>0 THEN PRINT "ERROR: Offset by more than one page at &";~&8000+off%
  910   IF (byte80% AND &C0)=&80:byte%=byte%DIV2+128*(byte81%-byte80%):count%=count%+1
  920   IF count%=8:?O%=byte%:O%=O%+1:byte%=0:count%=0
  930 off%=off%+1:UNTILoff%>=M% AND count%=0
  940 ENDPROC