; > Territories.Source ; History ; 28 Jan 1999 JB wrote module base ; 29 Jan 1999 JB changed to use paths ; added character tables ; 04 Feb 1999 JB wrote much of territory_convertdateandtime ; 05 Feb 1999 JB continued with territory_convertdateandtime ; 06 Feb 1999 JB finished territory_convertdateandtime ; wrote territory_convertstandard* ; 08 Feb 1999 JB wrote territory_converttimetoordinals ; 10 Feb 1999 JB wrote territory_converttimestringtoordinals ; 11 Feb 1999 JB wrote territory_convertordinalstotime ; wrote territory_selectkeyboardhandler ; 15 Feb 1999 JB wrote territory_collate ; 18 Feb 1999 JB wrote territory_readsymbols ; wrote territory_readcalendarinformation ; wrote territory_nametonumber ; wrote territory_transformstring ; 20 Feb 1999 JB removed help_and_command_keyword_table (was null) ; 25 Jan 2000 JB altered to use AAsm and rearranged files ; 12 Feb 2000 JB fixed divide to round downwards ; ; Misc stuff ; ; lower case registers r0 RN 0 r1 RN 1 r2 RN 2 r3 RN 3 r4 RN 4 r5 RN 5 r6 RN 6 r7 RN 7 r8 RN 8 r9 RN 9 r10 RN 10 r11 RN 11 r12 RN 12 r13 RN 13 r14 RN 14 r15 RN 15 pc RN 15 f0 FN 0 f1 FN 1 ; workspace offsets ^ 0 Entry_Table # 43 * 4 Time # 8 Ordinal_Buffer # 0 Centiseconds # 4 Seconds # 4 Minutes # 4 Hours # 4 Day # 4 Month # 4 Year # 4 WeekDay # 4 YearDay # 4 Workspace_Size # 0 ; swi numbers XOS_Module * &2001e XOS_ReadUnsigned * &20021 XOS_ConvertCardinal4 * &200d8 XTerritory_Register * &63041 XTerritory_Deregister * &63042 XTerritory_ReadCurrentTimeZone * &63048 XTerritory_ConvertTimeToUTCOrdinals * &63049 XTerritory_ConvertOrdinalsToTime * &63051 XTerritory_ReadCalendarInformation * &6305f XTerritory_NameToNumber * &63060 ; ; Module header ; start DCD 0 ;start_code DCD initialisation_code - start DCD finalisation_code - start DCD service_call_handler - start DCD title_string - start DCD help_string - start DCD help_and_command_keyword_table - start ; ; Title and help strings ; title_string DCB MODULE_NAME DCB 0 help_string DCB MODULE_TITLE DCB 9 DCB MODULE_VERSION DCB 0 ALIGN ; ; Initialisation code ; initialisation_code ; 1-207 STMFD r13!, {r14} LDR r0, [r12] TEQ r0, #0 BNE ic_allocated MOV r0, #6 MOV r3, #Workspace_Size SWI XOS_Module ; Claim (1-233) LDMVSFD r13!, {pc} STR r2, [r12] ic_allocated LDR r12, [r12] BL territory_register LDMVSFD r13!, {pc} LDMFD r13!, {pc}^ ; ; Finalisation code ; finalisation_code ; 1-209 STMFD r13!, {r14} MOV r0, #(TERRITORY_NUMBER) SWI XTerritory_Deregister ; 3-795 LDMVSFD r13!, {pc} LDMFD r13!, {pc}^ ; ; Service call handler ; service_call_handler ; 1-210 TEQ r1, #&64 ; Service_TerritoryManagerLoaded (3-790) MOVNES pc, r14 STMFD r13!, {r14} LDR r12, [r12] BL territory_register LDMVSFD r13!, {pc} LDMFD r13!, {pc}^ ; ; Help and command keyword table ; help_and_command_keyword_table DCB MODULE_NAME DCB 0 ALIGN DCD 0 ; no code DCD 0 ; information word DCD 0 ; syntax message DCD about - start ; help offset DCB 0 about DCB ABOUT_MESSAGE DCB 0 ALIGN ; ; Territory manager related ; territory_register STMFD r13!, {r0-r2, r14} ADRL r1, territory_readtimezones ; &4304A STR r1, [r12, #00] ADRL r1, territory_convertdateandtime ; &4304B STR r1, [r12, #04] ADRL r1, territory_convertstandarddateandtime ; &4304C STR r1, [r12, #08] ADRL r1, territory_convertstandarddate ; &4304D STR r1, [r12, #12] ADRL r1, territory_convertstandardtime ; &4304E STR r1, [r12, #16] ADRL r1, territory_converttimetoordinals ; &4304F STR r1, [r12, #20] ADRL r1, territory_converttimestringtoordinals ; &43050 STR r1, [r12, #24] ADRL r1, territory_convertordinalstotime ; &43051 STR r1, [r12, #28] ADRL r1, territory_alphabet ; &43052 STR r1, [r12, #32] ADRL r1, territory_alphabetidentifier ; &43053 STR r1, [r12, #36] ADRL r1, territory_selectkeyboardhandler ; &43054 STR r1, [r12, #40] ADRL r1, territory_writedirection ; &43055 STR r1, [r12, #44] ADRL r1, territory_characterpropertytable ; &43056 STR r1, [r12, #48] ADRL r1, territory_lowercasetable ; &43057 STR r1, [r12, #52] ADRL r1, territory_uppercasetable ; &43058 STR r1, [r12, #56] ADRL r1, territory_controltable ; &43059 STR r1, [r12, #60] ADRL r1, territory_plaintable ; &4305A STR r1, [r12, #64] ADRL r1, territory_valuetable ; &4305B STR r1, [r12, #68] ADRL r1, territory_representationtable ; &4305C STR r1, [r12, #72] ADRL r1, territory_collate ; &4305D STR r1, [r12, #76] ADRL r1, territory_readsymbols ; &4305E STR r1, [r12, #80] ADRL r1, territory_readcalendarinformation ; &4305F STR r1, [r12, #84] ADRL r1, territory_nametonumber ; &43060 STR r1, [r12, #88] ADRL r1, territory_transformstring ; &43061 STR r1, [r12, #92] ADRL r1, territory_reserved ; &43062 STR r1, [r12, #96] STR r1, [r12, #100] ; &43063 STR r1, [r12, #104] ; &43064 STR r1, [r12, #108] ; &43065 STR r1, [r12, #112] ; &43066 STR r1, [r12, #116] ; &43067 STR r1, [r12, #120] ; &43068 STR r1, [r12, #124] ; &43069 STR r1, [r12, #128] ; &4306A STR r1, [r12, #132] ; &4306B STR r1, [r12, #136] ; &4306C STR r1, [r12, #140] ; &4306D STR r1, [r12, #144] ; &4306E STR r1, [r12, #148] ; &4306F STR r1, [r12, #152] ; &43070 STR r1, [r12, #156] ; &43071 STR r1, [r12, #160] ; &43072 STR r1, [r12, #164] ; &43073 STR r1, [r12, #168] ; &43074 MOV r0, #TERRITORY_NUMBER MOV r1, r12 MOV r2, r12 SWI XTerritory_Register ADDVS r13, r13, #4 LDMVSFD r13!, {r1-r2, pc} LDMFD r13!, {r0-r2, pc}^ ; ; Territory module SWIs ; territory_readtimezones ; 3-806 ADR r0, timezone ADR r1, dstzone LDR r2, timeoffset LDR r3, dstoffset MOVS pc, r14 timezone DCB TIME_ZONE DCB 0 dstzone DCB DST_ZONE DCB 0 ALIGN timeoffset DCD TIME_OFFSET dstoffset DCD DST_OFFSET ; territory_convertdateandtime ; 3-807 STMFD r13!, {r5-r11, r14} MOV r7, r1 ; pointer to 5 byte UTC time MOV r8, r2 ; pointer to buffer MOV r9, r2 ; pointer to terminating 0 in buffer MOV r10, r3 ; number of bytes free in buffer MOV r11, r4 ; pointer to format string MOV r5, r4 ; pointer to format string position SWI XTerritory_ReadCurrentTimeZone ; 3-801 LDMVSFD r13!, {r5-r11, pc} MOV r6, r0 ; pointer to name of current time zone LDR r2, [r7] ; add time zone to convert UTC to local time LDRB r3, [r7, #4] ADDS r2, r2, r1 ADC r3, r3, #0 STR r2, [r12, #(Time + 0)] STRB r3, [r12, #(Time + 4)] ADD r1, r12, #Time ; convert 5 byte time to more useful ordinals ADD r2, r12, #Ordinal_Buffer SWI XTerritory_ConvertTimeToUTCOrdinals ; 3-802 LDMVSFD r13!, {r5-r11, pc} tcdat_loop CMP r10, #1 ; check space in buffer BLT tcdat_buffer_overflow LDRB r0, [r5], #1 ; get a byte TEQ r0, #"%" ; format field BEQ tcdat_field STRB r0, [r9], #1 ; other - add to buffer SUB r10, r10, #1 ; decrement free space CMP r0, #32 ; check for terminator (<32) BGE tcdat_loop MOV r0, r8 ; tidy up & exit SUB r1, r9, #1 MOV r2, r10 MOV r3, r11 MOV r4, r3 LDMFD r13!, {r5-r11, pc}^ tcdat_field ; 1-402 LDRB r0, [r5], #1 ; first byte TEQ r0, #"0" ; %0 - insert zero byte MOVEQ r0, #0 STREQB r0, [r9], #1 SUBEQ r10, r10, #1 BEQ tcdat_loop TEQ r0, #"%" ; %% - insert a % STREQB r0, [r9], #1 SUBEQ r10, r10, #1 BEQ tcdat_loop TEQ r0, #"z" ; z - without leading zeros TEQNE r0, #"Z" MOVEQ r4, #1 ; flag z MOVNE r4, #0 LDREQB r0, [r5], #1 ; get a replacement byte CMP r0, #32 ; unexpected termination BLS tcdat_unknown_field LDRB r1, [r5], #1 ; second byte CMP r1, #32 ; unexpected termination BLS tcdat_unknown_field ORR r0, r0, #32 ; convert to lowercase ORR r1, r1, #32 TEQ r0, #"c" ; cs TEQEQ r1, #"s" LDREQ r0, [r12, #Centiseconds] BEQ tcdat_add_number2 TEQ r0, #"s" ; se TEQEQ r1, #"e" LDREQ r0, [r12, #Seconds] BEQ tcdat_add_number2 TEQ r0, #"m" ; mi TEQEQ r1, #"i" LDREQ r0, [r12, #Minutes] BEQ tcdat_add_number2 TEQ r0, #"1" ; 12 TEQEQ r1, #"2" BNE tcdat_skip_12 LDR r0, [r12, #Hours] CMP r0, #12 ; convert to 12-hour SUBGT r0, r0, #12 TEQ r0, #0 ; 0h => 12h MOVEQ r0, #12 B tcdat_add_number2 tcdat_skip_12 TEQ r0, #"2" ; 24 TEQEQ r1, #"4" LDREQ r0, [r12, #Hours] BEQ tcdat_add_number2 TEQ r0, #"a" ; am TEQEQ r1, #"m" ; am/pm not implemented - not used much anyway BEQ tcdat_loop TEQ r0, #"p" ; pm TEQEQ r1, #"m" ; am/pm not implemented - not used much anyway BEQ tcdat_loop TEQ r0, #"w" ; we TEQEQ r1, #"e" BNE tcdat_skip_we LDR r1, [r12, #WeekDay] TEQ r1, #1 ; !!! ADREQL r0, sunday TEQ r1, #2 ADREQL r0, monday TEQ r1, #3 ADREQL r0, tuesday TEQ r1, #4 ADREQL r0, wednesday TEQ r1, #5 ADREQL r0, thursday TEQ r1, #6 ADREQL r0, friday TEQ r1, #7 ADREQL r0, saturday B tcdat_add_string tcdat_skip_we TEQ r0, #"w" ; w3 TEQEQ r1, #"3" BNE tcdat_skip_w3 LDR r1, [r12, #WeekDay] TEQ r1, #1 ; !!! ADREQL r0, sun TEQ r1, #2 ADREQL r0, mon TEQ r1, #3 ADREQL r0, tue TEQ r1, #4 ADREQL r0, wed TEQ r1, #5 ADREQL r0, thu TEQ r1, #6 ADREQL r0, fri TEQ r1, #7 ADREQL r0, sat B tcdat_add_string tcdat_skip_w3 TEQ r0, #"w" ; wn TEQEQ r1, #"n" BNE tcdat_skip_wn LDR r0, [r12, #WeekDay] SUB r0, r0, #1 ; convert to mon = 1, sun = 7 TEQ r0, #0 MOVEQ r0, #7 B tcdat_add_number1 tcdat_skip_wn TEQ r0, #"d" ; dy TEQEQ r1, #"y" LDREQ r0, [r12, #Day] BEQ tcdat_add_number2 TEQ r0, #"s" ; st TEQEQ r1, #"t" ; st field not implemented BEQ tcdat_loop TEQ r0, #"m" ; mo TEQEQ r1, #"o" BNE tcdat_skip_mo LDR r1, [r12, #Month] TEQ r1, #1 ADREQL r0, january TEQ r1, #2 ADREQL r0, february TEQ r1, #3 ADREQL r0, march TEQ r1, #4 ADREQL r0, april TEQ r1, #5 ADREQL r0, may TEQ r1, #6 ADREQL r0, june TEQ r1, #7 ADREQL r0, july TEQ r1, #8 ADREQL r0, august TEQ r1, #9 ADREQL r0, september TEQ r1, #10 ADREQL r0, october TEQ r1, #11 ADREQL r0, november TEQ r1, #12 ADREQL r0, december B tcdat_add_string tcdat_skip_mo TEQ r0, #"m" ; m3 TEQEQ r1, #"3" BNE tcdat_skip_m3 LDR r1, [r12, #Month] TEQ r1, #1 ADREQL r0, jan TEQ r1, #2 ADREQL r0, feb TEQ r1, #3 ADREQL r0, mar TEQ r1, #4 ADREQL r0, apr TEQ r1, #5 ADREQL r0, may3 TEQ r1, #6 ADREQL r0, jun TEQ r1, #7 ADREQL r0, jul TEQ r1, #8 ADREQL r0, aug TEQ r1, #9 ADREQL r0, sep TEQ r1, #10 ADREQL r0, oct TEQ r1, #11 ADREQL r0, nov TEQ r1, #12 ADREQL r0, dec B tcdat_add_string tcdat_skip_m3 TEQ r0, #"m" ; mn TEQEQ r1, #"n" LDREQ r0, [r12, #Month] BEQ tcdat_add_number2 TEQ r0, #"c" ; ce TEQEQ r1, #"e" LDREQ r0, [r12, #Year] MOVEQ r1, #100 BLEQ divide BEQ tcdat_add_number2 TEQ r0, #"y" ; yr TEQEQ r1, #"r" LDREQ r0, [r12, #Year] MOVEQ r3, r0 MOVEQ r1, #100 BLEQ divide MULEQ r2, r1, r0 ; work out the remainder SUBEQ r0, r3, r2 BEQ tcdat_add_number2 TEQ r0, #"w" ; wk TEQEQ r1, #"k" BNE tcdat_skip_wk LDR r0, [r12, #YearDay] LDR r1, [r12, #WeekDay] SUBS r1, r1, #1 ; compensate for sun = 1 MOVEQ r1, #7 SUB r1, r0, r1 ADD r0, r1, #7 MOV r1, #7 BL divide B tcdat_add_number2 tcdat_skip_wk TEQ r0, #"d" ; dn TEQEQ r1, #"n" LDREQ r0, [r12, #YearDay] BEQ tcdat_add_number3 TEQ r0, #"t" ; tz TEQEQ r1, #"z" MOVEQ r0, r6 BEQ tcdat_add_string ; drop through tcdat_unknown_field ADRL r0, unknown_field LDMFD r13!, {r5-r11, r14} ORRS pc, r14, #&10000000 tcdat_buffer_overflow ADRL r0, buffer_overflow LDMFD r13!, {r5-r11, r14} ORRS pc, r14, #&10000000 tcdat_add_number2 TEQ r4, #0 ; insert leading 0 if necessary BNE tcdat_add_number1 CMP r0, #10 MOVLT r1, #"0" STRLTB r1, [r9], #1 SUBLT r10, r10, #1 ; decrement free space ; dropped into by number2 tcdat_add_number1 MOV r1, r9 MOV r2, r10 SWI XOS_ConvertCardinal4 ; 1-469 LDMVSFD r13!, {r5-r11, pc} MOV r9, r1 MOV r10, r2 B tcdat_loop tcdat_add_number3 TEQ r4, #0 ; insert leading 0s if necessary BNE tcdat_add_number1 CMP r0, #100 BGE tcdat_add_number1 MOV r1, #"0" STRB r1, [r9], #1 SUB r10, r10, #1 ; decrement free space CMP r0, #10 BGE tcdat_add_number1 CMP r10, #1 ; check space in buffer BLT tcdat_buffer_overflow MOV r1, #"0" STRB r1, [r9], #1 SUB r10, r10, #1 ; decrement free space B tcdat_add_number1 tcdat_add_string LDRB r1, [r0], #1 ; source byte CMP r1, #32 BLT tcdat_loop STRB r1, [r9], #1 ; destination buffer SUB r10, r10, #1 CMP r10, #1 ; check space in buffer BLT tcdat_buffer_overflow B tcdat_add_string monday DCB MONDAY DCB 0 tuesday DCB TUESDAY DCB 0 wednesday DCB WEDNESDAY DCB 0 thursday DCB THURSDAY DCB 0 friday DCB FRIDAY DCB 0 saturday DCB SATURDAY DCB 0 sunday DCB SUNDAY DCB 0 mon DCB MON DCB 0 tue DCB TUE DCB 0 wed DCB WED DCB 0 thu DCB THU DCB 0 fri DCB FRI DCB 0 sat DCB SAT DCB 0 sun DCB SUN DCB 0 january DCB JANUARY DCB 0 february DCB FEBRUARY DCB 0 march DCB MARCH DCB 0 april DCB APRIL DCB 0 may DCB MAY DCB 0 june DCB JUNE DCB 0 july DCB JULY DCB 0 august DCB AUGUST DCB 0 september DCB SEPTEMBER DCB 0 october DCB OCTOBER DCB 0 november DCB NOVEMBER DCB 0 december DCB DECEMBER DCB 0 jan DCB JAN DCB 0 feb DCB FEB DCB 0 mar DCB MAR DCB 0 apr DCB APR DCB 0 may3 DCB MAY DCB 0 jun DCB JUN DCB 0 jul DCB JUL DCB 0 aug DCB AUG DCB 0 sep DCB SEP DCB 0 oct DCB OCT DCB 0 nov DCB NOV DCB 0 dec DCB DEC DCB 0 ALIGN ; territory_convertstandarddateandtime ; 3-809 STMFD r13!, {r3, r4, r14} ADR r4, dateandtime BL territory_convertdateandtime LDMVSFD r13!, {r3, r4, pc} LDMFD r13!, {r3, r4, pc}^ dateandtime DCB DATEANDTIME DCB 0 ALIGN ; territory_convertstandarddate ; 3-811 STMFD r13!, {r3, r4, r14} ADR r4, date BL territory_convertdateandtime LDMVSFD r13!, {r3, r4, pc} LDMFD r13!, {r3, r4, pc}^ date DCB DATE DCB 0 ALIGN ; territory_convertstandardtime ; 3-813 STMFD r13!, {r3, r4, r14} ADR r4, time BL territory_convertdateandtime LDMVSFD r13!, {r3, r4, pc} LDMFD r13!, {r3, r4, pc}^ time DCB TIME DCB 0 ALIGN ; territory_converttimetoordinals ; 3-815 STMFD r13!, {r1-r4, r14} MOV r4, r1 ; pointer to UTC time MOV r5, r2 ; pointer to buffer SWI XTerritory_ReadCurrentTimeZone ; 3-801 LDMVSFD r13!, {r1-r4, pc} LDR r2, [r4] ; add time zone to convert UTC to local time LDRB r3, [r4, #4] ADDS r2, r2, r1 ADC r3, r3, #0 STR r2, [r12, #(Time + 0)] STRB r3, [r12, #(Time + 4)] ADD r1, r12, #Time ; convert 5 byte time to more useful ordinals MOV r2, r5 SWI XTerritory_ConvertTimeToUTCOrdinals ; 3-802 LDMVSFD r13!, {r1-r4, pc} LDR r1, [r5, #28] ; correct day of week SUB r1, r1, #1 TEQ r1, #0 MOVEQ r1, #7 STR r1, [r5, #28] LDMFD r13!, {r1-r4, pc}^ ; territory_converttimestringtoordinals ; 3-817 STMFD r13!, {r1-r7, r14} MOV r0, #-1 STR r0, [r3, #0] STR r0, [r3, #4] STR r0, [r3, #8] STR r0, [r3, #12] STR r0, [r3, #16] STR r0, [r3, #20] STR r0, [r3, #24] MOV r4, r1 ; reason code MOV r5, r2 ; time STRing TEQ r4, #1 ; %24:%mi:%se BEQ tctsto_time TEQ r4, #2 ; %w3, %dy-%m3-%ce%yr TEQNE r4, #3 ; %w3, %dy-%m3-%ce%yr.%24:%mi:%se BEQ tctsto_date ADRL r0, unknown_format LDMFD r13!, {r1-r7, r14} ORRS pc, r14, #&10000000 tctsto_date LDRB r0, [r5], #1 ; skip %w3, CMP r0, #" " BLT tctsto_bad_string BNE tctsto_date MOV r0, #10 MOV r1, r5 SWI XOS_ReadUnsigned ; 1-448 LDMVSFD r13!, {r1-r7, pc} STR r2, [r3, #16] ; day ADD r5, r1, #1 ; skip - ADRL r0, jan MOV r2, #1 BL tctsto_compare ADRL r0, feb MOV r2, #2 BL tctsto_compare ADRL r0, mar MOV r2, #3 BL tctsto_compare ADRL r0, apr MOV r2, #4 BL tctsto_compare ADRL r0, may3 MOV r2, #5 BL tctsto_compare ADRL r0, jun MOV r2, #6 BL tctsto_compare ADRL r0, jul MOV r2, #7 BL tctsto_compare ADRL r0, aug MOV r2, #8 BL tctsto_compare ADRL r0, sep MOV r2, #9 BL tctsto_compare ADRL r0, oct MOV r2, #10 BL tctsto_compare ADRL r0, nov MOV r2, #11 BL tctsto_compare ADRL r0, dec MOV r2, #12 BL tctsto_compare B tctsto_bad_string tctsto_found STR r2, [r3, #20] ; month MOV r0, #10 SWI XOS_ReadUnsigned ; 1-448 LDMVSFD r13!, {r1-r7, pc} STR r2, [r3, #24] ; year ADD r5, r1, #1 TEQ r4, #2 LDMEQFD r13!, {r1-r7, pc}^ tctsto_time ; drop through MOV r0, #10 MOV r1, r5 SWI XOS_ReadUnsigned ; 1-448 LDMVSFD r13!, {r1-r7, pc} STR r2, [r3, #12] ; hours ADD r1, r5, #3 SWI XOS_ReadUnsigned ; 1-448 LDMVSFD r13!, {r1-r7, pc} STR r2, [r3, #8] ; minutes ADD r1, r5, #6 SWI XOS_ReadUnsigned ; 1-448 LDMVSFD r13!, {r1-r7, pc} STR r2, [r3, #4] ; seconds MOV r0, #0 STR r0, [r3, #0] ; centiseconds LDMFD r13!, {r1-r7, pc}^ tctsto_compare MOV r1, r5 tctsto_loop LDRB r6, [r1], #1 ; STRing LDRB r7, [r0], #1 ; month TEQ r7, #0 TEQEQ r6, #"-" BEQ tctsto_found TEQ r6, r7 MOVNE pc, r14 B tctsto_loop tctsto_bad_string ADRL r0, bad_string LDMFD r13!, {r1-r7, r14} ORRS pc, r14, #&10000000 ; territory_convertordinalstotime ; 3-819 STMFD r13!, {r14} MOV r0, #1 ; cheat: pass to UK territory SWI XTerritory_ConvertOrdinalsToTime LDMVSFD r13!, {pc} LDMFD r13!, {pc}^ ; territory_alphabet ; 3-821 MOV r0, #ALPHABET_NUMBER MOVS pc, r14 ; territory_alphabetidentifier ; 3-822 ADR r0, alphabet MOVS pc, r14 alphabet DCB ALPHABET_NAME DCB 0 ALIGN ; territory_selectkeyboardhandler ; 3-823 ; not implemented MOVS pc, r14 ; territory_writedirection ; 3-824 MOV r0, #WRITE_DIRECTION MOVS pc, r14 ; territory_characterpropertytable ; 3-826 ADRL r0, propertytables CMP r1, #10 ADRGTL r0, unknown_property ORRGTS pc, r14, #&10000000 ADD r0, r0, r1, LSL #5 MOVS pc, r14 ; territory_lowercasetable ; 3-828 ADRL r0, lowercasetable MOVS pc, r14 ; territory_uppercasetable ; 3-829 ADRL r0, uppercasetable MOVS pc, r14 ; territory_controltable ; 3-830 ADRL r0, controltable MOVS pc, r14 ; territory_plaintable ; 3-831 ADRL r0, plaintable MOVS pc, r14 ; territory_valuetable ; 3-832 ADRL r0, valuetable MOVS pc, r14 ; territory_representationtable ; 3-833 ADRL r0, representationtable MOVS pc, r14 ; territory_collate ; 3-834 STMFD r13!, {r1-r8, r14} ADRL r6, lowercasetable ADRL r7, plaintable ADRL r8, collatetable tc_loop LDRB r4, [r1], #1 LDRB r5, [r2], #1 CMP r4, #32 ; check for termination CMPLT r5, #32 MOVLT r0, #0 ; both end BLT tc_end CMP r4, #32 MOVLT r0, #-1 ; 1 ends BLT tc_end CMP r5, #32 MOVLT r0, #1 ; 2 ends BLT tc_end TST r3, #1 ; ignore case LDRNEB r4, [r6, r4] ; convert to lower case LDRNEB r5, [r6, r5] TST r3, #2 ; ignore accents LDRNEB r4, [r7, r4] ; convert to plain LDRNEB r5, [r7, r5] LDRB r4, [r8, r4] ; convert to sort priority LDRB r5, [r8, r5] CMP r4, r5 ; do comparison BEQ tc_loop MOVLT r0, #-1 MOVGT r0, #1 tc_end CMP r0, #0 ; set flags LDMFD r13!, {r1-r8, pc} ; no ^ ; territory_readsymbols ; 3-836 TEQ r1, #0 ; STRings ADREQ r0, trs_decimalpoint TEQ r1, #1 ADREQ r0, trs_thousands TEQ r1, #2 ADREQ r0, trs_digits TEQ r1, #3 ADREQ r0, trs_intcurrency TEQ r1, #4 ADREQ r0, trs_currency TEQ r1, #5 ADREQ r0, trs_moneydecimalpoint TEQ r1, #6 ADREQ r0, trs_moneythousands TEQ r1, #7 ADREQ r0, trs_moneydigits TEQ r1, #8 ADREQ r0, trs_moneypositive TEQ r1, #9 ADREQ r0, trs_moneynegative TEQ r1, #18 ADREQ r0, trs_listseparator TEQ r1, #10 ; values MOVEQ r0, #SYMBOL_MONEYINTFRACTION TEQ r1, #11 MOVEQ r0, #SYMBOL_MONEYFRACTION TEQ r1, #12 MOVEQ r0, #SYMBOL_CURRENCYPLACE TEQ r1, #13 MOVEQ r0, #SYMBOL_CURRENCYSPACE TEQ r1, #14 MOVEQ r0, #SYMBOL_CURRENCYPLACENEG TEQ r1, #15 MOVEQ r0, #SYMBOL_CURRENCYSPACENEG TEQ r1, #16 MOVEQ r0, #SYMBOL_MONEYPOS TEQ r1, #17 MOVEQ r0, #SYMBOL_MONEYNEG MOVS pc, r14 trs_decimalpoint DCB SYMBOL_DECIMALPOINT DCB 0 trs_thousands DCB SYMBOL_THOUSANDS DCB 0 trs_digits DCD SYMBOL_DIGITS trs_intcurrency DCB SYMBOL_INTCURRENCY DCB 0 trs_currency DCB SYMBOL_CURRENCY DCB 0 trs_moneydecimalpoint DCB SYMBOL_MONEYDECIMALPOINT DCB 0 trs_moneythousands DCB SYMBOL_MONEYTHOUSANDS DCB 0 trs_moneydigits DCD SYMBOL_MONEYDIGITS trs_moneypositive DCB SYMBOL_MONEYPOSITIVE DCB 0 trs_moneynegative DCB SYMBOL_MONEYNEGATIVE DCB 0 trs_listseparator DCB SYMBOL_LISTSEPARATOR DCB 0 ALIGN ; territory_readcalendarinformation ; 3-839 STMFD r13!, {r0-r2, r14} MOV r0, #1 ; pass to UK territory to get time SWI XTerritory_ReadCalendarInformation ADDVS r13, r13, #4 LDMVSFD r13!, {r1-r2, pc} MOV r0, #CALENDAR_FIRSTWORKDAY STR r0, [r2, #0] MOV r0, #CALENDAR_LASTWORKDAY STR r0, [r2, #4] MOV r0, #CALENDAR_MAXLENAMPM STR r0, [r2, #16] MOV r0, #CALENDAR_MAXLENWE STR r0, [r2, #20] MOV r0, #CALENDAR_MAXLENW3 STR r0, [r2, #24] MOV r0, #CALENDAR_MAXLENDY STR r0, [r2, #28] MOV r0, #CALENDAR_MAXLENST STR r0, [r2, #32] MOV r0, #CALENDAR_MAXLENMO STR r0, [r2, #36] MOV r0, #CALENDAR_MAXLENM3 STR r0, [r2, #40] MOV r0, #CALENDAR_MAXLENTZ STR r0, [r2, #44] LDMFD r13!, {r0-r2, pc}^ ; territory_nametonumber ; 3-841 STMFD r13!, {r14} MOV r0, #1 ; pass to UK territory SWI XTerritory_NameToNumber LDMVSFD r13!, {pc} LDMFD r13!, {pc}^ ; territory_transformstring ; 3-842 STMFD r13!, {r1-r5, r14} MOV r0, #0 ; find string length tts_loop LDRB r4, [r2, r0] ADD r0, r0, #1 CMP r4, #32 BGE tts_loop SUB r0, r0, #1 CMP r0, r3 ; buffer too short so exit LDMGEFD r13!, {r1-r5, pc}^ ADRL r5, collatetable tts_loop2 LDRB r4, [r2], #1 CMP r4, #32 BLT tts_end LDRB r4, [r5, r4] STRB r4, [r1], #1 B tts_loop2 tts_end MOV r4, #0 STRB r4, [r1] LDMFD r13!, {r1-r5, pc}^ ; territory_reserved ADR r0, unknown_SWI ORRS pc, r14, #&10000000 ; ; Division algorithm ; ; On entry ; r0 = value ; r1 = divisor ; On exit ; r0 = value divisor ; f0, f1 corrupted divide STMFD r13!, {r14} FLTS f0, r0 ; just use the FP :-) FLTS f1, r1 FDVS f0, f0, f1 FIXM r0, f0 LDMFD r13!, {pc}^ ; ; Error Blocks ; unknown_SWI DCD &43040 DCB "Unknown Territory SWI" DCB 0 ALIGN unknown_property DCD &43041 DCB "Unknown character property" DCB 0 ALIGN buffer_overflow DCD &2C1 DCB "Buffer overflow" DCB 0 ALIGN unknown_field DCD &2C2 DCB "Unknown '%' field" DCB 0 ALIGN unknown_format DCD &2C3 DCB "Unknown format type" DCB 0 ALIGN bad_string DCD &2C4 DCB "Bad time string" DCB 0 ; ; Data ; data ^ data propertytables # 352 lowercasetable # 256 uppercasetable # 256 controltable # 256 plaintable # 256 valuetable # 256 representationtable # 16 collatetable # 256 ALIGN ; END