;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; File Name :   wldUtil.asm
; Purpose   :   World Time Wrist App Common Utility Routines
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;DO NOT MODIFY THE FOLLOWING SUBROUTINE DEFINITION;;;;;;;;;;;;;;;;;

                IF @DEF('SUBROUTINE')
                    UNDEF SUBROUTINE
                ENDIF
                DEFINE  SUBROUTINE      "'wldutil'"
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;



                GLOBAL  wldReadCurrentCityRecord

wldReadCurrentCityRecord:

                ; Read currently viewed record from the EEPROM
                ld      HL, [CORECurrentADDAddress]
                ld      [DBExternalMemoryAddress], HL
                DB_OPEN_FILE

                ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
                ; Read the record header
                ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

                ; Setup the internal memory address to point record buffer
                ld      HL, #WLDCityGMTCode
                ld      [DBInternalMemoryAddress], HL

                ; Setup the record number to retrieve
                ld      HL, [CORECurrentASDAddress]
                add     HL, #WLDCURRENTCITYINDEXOFFSET
                ld      HL, [HL]
                ld      [DBRecordNumber], HL

                ; Setup the number of bytes to read -- read only the record header
                ld      L, #WLD_CITYRECORDHEADERSIZE
                ld      [DBLengthLo], L

                ; Read record header
                DB_READ_RECORD_RANDOMVAR

                ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
                ; Read the record city name
                ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

                ; Setup the record number to retrieve
                ld      HL, [CORECurrentASDAddress]
                add     HL, #WLDCURRENTCITYINDEXOFFSET
                ld      HL, [HL]
                ld      [DBRecordNumber], HL

                ; Set the internal memory message address to the city name buffer
                ld      HL, #WLDCityName
                ld      [DBInternalMemoryAddress], HL

                ; Set the Message length in the length variable
                ld      L, [WLDCityNameSize]
                ld      [DBLengthLo], L

                ; Set the message offset in the record
                ld      L, #WLD_CITYRECORDNAMEOFFSET
                ld      [DBRecordOffset], L

                ; Read the city name into buffer
                DB_READ_RECORD_WITHOFFSET_RANDOMVAR
                DB_CLOSE_FILE
                ret



                ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
                ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

                GLOBAL wldIncorporateOffsetIntoTimeStructure

wldIncorporateOffsetIntoTimeStructure:

                ; compute the city time
                ; HL - Base address of structure: sign, hour offset and minute offset

                push    HL

                ; copy the parameters to add or subtract from the time and date structure
                ld      B, #3
                ld      IX, #TempSign   
wldCopyNextDataStructure:
                ld      [IX], [HL]
                inc     IX
                inc     HL
                djr     NZ, wldCopyNextDataStructure


                ;clear all entries in the KRESBuffer
                ld      B,  #6
                ld      HL, #KRESBuffer
                KRES_CLEAR_N_BYTES

                ; Set the rollover value for hours
                ld      HL,     #KRESHrRollOverValue
                ld      [HL],   #UTLMAXHOURS

                ; setup the offsets to add or subtract from primary time
                ld      A, [TempHour]
                ld      [KRESHrBuffer], A
                ld      A, [TempMinute]
                ld      [KRESMinBuffer], A

                ; determine if we should add or suubtract the hour and minute offset
                ld      A, [TempSign]
                bit     A, #WLD_SIGNMASK
                jr      Z, wldAddOffsetRoutine

wldSubtractOffsetRoutine:


                ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
                ; SUBTRACT OFFSET FROM TIME STRUCTURE
                ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

                ; subtract hour and minute offset
                ld      HL, #WLDCityTimeMinute
                KRES_MINHR_SUB
                
                ; check if there if a day rollover has occured
                ld      A,  [KRESHourRolloverExcess]
                cp      A,  #00
                jr      Z,  wldIncorporateOffsetIntoTimeStructureExit
                
                ; subtract one day (the maximum) and correct for month, date, leap year
                ; number of days to subtract is already in A register
                ld      IY, #WLDTimeDateStructureFiller
                car     utlSubDaysToSearchRecordPlusCalcDOW
                jr      wldIncorporateOffsetIntoTimeStructureExit


wldAddOffsetRoutine:

                ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
                ; ADD OFFSET FROM TIME STRUCTURE
                ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

                ; add hour and minute offset
                ld      HL, #WLDCityTimeMinute
                KRES_MINHR_UPD
                
                ; check if there if a day rollover has occured
                bit     A,  #bKRESDayUpd
                jr      Z,  wldIncorporateOffsetIntoTimeStructureExit

                ; add one day (the maximum) and correct for month, date, leap year
                ld      A,  #UTL_ONE
                ld      IY, #WLDTimeDateStructureFiller
                car     utlAddDaysToSearchRecordPlusCalcDOW


wldIncorporateOffsetIntoTimeStructureExit:

                pop     HL
                ret


                ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
                ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


                GLOBAL  wldReformatGMTCode

wldReformatGMTCode:

                ;HL = address of the GMT code
                ld      A, [HL]
                and     A, #WLD_HOURMASK
                srl     A
                srl     A
                bit     [HL], #WLD_SIGNMASK
                jr      Z, hourisokay

                ;show the hour as a negative number
                neg     A

hourisokay:     

                ; check if we should compensate for DST
                bit     [HL], #WLD_DSTMASK
                jr      Z, hourisokay2

                ; add hour by 1 since DST is active for this timezone
                add     A, #1

hourisokay2:    

                ;put in the correct sign
                and     [HL], #@LOW(~WLD_SIGNMASK)
                bit     A, #WLD_SIGNMASK
                jr      Z, hourisokay3

                ; set the sign flag since the hour is still negative
                or      [HL], #WLD_SIGNMASK

                ; make the hour positive
                neg     A

hourisokay3:

                ;put in the correct hour
                and     [HL], #@LOW(~WLD_HOURMASK)
                sla     A
                sla     A
                or      [HL], A

                ;remove DST flag since it is already compensated
                and     [HL], #@LOW(~WLD_DSTMASK)

                ret
