package Ġorg . j gl rx av pok . k ame boy . memory . car tr idget ypes Ċ Ċ import Ġorg . j gl rx av pok . k ame boy . help ful . as Unsigned Ċ import Ġorg . j gl rx av pok . k ame boy . help ful . set Bits Ċ import Ġorg . j gl rx av pok . k ame boy . help ful . to Clock Cycles Ċ import Ġorg . j gl rx av pok . k ame boy . memory . Battery Ċ import Ġorg . j gl rx av pok . k ame boy . memory . Car tr idge Ċ import Ġorg . j gl rx av pok . k ame boy . memory . Register Ċ import Ġorg . j gl rx av pok . k ame boy . memory . special Regs . DH Counter Register Ċ import Ġorg . j gl rx av pok . k ame boy . memory . special Regs . DL Counter Register Ċ import Ġorg . j gl rx av pok . k ame boy . time . Save State Element Ċ Ċ class ĠM BC 3 ( val Ġcar tr idge : ĠCar tr idge , Ġval Ġbattery : ĠB attery ): ĠCar tr idge Type () Ġ{ ĊĠĠĠ Ġoverride Ġval Ġname Ġ= Ġ" MB C 3 " ĊĠĠĠ Ġ@ Save State Element ĊĠĠĠ Ġinternal Ġvar Ġenabled Ġ= Ġtrue ĊĠĠĠ Ġ@ Save State Element ĊĠĠĠ Ġinternal Ġvar Ġl atch Start Ġ= Ġfalse ĊĠĠĠ Ġ@ Save State Element ĊĠĠĠ Ġvar Ġmode Ġ= ĠMode . Ram ĊĠĠĠ Ġ@ Save State Element ĊĠĠĠ Ġvar Ġcurrent Bank Ġ= Ġ 1 ĊĠĠĠ Ġval ĠBank Size Ġ= Ġ 0 x 4 0 0 0 ĊĠĠĠ Ġval Ġb anks Ġ= ĠArray ( car tr idge . rom Bank Count ) Ġ{ Ġindex Ġ-> ĊĠĠĠĠĠĠĠ Ġval Ġstart Ġ= Ġindex * Bank Size ĊĠĠĠĠĠĠĠ Ġval Ġend Ġ= Ġstart + Bank Size ĊĠĠĠĠĠĠĠ Ġcar tr idge . raw Data . slice Array ( start Ġuntil Ġend ) ĊĠĠĠ Ġ} ĊĠĠĠ Ġ@ Save State Element ĊĠĠĠ Ġinternal Ġvar Ġmilliseconds Ġ= Ġ 0 ĊĠĠĠ Ġ@ Save State Element ĊĠĠĠ Ġinternal Ġval Ġseconds Ġ= ĠRegister (" RTC ĠS ") ĊĠĠĠ Ġ@ Save State Element ĊĠĠĠ Ġinternal Ġval Ġminutes Ġ= ĠRegister (" RTC ĠM ") ĊĠĠĠ Ġ@ Save State Element ĊĠĠĠ Ġinternal Ġval Ġhours Ġ= ĠRegister (" RTC ĠH ") ĊĠĠĠ Ġ@ Save State Element ĊĠĠĠ Ġinternal Ġval Ġupper Day Counter Ġ= ĠDH Counter Register () ĊĠĠĠ Ġ@ Save State Element ĊĠĠĠ Ġinternal Ġval Ġlower Day Counter Ġ= ĠDL Counter Register ( upper Day Counter ) ĊĠĠĠ Ġ@ Save State Element ĊĠĠĠ Ġinternal Ġvar Ġselected Clock Register Ġ= Ġ 0 ĊĠĠĠ Ġprivate Ġvar Ġlast Time Ġ= ĠSystem . currentTimeMillis () ĊĊĠĠĠ Ġinit Ġ{ ĊĠĠĠĠĠĠĠ Ġbattery . load RAM ( car tr idge ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġtick ( cycles : ĠInt ) Ġ{ ĊĠĠĠĠĠĠĠ Ġsuper . tick ( cycles ) ĊĠĠĠĠĠĠĠ Ġif ( upper Day Counter . timer H alt ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlast Time Ġ= ĠSystem . currentTimeMillis () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġwrite ( address : ĠInt , Ġvalue : ĠInt ) Ġ{ ĊĠĠĠĠĠĠĠ Ġwhen ( address ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġin Ġ 0 x 2 0 0 0 .. 0 x 3 FFF Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcurrent Bank Ġ= Ġif ( value Ġ== Ġ 0 x 0 0 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ 0 x 0 1 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvalue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġin Ġ 0 x 4 0 0 0 .. 0 x 5 FFF Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif ( value Ġin Ġ 0 .. 3 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcar tr idge . selected RAM Bank Index Ġ= Ġvalue Ġand Ġ 0 b 1 1 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmode Ġ= ĠMode . Ram ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġif ( value Ġin Ġ 0 x 0 8 .. 0 x 0 C ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmode Ġ= ĠMode . Clock ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġselected Clock Register Ġ= Ġvalue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġin Ġ 0 x 6 0 0 0 .. 0 x 7 FFF Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwhen ( value ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ 0 x 0 0 Ġ-> Ġl atch Start Ġ= Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ 0 x 0 1 Ġ-> Ġif ( latch Start ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġl atch Clock Data () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġl atch Start Ġ= Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġl atch Start Ġ= Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġin Ġ 0 x 0 0 0 0 .. 0 x 1 FFF Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġenable Ġ= Ġvalue Ġand Ġ 0 xF Ġ== Ġ 0 b 1 0 1 0 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif ( enabled Ġ&& Ġ! enable Ġ&& Ġmode Ġ== ĠMode . Ram ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbattery . save RAM ( car tr idge ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġenabled Ġ= Ġenable ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġin Ġ 0 xA 0 0 0 .. 0 xB FFF Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( mode ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠMode . Clock Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif ( enabled ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwrite RTC ( address - 0 xA 0 0 0 , Ġvalue ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠMode . Ram Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif ( enabled ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcar tr idge . current RAM Bank . write ( address , Ġvalue ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġl atch Clock Data () Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġtime Ġ= Ġ( System . currentTimeMillis ()- last Time )/ 1 0 0 0 ĊĠĠĠĠĠĠĠ Ġvar Ġnew Milliseconds Ġ= Ġmilliseconds Ġ+ Ġ( System . currentTimeMillis ()- last Time ) Ġ% Ġ 1 0 0 0 ĊĠĠĠĠĠĠĠ Ġvar Ġnew Seconds Ġ= Ġseconds . getValue () Ġ+ Ġ( time Ġ% Ġ 6 0 ) ĊĠĠĠĠĠĠĠ Ġvar Ġnew Minutes Ġ= Ġminutes . getValue () Ġ+ Ġ(( time Ġ/ Ġ 6 0 ) Ġ% Ġ 6 0 ) ĊĠĠĠĠĠĠĠ Ġvar Ġnew Hours Ġ= Ġhours . getValue () Ġ+ Ġ(( time Ġ/ Ġ 3 6 0 0 ) Ġ% Ġ 6 0 ) ĊĠĠĠĠĠĠĠ Ġvar Ġnew Days Ġ= Ġ(( upper Day Counter . getValue () Ġand Ġ 0 x 1 ) Ġshl Ġ 8 ) Ġ+ Ġlower Day Counter . getValue () Ġ+ Ġ(( time Ġ/ Ġ 3 6 0 0 Ġ/ Ġ 2 4 ) Ġ% Ġ 5 1 2 ) ĊĠĠĠĠĠĠĠ Ġwhile ( new Milliseconds Ġ>= Ġ 1 0 0 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġnew Milliseconds Ġ-= Ġ 1 0 0 0 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġnew Seconds ++ ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġwhile ( new Seconds Ġ>= Ġ 6 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġnew Seconds Ġ-= Ġ 6 0 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġnew Minutes ++ ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġwhile ( new Minutes Ġ>= Ġ 6 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġnew Minutes Ġ-= Ġ 6 0 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġnew Hours ++ ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġwhile ( new Hours Ġ>= Ġ 2 4 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġnew Hours Ġ-= Ġ 2 4 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġnew Days ++ ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġseconds . setValue ( new Seconds . toInt ()) ĊĠĠĠĠĠĠĠ Ġminutes . setValue ( new Minutes . toInt ()) ĊĠĠĠĠĠĠĠ Ġhours . setValue ( new Hours . toInt ()) ĊĠĠĠĠĠĠĠ Ġlower Day Counter . setValue ( new Days . toInt () Ġand Ġ 0 xFF ) ĊĠĠĠĠĠĠĠ Ġif ( new Days Ġ> Ġ 0 xFF ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġupper Day Counter . setValue ( upper Day Counter . getValue (). set Bits ( 1 , Ġ 0 .. 0 )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif ( new Days Ġ> Ġ 0 x 1 FF ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġupper Day Counter . setValue ( upper Day Counter . getValue (). set Bits ( 0 , Ġ 0 .. 0 )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġupper Day Counter . setValue ( upper Day Counter . getValue (). set Bits ( 1 , Ġ 7 .. 7 )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġmilliseconds Ġ= Ġnew Milliseconds . toInt () ĊĠĠĠĠĠĠĠ Ġlast Time Ġ= ĠSystem . currentTimeMillis () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġread ( address : ĠInt ): ĠInt Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġwhen ( address ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġin Ġ 0 x 0 0 0 0 .. 0 x 3 FFF Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġb anks [ 0 ][ address ]. as Unsigned () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġin Ġ 0 x 4 0 0 0 .. 0 x 7 FFF Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġbank Ġ= Ġb anks [ current Bank ] ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbank [ address - 0 x 4 0 0 0 ]. as Unsigned () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġin Ġ 0 xA 0 0 0 .. 0 xB FFF Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif (! enabled ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġ 0 xFF ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġwhen Ġ( mode ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠMode . Clock Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġread RTC ( address ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠMode . Ram Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcar tr idge . current RAM Bank . read ( address ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġ 0 xFF ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġwrite RTC ( addr : ĠInt , Ġvalue : ĠInt ) Ġ{ ĊĠĠĠĠĠĠĠ Ġwhen ( selected Clock Register ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠ 0 x 0 8 Ġ-> Ġseconds . setValue ( value ) ĊĠĠĠĠĠĠĠĠĠĠĠĠ 0 x 0 9 Ġ-> Ġminutes . setValue ( value ) ĊĠĠĠĠĠĠĠĠĠĠĠĠ 0 x 0 A Ġ-> Ġhours . setValue ( value ) ĊĠĠĠĠĠĠĠĠĠĠĠĠ 0 x 0 B Ġ-> Ġlower Day Counter . setValue ( value ) ĊĠĠĠĠĠĠĠĠĠĠĠĠ 0 x 0 C Ġ-> Ġupper Day Counter . setValue ( value ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġread RTC ( addr : ĠInt ): ĠInt Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġwhen ( selected Clock Register ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠ 0 x 0 8 Ġ-> Ġseconds . getValue () ĊĠĠĠĠĠĠĠĠĠĠĠĠ 0 x 0 9 Ġ-> Ġminutes . getValue () ĊĠĠĠĠĠĠĠĠĠĠĠĠ 0 x 0 A Ġ-> Ġhours . getValue () ĊĠĠĠĠĠĠĠĠĠĠĠĠ 0 x 0 B Ġ-> Ġlower Day Counter . getValue () ĊĠĠĠĠĠĠĠĠĠĠĠĠ 0 x 0 C Ġ-> Ġupper Day Counter . getValue () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġ 0 xFF ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġaccepts ( address : ĠInt ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġaddress Ġin Ġ 0 .. 0 x 8 0 0 0 Ġ|| Ġaddress Ġin Ġ 0 xA 0 0 0 .. 0 xB FFF ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġenum Ġclass ĠMode Ġ{ ĊĠĠĠĠĠĠĠ ĠRam , ĊĠĠĠĠĠĠĠ ĠClock ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun ĠtoString (): ĠString Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġ" MB C 3 ( Current Bank =$ current Bank , ĠB attery =$ battery )" ĊĠĠĠ Ġ} Ċ Ċ }