10 REM > SMFree/src v0.10
   20 REM List free memory in relocatable sideways modules
   30 REM 28-Feb-1999 v0.10 JGH: Initial version
   40 :
   50 OSASCI=&FFE3:OSWRCH=&FFEE:OSNEWL=&FFE7:OSBYTE=&FFF4
   60 DIM mcode% &300:load%=&FFFF0900:ver$="0.10"
   70 addr=&A8:total=&AA:num=total:pad=num+3
   80 :
   90 FOR P=0 TO 1
  100   P%=load%:O%=mcode%
  110   [OPT P*2+4
  120   .txtMessage
  130   .txtPlus :EQUS " + ":EQUB 0
  140   .txtTotal:EQUS "Total: ":EQUB 0
  150   .txtComma:EQUS ", ":EQUB 0
  160   .txtBytes:EQUS " bytes":EQUB 13:EQUB 0
  170   :
  180   .exec%
  190   LDA #0:LDX #3
  200   .ListZero
  210   STA total,X:DEX:BPL ListZero       :\ total=0
  220   :
  230   LDA &F4:PHA:LDX #15                :\ Start with ROM 15
  240   .ScanRomLoop
  250   JSR SelectRom
  260   LDA #&BF:STA addr+1                :\ Start at &BFFE
  270   LDA #&FE:STA addr+0
  280   LDY #0:SEC                         :\ SEC on first pass
  290   .lp1
  300   LDA (addr),Y:EOR &BFFF:BNE found   :\ Byte different
  310   LDA addr+0:BNE P%+4:DEC addr+1     :\ Decrement address
  320   DEC addr+0
  330   CLC:LDA addr+1:BMI lp1             :\ Loop while still in ROM
  340                                      :\ Ends at &7FFF for full ROM
  350   .found
  360   JSR IncAddr:JSR IncAddr1           :\ Increment addr to first free byte
  370   LDA #&FF:JSR PrHex                 :\ Print FFFxyyyy
  380   LDA &F4:ORA #&F0:JSR PrHex
  390   LDX #addr+1-addr:LDY #2:JSR PrAddr :\ Print addr
  400   LDX #txtPlus-txtMessage:JSR PrMsg  :\ Print ' + '
  410   SEC
  420   LDA #&00:SBC addr+0:STA addr+0     :\ addr=free space
  430   LDA #&C0:SBC addr+1:STA addr+1     :\ addr=&C000-addr
  440   LDX #addr+1-addr:LDY #2:JSR PrAddr :\ Print free space
  450   JSR AddTotal                       :\ total=total+free
  460   :
  470   LDA #ASC" ":JSR OSWRCH:LDX #0
  480   .romtitle
  490   LDA &8009,X                        :\ Print ROM title
  500   CMP #ASC" ":BCC romtitledone       :\ Stop at invalie character
  510   CMP #&7F:BCS romtitledone
  520   JSR OSWRCH:INX:BNE romtitle
  530   .romtitledone
  540   JSR OSNEWL
  550   LDX &F4:DEX:BPL ScanRomLoop        :\ Step to next ROM
  560   :
  570   LDX #txtTotal-txtMessage:JSR PrMsg :\ Print 'Total '
  580   LDX #total+3-addr:LDY #4:JSR PrAddr:\ Print total in hex
  590   LDX #txtComma-txtMessage:JSR PrMsg :\ Print ', '
  600   LDA #0:STA pad:JSR PrDec24         :\ Print total in decimal
  610   LDX #txtBytes-txtMessage:JSR PrMsg :\ Print 'bytes'
  620   :
  630   PLA:TAX                            :\ Restore ROM
  640   .SelectRom
  650   STX &F4:JMP &FFB9                  :\ Select ROM
  660   :
  670   .IncAddr1
  680   SEC
  690   .IncAddr
  700   LDA addr+0:ADC #0:STA addr+0
  710   LDA addr+1:ADC #0:STA addr+1
  720   RTS
  730   :
  740   .AddTotal
  750   CLC
  760   LDA total+0:ADC addr+0:STA total+0 :\ total=total+free
  770   LDA total+1:ADC addr+1:STA total+1
  780   LDA total+2:ADC #0:STA total+2
  790   RTS
  800   :
  810   .PrAddr
  820   LDA addr,X:JSR PrHex
  830   DEX:DEY:BNE PrAddr
  840   RTS
  850   :
  860   .PrMsg
  870   LDA txtMessage,X:BEQ PrMsgDone
  880   JSR OSASCI:INX:BNE PrMsg
  890   .PrMsgDone
  900   RTS
  910   :
  920   .PrHex
  930   PHA:LSR A:LSR A:LSR A:LSR A
  940   JSR PrNyb:PLA
  950   .PrNyb
  960   AND #15:CMP #10:BCC PrDigit
  970   ADC #6:.PrDigit
  980   ADC #ASC"0":JMP OSWRCH
  990   :
 1000   \ Print 24-bit decimal number
 1010   \ ---------------------------
 1020   .PrDec24
 1030   LDY #6*3-3                               :\ 6 digits
 1040   .PrDec24Lp1
 1050   LDX #&FF:SEC                             :\ Start with digit=-1
 1060   .PrDec24Lp2
 1070   LDA num+0:SBC PrDecTens+0,Y:STA num+0    :\ Subtract current tens
 1080   LDA num+1:SBC PrDecTens+1,Y:STA num+1
 1090   LDA num+2:SBC PrDecTens+2,Y:STA num+2
 1100   INX:BCS PrDec24Lp2                       :\ Loop until <0
 1110   LDA num+0:ADC PrDecTens+0,Y:STA num+0    :\ Add current tens back in
 1120   LDA num+1:ADC PrDecTens+1,Y:STA num+1
 1130   LDA num+2:ADC PrDecTens+2,Y:STA num+2
 1140   TXA:BNE PrDec24Digit                     :\ Not zero, print it
 1150   LDA pad:BNE PrDec24Print:BEQ PrDec24Next :\ pad<>0, use it
 1160   .PrDec24Digit
 1170   LDX #ASC"0":STX pad                      :\ No more zero padding
 1180   ORA #ASC"0"                              :\ Print this digit
 1190   .PrDec24Print
 1200   JSR OSWRCH
 1210   .PrDec24Next
 1220   DEY:DEY:DEY:BPL PrDec24Lp1               :\ Loop for next digit
 1230   RTS
 1240   :
 1250   .PrDecTens
 1260   EQUW 1     :EQUB 1 DIV 65536
 1270   EQUW 10    :EQUB 10 DIV 65536
 1280   EQUW 100   :EQUB 100 DIV 65536
 1290   EQUW 1000  :EQUB 1000 DIV 65536
 1300   EQUW 10000 :EQUB 10000 DIV 65536
 1310   EQUW 100000:EQUB 100000 DIV 65536
 1320   :
 1330   EQUS "v"+ver$
 1340 ]NEXT
 1350 PRINT" *Save SMFree ";~mcode%;" ";~O%;" ";~exec%OR&FFFF0000;" ";~load%