From 4d65c704b6a652a66cbff653c192fcc8aca6ef30 Mon Sep 17 00:00:00 2001 From: sparky4 Date: Wed, 15 Jul 2015 14:30:26 -0500 Subject: [PATCH] seriously i want sound!!! bakapee! new file: 16/ADT2PLAY/FILE_ID.DIZ new file: 16/ADT2PLAY/ILOADERS.INC new file: 16/ADT2PLAY/MAKE.BAT new file: 16/ADT2PLAY/STRINGIO.PAS new file: 16/ADT2PLAY/STRUCTRS.INC new file: 16/ADT2PLAY/TXTSCRIO.PAS new file: 16/ADT2PLAY/a2player.c new file: 16/ADT2PLAY/a2player.h new file: 16/ADT2PLAY/a2player.pas new file: 16/ADT2PLAY/adt2play.c new file: 16/ADT2PLAY/adt2play.pas new file: 16/ADT2PLAY/parserio.pas new file: 16/ADT2PLAY/timerint.pas new file: 16/ADT2PLAY/typconst.inc new file: 16/ADT2PLAY/unpk_lib.pas modified: inputest.exe modified: makefile new file: sountest.exe modified: src/lib/16_in.c modified: src/lib/16_in.h modified: src/lib/16_snd.c modified: src/lib/16_snd.h new file: src/sountest.c --- 16/ADT2PLAY/FILE_ID.DIZ | 26 + 16/ADT2PLAY/ILOADERS.INC | 6274 ++++++++++++++++++++++++++++++++++++++ 16/ADT2PLAY/MAKE.BAT | 4 + 16/ADT2PLAY/STRINGIO.PAS | 825 +++++ 16/ADT2PLAY/STRUCTRS.INC | 2231 ++++++++++++++ 16/ADT2PLAY/TXTSCRIO.PAS | 1683 ++++++++++ 16/ADT2PLAY/a2player.c | 239 ++ 16/ADT2PLAY/a2player.h | 354 +++ 16/ADT2PLAY/a2player.pas | 4590 ++++++++++++++++++++++++++++ 16/ADT2PLAY/adt2play.c | 179 ++ 16/ADT2PLAY/adt2play.pas | 998 ++++++ 16/ADT2PLAY/parserio.pas | 305 ++ 16/ADT2PLAY/timerint.pas | 154 + 16/ADT2PLAY/typconst.inc | 12 + 16/ADT2PLAY/unpk_lib.pas | 977 ++++++ inputest.exe | Bin 42029 -> 41837 bytes makefile | 8 +- sountest.exe | Bin 0 -> 44275 bytes src/lib/16_in.c | 6 +- src/lib/16_in.h | 4 +- src/lib/16_snd.c | 86 + src/lib/16_snd.h | 22 + src/sountest.c | 58 + 23 files changed, 19030 insertions(+), 5 deletions(-) create mode 100644 16/ADT2PLAY/FILE_ID.DIZ create mode 100644 16/ADT2PLAY/ILOADERS.INC create mode 100644 16/ADT2PLAY/MAKE.BAT create mode 100644 16/ADT2PLAY/STRINGIO.PAS create mode 100644 16/ADT2PLAY/STRUCTRS.INC create mode 100644 16/ADT2PLAY/TXTSCRIO.PAS create mode 100644 16/ADT2PLAY/a2player.c create mode 100644 16/ADT2PLAY/a2player.h create mode 100644 16/ADT2PLAY/a2player.pas create mode 100644 16/ADT2PLAY/adt2play.c create mode 100644 16/ADT2PLAY/adt2play.pas create mode 100644 16/ADT2PLAY/parserio.pas create mode 100644 16/ADT2PLAY/timerint.pas create mode 100644 16/ADT2PLAY/typconst.inc create mode 100644 16/ADT2PLAY/unpk_lib.pas create mode 100644 sountest.exe create mode 100644 src/sountest.c diff --git a/16/ADT2PLAY/FILE_ID.DIZ b/16/ADT2PLAY/FILE_ID.DIZ new file mode 100644 index 00000000..8488454e --- /dev/null +++ b/16/ADT2PLAY/FILE_ID.DIZ @@ -0,0 +1,26 @@ + úù-ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ-¿ + ú subz3ro's ù + ù /´DLiB TR/´CK3R ][ G3 PLAYER ú + À-ÄÄÄÄÄ-ÄÄÄÄÄÄÄÄ--ùú 0.43 + + Ú-ÄÄÄÄÄÄÄÄÄÄÄÄ--ùú ú + ù HiGHLiGHTS ù + ú úù-ÄÄÄÄÄÄÄÄÄÄÄ-Ù + + þ powered by PMODE/W 1.33 + + þ 255 instruments + 128 patterns + 128 order list entries ú + ù + þ 87 effects, ³ + and 16 extended commands ³ + ³ + þ optional graphic interface ³ + ³ + þ replays A2M A2T AMD DFM ù + CFF FMK HSC MTK ú + RAD S3M SAT SA2 + ú XMS + ù + À-ÄÄÄÄÄÄÄ--ùú diff --git a/16/ADT2PLAY/ILOADERS.INC b/16/ADT2PLAY/ILOADERS.INC new file mode 100644 index 00000000..18a5e505 --- /dev/null +++ b/16/ADT2PLAY/ILOADERS.INC @@ -0,0 +1,6274 @@ +{ + function check_byte(var data; _byte: Byte; size: Longint): Boolean; + procedure insert_command(cmd,cmd2: Word; patterns: Byte; chan: Byte; exceptions: tByteSet); + procedure import_old_a2m_event1(patt,line,chan: Byte; old_chunk: tOLD_CHUNK; + processing_whole_song: Boolean); + procedure replace_old_adsr(patterns: Byte); + procedure import_old_a2m_patterns1(block: Byte; count: Byte); + procedure import_old_a2m_event2(patt,line,chan: Byte; old_chunk: tOLD_CHUNK); + procedure import_old_a2m_patterns2(block: Byte; count: Byte); + procedure import_old_flags; + procedure import_old_songdata(old_songdata: pOLD_FIXED_SONGDATA); + procedure import_old_instruments(old_songdata: pOLD_FIXED_SONGDATA; + new_songdata: pFIXED_SONGDATA; + instr,count: Byte); + procedure import_single_old_instrument(old_songdata: pOLD_FIXED_SONGDATA; + pos,instr: Byte); + procedure a2m_file_loader; + procedure a2t_file_loader; + procedure a2p_file_loader; + function dec2hex(dec: Byte): Byte; + function truncate_string(str: String): String; + procedure amd_file_loader; + procedure import_cff_event(patt,line,chan,byte0,byte1,byte2: Byte); + procedure import_cff_patterns(var data; patterns: Byte); + procedure cff_file_loader; + procedure import_standard_instrument(inst: Byte; var data); + procedure dfm_file_loader; + procedure import_hsc_event(patt,line,chan: Byte; event: Word); + procedure import_hsc_patterns(var data; patterns: Byte); + procedure import_hsc_instrument(inst: Byte; var data); + procedure hsc_file_loader; + procedure mtk_file_loader; + procedure rad_file_loader; + procedure fix_s3m_commands(patterns: Byte); + procedure fix_single_pattern(patt: Byte); + procedure s3m_file_loader; + procedure fix_fmk_commands(patterns: Byte); + procedure import_fin_instrument(inst: Byte; var data); + procedure fmk_file_loader; + procedure import_sat_instrument(inst: Byte; var data); + function import_sat_instrument_name(var data; inst: Byte): String; + procedure sat_file_loader; + function _sal(op1,op2: Word): Byte; + function _sar(op1,op2: Word): Byte; + procedure import_sa2_effect(effect,def1,def2: Byte; + var out1,out2: Byte); + procedure sa2_file_loader; +} + +function check_byte(var data; _byte: Byte; size: Longint): Boolean; + +var + result: Boolean; + +begin + asm + mov edi,[data] + mov ecx,size + jecxz @@1 + mov al,_byte + repnz scasb + jnz @@1 + mov result,TRUE + jmp @@2 +@@1: mov result,FALSE +@@2: + end; + check_byte := result; +end; + +procedure insert_command(cmd,cmd2: Word; patterns: Byte; chan: Byte; exceptions: tByteSet); + +var + chunk: tCHUNK; + temp2,temp3: Byte; + patt_break: Byte; + order,patt: Byte; + patts: String; + +begin + patts := ''; + order := 0; patt := BYTE_NULL; + + Repeat + If (Pos(CHR(songdata.pattern_order[order]),patts) <> 0) or + (songdata.pattern_order[order] >= $80) then Inc(order) + else + begin + patt := songdata.pattern_order[order]; + patt_break := songdata.patt_len; + For temp3 := 1 to songdata.nm_tracks do + For temp2 := 0 to PRED(songdata.patt_len) do + begin + get_chunk(patt,temp2,temp3,chunk); + If (chunk.effect_def in [ef_PositionJump,ef_PatternBreak]) or + (chunk.effect_def2 in [ef_PositionJump,ef_PatternBreak]) then + patt_break := temp2; + + If (temp3 = chan) and (temp2 <= patt_break) then + If (cmd2 = 0) then + If (chunk.effect_def+chunk.effect = 0) or + (chunk.effect_def in exceptions) then + begin + chunk.effect_def := HI(cmd); + chunk.effect := LO(cmd); + put_chunk(patt,temp2,temp3,chunk); + EXIT; + end + else If (chunk.effect_def2+chunk.effect2 = 0) or + (chunk.effect_def2 in exceptions) then + begin + chunk.effect_def2 := HI(cmd); + chunk.effect2 := LO(cmd); + put_chunk(patt,temp2,temp3,chunk); + EXIT; + end + else + else If ((chunk.effect_def+chunk.effect = 0) or + (chunk.effect_def in exceptions)) and + ((chunk.effect_def2+chunk.effect2 = 0) or + (chunk.effect_def2 in exceptions)) then + begin + chunk.effect_def := HI(cmd); + chunk.effect := LO(cmd); + chunk.effect_def2 := HI(cmd2); + chunk.effect2 := LO(cmd2); + put_chunk(patt,temp2,temp3,chunk); + EXIT; + end; + end; + Inc(order); + patts := patts+CHR(patt); + end; + until (patt >= patterns) or (order > $7f); +end; + +var + adsr_carrier: array[1..9] of Boolean; + +procedure import_old_a2m_event1(patt,line,chan: Byte; old_chunk: tOLD_CHUNK; + processing_whole_song: Boolean); + +const + fx_Arpeggio = $00; + fx_FSlideUp = $01; + fx_FSlideDown = $02; + fx_FSlideUpFine = $03; + fx_FSlideDownFine = $04; + fx_TonePortamento = $05; + fx_TPortamVolSlide = $06; + fx_Vibrato = $07; + fx_VibratoVolSlide = $08; + fx_SetOpIntensity = $09; + fx_SetInsVolume = $0a; + fx_PatternBreak = $0b; + fx_PatternJump = $0c; + fx_SetTempo = $0d; + fx_SetTimer = $0e; + fx_Extended = $0f; + fx_ex_DefAMdepth = $00; + fx_ex_DefVibDepth = $01; + fx_ex_DefWaveform = $02; + fx_ex_ManSlideUp = $03; + fx_ex_ManSlideDown = $04; + fx_ex_VSlideUp = $05; + fx_ex_VSlideDown = $06; + fx_ex_VSlideUpFine = $07; + fx_ex_VSlideDownFine = $08; + fx_ex_RetrigNote = $09; + fx_ex_SetAttckRate = $0a; + fx_ex_SetDecayRate = $0b; + fx_ex_SetSustnLevel = $0c; + fx_ex_SetReleaseRate = $0d; + fx_ex_SetFeedback = $0e; + fx_ex_ExtendedCmd = $0f; + +var + chunk: tCHUNK; + +begin + FillChar(chunk,SizeOf(chunk),0); + chunk.note := old_chunk.note; + chunk.instr_def := old_chunk.instr_def; + chunk.effect_def := old_chunk.effect_def; + chunk.effect := old_chunk.effect; + + Case old_chunk.effect_def of + fx_Arpeggio: chunk.effect_def := ef_Arpeggio; + fx_FSlideUp: chunk.effect_def := ef_FSlideUp; + fx_FSlideDown: chunk.effect_def := ef_FSlideDown; + fx_FSlideUpFine: chunk.effect_def := ef_FSlideUpFine; + fx_FSlideDownFine: chunk.effect_def := ef_FSlideDownFine; + fx_TonePortamento: chunk.effect_def := ef_TonePortamento; + fx_TPortamVolSlide: chunk.effect_def := ef_TPortamVolSlide; + fx_Vibrato: chunk.effect_def := ef_Vibrato; + fx_VibratoVolSlide: chunk.effect_def := ef_VibratoVolSlide; + fx_SetInsVolume: chunk.effect_def := ef_SetInsVolume; + fx_PatternJump: chunk.effect_def := ef_PositionJump; + fx_PatternBreak: chunk.effect_def := ef_PatternBreak; + fx_SetTempo: chunk.effect_def := ef_SetSpeed; + fx_SetTimer: chunk.effect_def := ef_SetTempo; + + fx_SetOpIntensity: + If (old_chunk.effect DIV 16 <> 0) then + begin + chunk.effect_def := ef_SetCarrierVol; + chunk.effect := 3+(old_chunk.effect DIV 16)*4; + end + else If (old_chunk.effect MOD 16 <> 0) then + begin + chunk.effect_def := ef_SetModulatorVol; + chunk.effect := 3+(old_chunk.effect MOD 16)*4; + end + else chunk.effect_def := 0; + + fx_Extended: + Case old_chunk.effect DIV 16 of + fx_ex_DefAMdepth: + begin + chunk.effect_def := ef_Extended; + chunk.effect := ef_ex_SetTremDepth*16+old_chunk.effect MOD 16; + end; + + fx_ex_DefVibDepth: + begin + chunk.effect_def := ef_Extended; + chunk.effect := ef_ex_SetVibDepth*16+old_chunk.effect MOD 16; + end; + + + fx_ex_DefWaveform: + begin + chunk.effect_def := ef_SetWaveform; + Case old_chunk.effect MOD 16 of + 0..3: chunk.effect := (old_chunk.effect MOD 16)*16+$0f; + 4..7: chunk.effect := $0f0+(old_chunk.effect MOD 16)-4; + end; + end; + + fx_ex_VSlideUp: + begin + chunk.effect_def := ef_VolSlide; + chunk.effect := (old_chunk.effect MOD 16)*16; + end; + + fx_ex_VSlideDown: + begin + chunk.effect_def := ef_VolSlide; + chunk.effect := old_chunk.effect MOD 16; + end; + + fx_ex_VSlideUpFine: + begin + chunk.effect_def := ef_VolSlideFine; + chunk.effect := (old_chunk.effect MOD 16)*16; + end; + + fx_ex_VSlideDownFine: + begin + chunk.effect_def := ef_VolSlideFine; + chunk.effect := old_chunk.effect MOD 16; + end; + + fx_ex_ManSlideUp: + begin + chunk.effect_def := ef_Extended2; + chunk.effect := ef_ex2_FineTuneUp*16+old_chunk.effect MOD 16; + end; + + fx_ex_ManSlideDown: + begin + chunk.effect_def := ef_Extended2; + chunk.effect := ef_ex2_FineTuneDown*16+old_chunk.effect MOD 16; + end; + + fx_ex_RetrigNote: + begin + chunk.effect_def := ef_RetrigNote; + chunk.effect := SUCC(old_chunk.effect MOD 16); + end; + + fx_ex_SetAttckRate: + begin + chunk.effect_def := ef_Extended; + chunk.effect := old_chunk.effect MOD 16; + If NOT adsr_carrier[chan] then + Inc(chunk.effect,ef_ex_SetAttckRateM*16) + else Inc(chunk.effect,ef_ex_SetAttckRateC*16); + end; + + fx_ex_SetDecayRate: + begin + chunk.effect_def := ef_Extended; + chunk.effect := old_chunk.effect MOD 16; + If NOT adsr_carrier[chan] then + Inc(chunk.effect,ef_ex_SetDecayRateM*16) + else Inc(chunk.effect,ef_ex_SetDecayRateC*16); + end; + + fx_ex_SetSustnLevel: + begin + chunk.effect_def := ef_Extended; + chunk.effect := old_chunk.effect MOD 16; + If NOT adsr_carrier[chan] then + Inc(chunk.effect,ef_ex_SetSustnLevelM*16) + else Inc(chunk.effect,ef_ex_SetSustnLevelC*16); + end; + + fx_ex_SetReleaseRate: + begin + chunk.effect_def := ef_Extended; + chunk.effect := old_chunk.effect MOD 16; + If NOT adsr_carrier[chan] then + Inc(chunk.effect,ef_ex_SetRelRateM*16) + else Inc(chunk.effect,ef_ex_SetRelRateC*16); + end; + + fx_ex_SetFeedback: + begin + chunk.effect_def := ef_Extended; + chunk.effect := ef_ex_SetFeedback*16+old_chunk.effect MOD 16; + end; + + fx_ex_ExtendedCmd: + If (old_chunk.effect MOD 16 in [0..9]) then + begin + chunk.effect_def := ef_Extended; + chunk.effect := ef_ex_ExtendedCmd*16; + + Case old_chunk.effect MOD 16 of + 0: Inc(chunk.effect,ef_ex_cmd_RSS); + 1: Inc(chunk.effect,ef_ex_cmd_LockVol); + 2: Inc(chunk.effect,ef_ex_cmd_UnlockVol); + 3: Inc(chunk.effect,ef_ex_cmd_LockVP); + 4: Inc(chunk.effect,ef_ex_cmd_UnlockVP); + + 5: begin + If processing_whole_song then chunk.effect_def := 255 + else chunk.effect_def := 0; + chunk.effect := 0; + adsr_carrier[chan] := TRUE; + end; + + 6: begin + If processing_whole_song then chunk.effect_def := 255 + else chunk.effect_def := 0; + If processing_whole_song then chunk.effect := 1 + else chunk.effect := 0; + adsr_carrier[chan] := FALSE; + end; + + 7: Inc(chunk.effect,ef_ex_cmd_VSlide_car); + 8: Inc(chunk.effect,ef_ex_cmd_VSlide_mod); + 9: Inc(chunk.effect,ef_ex_cmd_VSlide_def); + end; + end + else begin + chunk.effect_def := 0; + chunk.effect := 0; + end; + end; + end; + + put_chunk(patt,line,chan,chunk); +end; + +procedure replace_old_adsr(patterns: Byte); + +var + chunk,chunk2: tCHUNK; + temp2,temp3: Byte; + patt_break: Byte; + order,patt: Byte; + patts: String; + +begin + patts := ''; + FillChar(adsr_carrier,SizeOf(adsr_carrier),0); + + order := 0; patt := BYTE_NULL; + Repeat + If (songdata.pattern_order[order] >= $80) then Inc(order) + else + begin + patt := songdata.pattern_order[order]; + patt_break := BYTE_NULL; + For temp2 := 0 to $3f do + For temp3 := 1 to 9 do + begin + get_chunk(patt,temp2,temp3,chunk); + chunk2 := chunk; + + If (chunk.effect_def in [ef_PositionJump,ef_PatternBreak]) then + patt_break := temp2; + + If (chunk.effect_def in [$ff,ef_Extended]) then + begin + If (chunk.effect_def = $ff) then + begin + chunk2.effect_def := 0; + chunk2.effect := 0; + + If (temp2 <= patt_break) then + Case chunk.effect of + 0: adsr_carrier[temp3] := TRUE; + 1: adsr_carrier[temp3] := FALSE; + end; + end; + + If (chunk.effect_def = ef_Extended) then + Case chunk.effect DIV 16 of + ef_ex_SetAttckRateM, + ef_ex_SetAttckRateC: + If adsr_carrier[temp3] then + chunk2.effect := ef_ex_SetAttckRateC*16+chunk.effect MOD 16 + else chunk2.effect := ef_ex_SetAttckRateM*16+chunk.effect MOD 16; + + ef_ex_SetDecayRateM, + ef_ex_SetDecayRateC: + If adsr_carrier[temp3] then + chunk2.effect := ef_ex_SetDecayRateC*16+chunk.effect MOD 16 + else chunk2.effect := ef_ex_SetDecayRateM*16+chunk.effect MOD 16; + + ef_ex_SetSustnLevelM, + ef_ex_SetSustnLevelC: + If adsr_carrier[temp3] then + chunk2.effect := ef_ex_SetSustnLevelC*16+chunk.effect MOD 16 + else chunk2.effect := ef_ex_SetSustnLevelM*16+chunk.effect MOD 16; + + ef_ex_SetRelRateM, + ef_ex_SetRelRateC: + If adsr_carrier[temp3] then + chunk2.effect := ef_ex_SetRelRateC*16+chunk.effect MOD 16 + else chunk2.effect := ef_ex_SetRelRateM*16+chunk.effect MOD 16; + end; + + If (Pos(CHR(songdata.pattern_order[order]),patts) = 0) then + If (chunk.effect_def <> chunk2.effect_def) or + (chunk.effect <> chunk2.effect) then + put_chunk(patt,temp2,temp3,chunk2); + end; + end; + Inc(order); + patts := patts+CHR(patt); + end; + until (patt >= patterns) or (order > $7f); +end; + +procedure import_old_a2m_patterns1(block: Byte; count: Byte); + +procedure get_old_chunk(pattern,line,channel: Byte; var chunk: tOLD_CHUNK); +begin chunk := old_hash_buffer[pattern][line][channel]; end; + +var + patt,line,chan: Byte; + chunk: tOLD_CHUNK; + +begin { import_old_a2m_patterns1 } + For patt := 0 to max(PRED(count),15) do + For line := 0 to $3f do + For chan := 1 to 9 do + begin + get_old_chunk(patt,line,chan,chunk); + import_old_a2m_event1(block*16+patt,line,chan,chunk,TRUE); + end; +end; + +procedure import_old_a2m_event2(patt,line,chan: Byte; old_chunk: tOLD_CHUNK); + +const + ef_ManualFSlide = 22; + +var + chunk: tCHUNK; + +begin + FillChar(chunk,SizeOf(chunk),0); + chunk.note := old_chunk.note; + chunk.instr_def := old_chunk.instr_def; + + If (old_chunk.effect_def <> ef_ManualFSlide) then + begin + chunk.effect_def := old_chunk.effect_def; + chunk.effect := old_chunk.effect; + end + else If (old_chunk.effect DIV 16 <> 0) then + begin + chunk.effect_def := ef_Extended2; + chunk.effect := ef_ex2_FineTuneUp*16+old_chunk.effect DIV 16; + end + else begin + chunk.effect_def := ef_Extended2; + chunk.effect := ef_ex2_FineTuneDown*16+old_chunk.effect MOD 16; + end; + + put_chunk(patt,line,chan,chunk); +end; + +procedure import_old_a2m_patterns2(block: Byte; count: Byte); + +procedure get_old_chunk(pattern,line,channel: Byte; var chunk: tOLD_CHUNK); +begin chunk := hash_buffer[pattern][channel][line]; end; + +var + patt,line,chan: Byte; + chunk: tOLD_CHUNK; + +begin { import_old_a2m_patterns2 } + For patt := 0 to max(PRED(count),7) do + For line := 0 to $3f do + For chan := 1 to 18 do + begin + get_old_chunk(patt,line,chan,chunk); + import_old_a2m_event2(block*8+patt,line,chan,chunk); + end; +end; + +procedure import_old_flags; + +var + temp: Byte; + +begin + If (songdata.common_flag OR 2 = songdata.common_flag) then + For temp := 1 to 20 do + songdata.lock_flags[temp] := songdata.lock_flags[temp] OR $10; + + If (songdata.common_flag OR 4 = songdata.common_flag) then + For temp := 1 to 20 do + songdata.lock_flags[temp] := songdata.lock_flags[temp] OR $20; + + If (songdata.common_flag OR $20 = songdata.common_flag) then + For temp := 1 to 20 do + songdata.lock_flags[temp] := songdata.lock_flags[temp] AND NOT 3; +end; + +procedure import_old_songdata(old_songdata: pOLD_FIXED_SONGDATA); + +var + temp: Byte; + +begin + songdata.songname := old_songdata^.songname; + songdata.composer := old_songdata^.composer; + + For temp := 1 to 250 do + begin + songdata.instr_names[temp] := old_songdata^.instr_names[temp]; + songdata.instr_data[temp].fm_data := old_songdata^.instr_data[temp].fm_data; + songdata.instr_data[temp].panning := old_songdata^.instr_data[temp].panning; + songdata.instr_data[temp].fine_tune := old_songdata^.instr_data[temp].fine_tune; + songdata.instr_data[temp].perc_voice := 0; + end; + + Move(old_songdata^.pattern_order, + songdata.pattern_order, + SizeOf(old_songdata^.pattern_order)); + + songdata.tempo := old_songdata^.tempo; + songdata.speed := old_songdata^.speed; + songdata.common_flag := old_songdata^.common_flag; + import_old_flags; +end; + + +procedure a2m_file_loader; + +type + tOLD_HEADER = Record + ident: array[1..10] of Char; + crc32: Longint; + ffver: Byte; + patts: Byte; + b0len: Word; + b1len: Word; + b2len: Word; + b3len: Word; + b4len: Word; + b5len: Word; + b6len: Word; + b7len: Word; + b8len: Word; + end; +type + tHEADER = Record + ident: array[1..10] of Char; + crc32: Longint; + ffver: Byte; + patts: Byte; + b0len: Longint; + b1len: array[0..15] of Longint; + end; + +const + id = '_A2module_'; + +const + old_a2m_header_size = 26; + +var + f: File; + header: tHEADER; + header2: tOLD_HEADER; + temp,temp2: Longint; + crc: Longint; + xlen: array[0..6] of Word; + +begin + {$i-} + Assign(f,songdata_source); + ResetF(f); + {$i+} + If (IOresult <> 0) then + begin + CloseF(f); + EXIT; + end; + + FillChar(buf1,SizeOf(buf1),0); + BlockReadF(f,header,SizeOf(header),temp); + If NOT ((temp = SizeOf(header)) and (header.ident = id)) then + begin + CloseF(f); + EXIT; + end; + + load_flag := $7f; + If NOT (header.ffver in [1..11]) then + begin + CloseF(f); + EXIT; + end; + + init_old_songdata; + If (header.ffver in [1..4]) then + begin + FillChar(adsr_carrier,SizeOf(adsr_carrier),BYTE(FALSE)); + ResetF(f); + BlockReadF(f,header2,SizeOf(header2),temp); + If NOT ((temp = SizeOf(header2)) and (header2.ident = id)) then + begin + CloseF(f); + EXIT; + end; + + xlen[0] := header2.b2len; + xlen[1] := header2.b3len; + xlen[2] := header2.b4len; + + SeekF(f,old_a2m_header_size); + If (IOresult <> 0) then + begin + CloseF(f); + EXIT; + end; + + crc := DWORD_NULL; + BlockReadF(f,buf1,header2.b0len,temp); + If NOT (temp = header2.b0len) then + begin + CloseF(f); + EXIT; + end; + + crc := Update32(buf1,temp,crc); + BlockReadF(f,buf1,header2.b1len,temp); + If NOT (temp = header2.b1len) then + begin + CloseF(f); + EXIT; + end; + + crc := Update32(buf1,temp,crc); + For temp2 := 0 to 2 do + If ((header2.patts-1) DIV 16 > temp2) then + begin + BlockReadF(f,buf1,xlen[temp2],temp); + If NOT (temp = xlen[temp2]) then + begin + CloseF(f); + EXIT; + end; + crc := Update32(buf1,temp,crc); + end; + + crc := Update32(header2.b0len,2,crc); + crc := Update32(header2.b1len,2,crc); + + For temp2 := 0 to 2 do + crc := Update32(xlen[temp2],2,crc); + + If (crc <> header2.crc32) then + begin + CloseF(f); + EXIT; + end; + + init_songdata; + load_flag := 0; + + songdata.patt_len := 64; + If adjust_tracks then songdata.nm_tracks := 9 + else If (songdata.nm_tracks < 9) then songdata.nm_tracks := 9; + + SeekF(f,old_a2m_header_size); + If (IOresult <> 0) then + begin + CloseF(f); + EXIT; + end; + + BlockReadF(f,buf1,header2.b0len,temp); + If NOT (temp = header2.b0len) then + begin + CloseF(f); + EXIT; + end; + + Case header2.ffver of + 4: Move(buf1,old_songdata,header2.b0len); + 3: LZSS_decompress(buf1,old_songdata,header2.b0len); + 2: LZW_decompress(buf1,old_songdata); + 1: SIXPACK_decompress(buf1,old_songdata,header2.b0len); + end; + + For temp := 1 to 250 do + old_songdata.instr_data[temp].panning := 0; + + BlockReadF(f,buf1,header2.b1len,temp); + If NOT (temp = header2.b1len) then + begin + CloseF(f); + EXIT; + end; + + Case header2.ffver of + 4: Move(buf1,old_hash_buffer,header2.b1len); + 3: LZSS_decompress(buf1,old_hash_buffer,header2.b1len); + 2: LZW_decompress(buf1,old_hash_buffer); + 1: SIXPACK_decompress(buf1,old_hash_buffer,header2.b1len); + end; + import_old_a2m_patterns1(0,16); + + For temp2 := 0 to 2 do + If ((header2.patts-1) DIV 16 > temp2) then + begin + BlockReadF(f,buf1,xlen[temp2],temp); + If NOT (temp = xlen[temp2]) then + begin + CloseF(f); + EXIT; + end; + + Case header2.ffver of + 4: Move(buf1,old_hash_buffer,xlen[temp2]); + 3: LZSS_decompress(buf1,old_hash_buffer,xlen[temp2]); + 2: LZW_decompress(buf1,old_hash_buffer); + 1: SIXPACK_decompress(buf1,old_hash_buffer,xlen[temp2]); + end; + import_old_a2m_patterns1(SUCC(temp2),16); + end; + + replace_old_adsr(header2.patts); + import_old_songdata(Addr(old_songdata)); + end; + + If (header.ffver in [5..8]) then + begin + ResetF(f); + BlockReadF(f,header2,SizeOf(header2),temp); + If NOT ((temp = SizeOf(header2)) and (header2.ident = id)) then + begin + CloseF(f); + EXIT; + end; + + xlen[0] := header2.b2len; + xlen[1] := header2.b3len; + xlen[2] := header2.b4len; + xlen[3] := header2.b5len; + xlen[4] := header2.b6len; + xlen[5] := header2.b7len; + xlen[6] := header2.b8len; + + crc := DWORD_NULL; + BlockReadF(f,buf1,header2.b0len,temp); + If NOT (temp = header2.b0len) then + begin + CloseF(f); + EXIT; + end; + + crc := Update32(buf1,temp,crc); + BlockReadF(f,buf1,header2.b1len,temp); + If NOT (temp = header2.b1len) then + begin + CloseF(f); + EXIT; + end; + + crc := Update32(buf1,temp,crc); + For temp2 := 0 to 6 do + If ((header2.patts-1) DIV 8 > temp2) then + begin + BlockReadF(f,buf1,xlen[temp2],temp); + If NOT (temp = xlen[temp2]) then + begin + CloseF(f); + EXIT; + end; + crc := Update32(buf1,temp,crc); + end; + + crc := Update32(header2.b0len,2,crc); + crc := Update32(header2.b1len,2,crc); + + For temp2 := 0 to 6 do + crc := Update32(xlen[temp2],2,crc); + + If (crc <> header2.crc32) then + begin + CloseF(f); + EXIT; + end; + + init_songdata; + load_flag := 0; + + songdata.patt_len := 64; + If adjust_tracks then songdata.nm_tracks := 18 + else If (songdata.nm_tracks < 18) then songdata.nm_tracks := 18; + + SeekF(f,SizeOf(header2)); + If (IOresult <> 0) then + begin + CloseF(f); + EXIT; + end; + + BlockReadF(f,buf1,header2.b0len,temp); + If NOT (temp = header2.b0len) then + begin + CloseF(f); + EXIT; + end; + + Case header2.ffver of + 8: Move(buf1,old_songdata,header2.b0len); + 7: LZSS_decompress(buf1,old_songdata,header2.b0len); + 6: LZW_decompress(buf1,old_songdata); + 5: SIXPACK_decompress(buf1,old_songdata,header2.b0len); + end; + + BlockReadF(f,buf1,header2.b1len,temp); + If NOT (temp = header2.b1len) then + begin + CloseF(f); + EXIT; + end; + + Case header2.ffver of + 8: Move(buf1,hash_buffer,header2.b1len); + 7: LZSS_decompress(buf1,hash_buffer,header2.b1len); + 6: LZW_decompress(buf1,hash_buffer); + 5: SIXPACK_decompress(buf1,hash_buffer,header2.b1len); + end; + import_old_a2m_patterns2(0,8); + + For temp2 := 0 to 6 do + If ((header2.patts-1) DIV 8 > temp2) then + begin + BlockReadF(f,buf1,xlen[temp2],temp); + If NOT (temp = xlen[temp2]) then + begin + CloseF(f); + EXIT; + end; + + Case header2.ffver of + 8: Move(buf1,hash_buffer,header2.b2len); + 7: LZSS_decompress(buf1,hash_buffer,header2.b2len); + 6: LZW_decompress(buf1,hash_buffer); + 5: SIXPACK_decompress(buf1,hash_buffer,header2.b2len); + end; + import_old_a2m_patterns2(SUCC(temp2),8); + end; + import_old_songdata(Addr(old_songdata)); + end; + + If (header.ffver in [9,10,11]) then + begin + crc := DWORD_NULL; + BlockReadF(f,buf1,header.b0len,temp); + If NOT (temp = header.b0len) then + begin + CloseF(f); + EXIT; + end; + + crc := Update32(buf1,temp,crc); + BlockReadF(f,buf1,header.b1len[0],temp); + If NOT (temp = header.b1len[0]) then + begin + CloseF(f); + EXIT; + end; + + crc := Update32(buf1,temp,crc); + For temp2 := 1 to 15 do + If ((header.patts-1) DIV 8 > PRED(temp2)) then + begin + BlockReadF(f,buf1,header.b1len[temp2],temp); + If NOT (temp = header.b1len[temp2]) then + begin + CloseF(f); + EXIT; + end; + crc := Update32(buf1,temp,crc); + end; + + crc := Update32(header.b0len,2,crc); + For temp2 := 0 to 15 do + crc := Update32(header.b1len[temp2],2,crc); + + If (crc <> header.crc32) then + begin + CloseF(f); + EXIT; + end; + + init_songdata; + load_flag := 0; + + SeekF(f,SizeOf(header)); + If (IOresult <> 0) then + begin + CloseF(f); + EXIT; + end; + + BlockReadF(f,buf1,header.b0len,temp); + If NOT (temp = header.b0len) then + begin + CloseF(f); + EXIT; + end; + + APACK_decompress(buf1,songdata); + BlockReadF(f,buf1,header.b1len[0],temp); + If NOT (temp = header.b1len[0]) then + begin + CloseF(f); + EXIT; + end; + + If (header.ffver = 9) then + import_old_flags; + + + APACK_decompress(buf1,pattdata^[0]); + For temp2 := 1 to 15 do + If ((header.patts-1) DIV 8 > PRED(temp2)) then + begin + BlockReadF(f,buf1,header.b1len[temp2],temp); + If NOT (temp = header.b1len[temp2]) then + begin + CloseF(f); + EXIT; + end; + + If (temp2*8+8 <= max_patterns) then + APACK_decompress(buf1,pattdata^[temp2]) + else limit_exceeded := TRUE; + end; + end; + + speed := songdata.speed; + tempo := songdata.tempo; + + CloseF(f); + songdata_title := NameOnly(songdata_source); + Case header.ffver of + 1..4: load_flag := 1; + else load_flag := 2; + end; +end; + +procedure a2t_file_loader; + +type + tOLD_HEADER1 = Record + ident: array[1..15] of Char; + crc32: Longint; + ffver: Byte; + patts: Byte; + tempo: Byte; + speed: Byte; + b0len: Word; + b1len: Word; + b2len: Word; + b3len: Word; + b4len: Word; + b5len: Word; + end; +type + tOLD_HEADER2 = Record + ident: array[1..15] of Char; + crc32: Longint; + ffver: Byte; + patts: Byte; + tempo: Byte; + speed: Byte; + cflag: Byte; + b0len: Word; + b1len: Word; + b2len: Word; + b3len: Word; + b4len: Word; + b5len: Word; + b6len: Word; + b7len: Word; + b8len: Word; + b9len: Word; + end; +type + tOLD_HEADER3 = Record + ident: array[1..15] of Char; + crc32: Longint; + ffver: Byte; + patts: Byte; + tempo: Byte; + speed: Byte; + cflag: Byte; + patln: Word; + nmtrk: Byte; + mcspd: Word; + b0len: Longint; + b1len: Longint; + b2len: Longint; + b3len: Longint; + b4len: array[0..15] of Longint; + end; +type + tOLD_HEADER4 = Record + ident: array[1..15] of Char; + crc32: Longint; + ffver: Byte; + patts: Byte; + tempo: Byte; + speed: Byte; + cflag: Byte; + patln: Word; + nmtrk: Byte; + mcspd: Word; + is4op: Byte; + locks: array[1..20] of Byte; + b0len: Longint; + b1len: Longint; + b2len: Longint; + b3len: Longint; + b4len: array[0..15] of Longint; + end; +type + tHEADER = Record + ident: array[1..15] of Char; + crc32: Longint; + ffver: Byte; + patts: Byte; + tempo: Byte; + speed: Byte; + cflag: Byte; + patln: Word; + nmtrk: Byte; + mcspd: Word; + is4op: Byte; + locks: array[1..20] of Byte; + b0len: Longint; + b1len: Longint; + b2len: Longint; + b3len: Longint; + b4len: Longint; + b5len: array[0..15] of Longint; + end; +const + id = '_A2tiny_module_'; + +var + f: File; + header: tHEADER; + header2: tOLD_HEADER1; + header3: tOLD_HEADER2; + header4: tOLD_HEADER3; + header5: tOLD_HEADER4; + temp,temp2: Longint; + crc: Longint; + xlen: array[0..6] of Word; + +begin + {$i-} + Assign(f,songdata_source); + ResetF(f); + {$i+} + If (IOresult <> 0) then + begin + CloseF(f); + EXIT; + end; + + FillChar(buf1,SizeOf(buf1),0); + BlockReadF(f,header,SizeOf(header),temp); + If NOT ((temp = SizeOf(header)) and (header.ident = id)) then + begin + CloseF(f); + EXIT; + end; + + load_flag := $7f; + If NOT (header.ffver in [1..11]) then + begin + CloseF(f); + EXIT; + end; + + init_old_songdata; + If (header.ffver in [1..4]) then + begin + FillChar(adsr_carrier,SizeOf(adsr_carrier),BYTE(FALSE)); + ResetF(f); + BlockReadF(f,header2,SizeOf(header2),temp); + If NOT ((temp = SizeOf(header2)) and (header2.ident = id)) then + begin + CloseF(f); + EXIT; + end; + + xlen[0] := header2.b3len; + xlen[1] := header2.b4len; + xlen[2] := header2.b5len; + + crc := DWORD_NULL; + BlockReadF(f,buf1,header2.b0len,temp); + If NOT (temp = header2.b0len) then + begin + CloseF(f); + EXIT; + end; + + crc := Update32(buf1,temp,crc); + BlockReadF(f,buf1,header2.b1len,temp); + If NOT (temp = header2.b1len) then + begin + CloseF(f); + EXIT; + end; + + crc := Update32(buf1,temp,crc); + BlockReadF(f,buf1,header2.b2len,temp); + If NOT (temp = header2.b2len) then + begin + CloseF(f); + EXIT; + end; + + crc := Update32(buf1,temp,crc); + For temp2 := 0 to 2 do + If ((header2.patts-1) DIV 16 > temp2) then + begin + BlockReadF(f,buf1,xlen[temp2],temp); + If NOT (temp = xlen[temp2]) then + begin + CloseF(f); + EXIT; + end; + crc := Update32(buf1,temp,crc); + end; + + crc := Update32(header2.b0len,2,crc); + crc := Update32(header2.b1len,2,crc); + crc := Update32(header2.b2len,2,crc); + + For temp2 := 0 to 2 do + crc := Update32(xlen[temp2],2,crc); + + If (crc <> header2.crc32) then + begin + CloseF(f); + EXIT; + end; + + init_songdata; + load_flag := 0; + + songdata.patt_len := 64; + If adjust_tracks then songdata.nm_tracks := 9 + else If (songdata.nm_tracks < 9) then songdata.nm_tracks := 9; + + SeekF(f,SizeOf(header2)); + If (IOresult <> 0) then + begin + CloseF(f); + EXIT; + end; + + BlockReadF(f,buf1,header2.b0len,temp); + If NOT (temp = header2.b0len) then + begin + CloseF(f); + EXIT; + end; + + old_songdata.tempo := header2.tempo; + old_songdata.speed := header2.speed; + + Case header2.ffver of + 4: Move(buf1,old_songdata.instr_data,header2.b0len); + 3: LZSS_decompress(buf1,old_songdata.instr_data,header2.b0len); + 2: LZW_decompress(buf1,old_songdata.instr_data); + 1: SIXPACK_decompress(buf1,old_songdata.instr_data,header2.b0len); + end; + + For temp := 1 to 250 do + old_songdata.instr_data[temp].panning := 0; + + BlockReadF(f,buf1,header2.b1len,temp); + If NOT (temp = header2.b1len) then + begin + CloseF(f); + EXIT; + end; + + Case header2.ffver of + 4: Move(buf1,old_songdata.pattern_order,header2.b1len); + 3: LZSS_decompress(buf1,old_songdata.pattern_order,header2.b1len); + 2: LZW_decompress(buf1,old_songdata.pattern_order); + 1: SIXPACK_decompress(buf1,old_songdata.pattern_order,header2.b1len); + end; + + BlockReadF(f,buf1,header2.b2len,temp); + If NOT (temp = header2.b2len) then + begin + CloseF(f); + EXIT; + end; + + FillChar(old_hash_buffer,SizeOf(old_hash_buffer),0); + Case header2.ffver of + 4: Move(buf1,old_hash_buffer,header2.b2len); + 3: LZSS_decompress(buf1,old_hash_buffer,header2.b2len); + 2: LZW_decompress(buf1,old_hash_buffer); + 1: SIXPACK_decompress(buf1,old_hash_buffer,header2.b2len); + end; + import_old_a2m_patterns1(0,16); + + For temp2 := 0 to 2 do + If ((header2.patts-1) DIV 16 > temp2) then + begin + BlockReadF(f,buf1,xlen[temp2],temp); + If NOT (temp = xlen[temp2]) then + begin + CloseF(f); + EXIT; + end; + + FillChar(old_hash_buffer,SizeOf(old_hash_buffer),0); + Case header2.ffver of + 4: Move(buf1,old_hash_buffer,header2.b3len); + 3: LZSS_decompress(buf1,old_hash_buffer,header2.b3len); + 2: LZW_decompress(buf1,old_hash_buffer); + 1: SIXPACK_decompress(buf1,old_hash_buffer,header2.b3len); + end; + import_old_a2m_patterns1(SUCC(temp2),16); + end; + + replace_old_adsr(header2.patts); + import_old_songdata(Addr(old_songdata)); + end; + + If (header.ffver in [5..8]) then + begin + ResetF(f); + BlockReadF(f,header3,SizeOf(header3),temp); + If NOT ((temp = SizeOf(header3)) and (header3.ident = id)) then + begin + CloseF(f); + EXIT; + end; + + xlen[0] := header3.b3len; + xlen[1] := header3.b4len; + xlen[2] := header3.b5len; + xlen[3] := header3.b6len; + xlen[4] := header3.b7len; + xlen[5] := header3.b8len; + xlen[6] := header3.b9len; + + crc := DWORD_NULL; + BlockReadF(f,buf1,header3.b0len,temp); + If NOT (temp = header3.b0len) then + begin + CloseF(f); + EXIT; + end; + + crc := Update32(buf1,temp,crc); + BlockReadF(f,buf1,header3.b1len,temp); + If NOT (temp = header3.b1len) then + begin + CloseF(f); + EXIT; + end; + + crc := Update32(buf1,temp,crc); + BlockReadF(f,buf1,header3.b2len,temp); + If NOT (temp = header3.b2len) then + begin + CloseF(f); + EXIT; + end; + + crc := Update32(buf1,temp,crc); + For temp2 := 0 to 6 do + If ((header3.patts-1) DIV 8 > temp2) then + begin + BlockReadF(f,buf1,xlen[temp2],temp); + If NOT (temp = xlen[temp2]) then + begin + CloseF(f); + EXIT; + end; + crc := Update32(buf1,temp,crc); + end; + + crc := Update32(header3.b0len,2,crc); + crc := Update32(header3.b1len,2,crc); + crc := Update32(header3.b2len,2,crc); + + For temp2 := 0 to 6 do + crc := Update32(xlen[temp2],2,crc); + + If (crc <> header3.crc32) then + begin + CloseF(f); + EXIT; + end; + + init_songdata; + load_flag := 0; + + songdata.patt_len := 64; + If adjust_tracks then songdata.nm_tracks := 18 + else If (songdata.nm_tracks < 18) then songdata.nm_tracks := 18; + + SeekF(f,SizeOf(header3)); + If (IOresult <> 0) then + begin + CloseF(f); + EXIT; + end; + + BlockReadF(f,buf1,header3.b0len,temp); + If NOT (temp = header3.b0len) then + begin + CloseF(f); + EXIT; + end; + + old_songdata.tempo := header3.tempo; + old_songdata.speed := header3.speed; + old_songdata.common_flag := header3.cflag; + + Case header3.ffver of + 8: Move(buf1,old_songdata.instr_data,header3.b0len); + 7: LZSS_decompress(buf1,old_songdata.instr_data,header3.b0len); + 6: LZW_decompress(buf1,old_songdata.instr_data); + 5: SIXPACK_decompress(buf1,old_songdata.instr_data,header3.b0len); + end; + + BlockReadF(f,buf1,header3.b1len,temp); + If NOT (temp = header3.b1len) then + begin + CloseF(f); + EXIT; + end; + + Case header3.ffver of + 8: Move(buf1,old_songdata.pattern_order,header3.b1len); + 7: LZSS_decompress(buf1,old_songdata.pattern_order,header3.b1len); + 6: LZW_decompress(buf1,old_songdata.pattern_order); + 5: SIXPACK_decompress(buf1,old_songdata.pattern_order,header3.b1len); + end; + + BlockReadF(f,buf1,header3.b2len,temp); + If NOT (temp = header3.b2len) then + begin + CloseF(f); + EXIT; + end; + + FillChar(hash_buffer,SizeOf(hash_buffer),0); + Case header3.ffver of + 8: Move(buf1,hash_buffer,header3.b2len); + 7: LZSS_decompress(buf1,hash_buffer,header3.b2len); + 6: LZW_decompress(buf1,hash_buffer); + 5: SIXPACK_decompress(buf1,hash_buffer,header3.b2len); + end; + import_old_a2m_patterns2(0,8); + + For temp2 := 0 to 6 do + If ((header3.patts-1) DIV 8 > temp2) then + begin + BlockReadF(f,buf1,xlen[temp2],temp); + If NOT (temp = xlen[temp2]) then + begin + CloseF(f); + EXIT; + end; + + FillChar(hash_buffer,SizeOf(hash_buffer),0); + Case header3.ffver of + 8: Move(buf1,hash_buffer,header3.b3len); + 7: LZSS_decompress(buf1,hash_buffer,header3.b3len); + 6: LZW_decompress(buf1,hash_buffer); + 5: SIXPACK_decompress(buf1,hash_buffer,header3.b3len); + end; + import_old_a2m_patterns2(SUCC(temp2),8); + end; + import_old_songdata(Addr(old_songdata)); + end; + + If (header.ffver = 9) then + begin + ResetF(f); + BlockReadF(f,header4,SizeOf(header4),temp); + If NOT ((temp = SizeOf(header4)) and (header4.ident = id)) then + begin + CloseF(f); + EXIT; + end; + + crc := DWORD_NULL; + BlockReadF(f,buf1,header4.b0len,temp); + If NOT (temp = header4.b0len) then + begin + CloseF(f); + EXIT; + end; + + crc := Update32(buf1,temp,crc); + BlockReadF(f,buf1,header4.b1len,temp); + If NOT (temp = header4.b1len) then + begin + CloseF(f); + EXIT; + end; + + crc := Update32(buf1,temp,crc); + BlockReadF(f,buf1,header4.b2len,temp); + If NOT (temp = header4.b2len) then + begin + CloseF(f); + EXIT; + end; + + crc := Update32(buf1,temp,crc); + BlockReadF(f,buf1,header4.b3len,temp); + If NOT (temp = header4.b3len) then + begin + CloseF(f); + EXIT; + end; + + crc := Update32(buf1,temp,crc); + BlockReadF(f,buf1,header4.b4len[0],temp); + If NOT (temp = header4.b4len[0]) then + begin + CloseF(f); + EXIT; + end; + + crc := Update32(buf1,temp,crc); + For temp2 := 1 to 15 do + If ((header4.patts-1) DIV 8 > PRED(temp2)) then + begin + BlockReadF(f,buf1,header4.b4len[temp2],temp); + If NOT (temp = header4.b4len[temp2]) then + begin + CloseF(f); + EXIT; + end; + crc := Update32(buf1,temp,crc); + end; + + crc := Update32(header4.b0len,2,crc); + crc := Update32(header4.b1len,2,crc); + crc := Update32(header4.b2len,2,crc); + crc := Update32(header4.b3len,2,crc); + + For temp2 := 0 to 15 do + crc := Update32(header4.b4len[temp2],2,crc); + + If (crc <> header4.crc32) then + begin + CloseF(f); + EXIT; + end; + + init_songdata; + load_flag := 0; + + SeekF(f,SizeOf(header4)); + If (IOresult <> 0) then + begin + CloseF(f); + EXIT; + end; + + BlockReadF(f,buf1,header4.b0len,temp); + If NOT (temp = header4.b0len) then + begin + CloseF(f); + EXIT; + end; + + APACK_decompress(buf1,songdata.instr_data); + BlockReadF(f,buf1,header4.b1len,temp); + If NOT (temp = header4.b1len) then + begin + CloseF(f); + EXIT; + end; + + APACK_decompress(buf1,songdata.instr_macros); + BlockReadF(f,buf1,header4.b2len,temp); + If NOT (temp = header4.b2len) then + begin + CloseF(f); + EXIT; + end; + + APACK_decompress(buf1,songdata.macro_table); + BlockReadF(f,buf1,header4.b3len,temp); + If NOT (temp = header4.b3len) then + begin + CloseF(f); + EXIT; + end; + + songdata.tempo := header4.tempo; + songdata.speed := header4.speed; + songdata.common_flag := header4.cflag; + songdata.patt_len := header4.patln; + songdata.nm_tracks := header4.nmtrk; + songdata.macro_speedup := header4.mcspd; + import_old_flags; + + APACK_decompress(buf1,songdata.pattern_order); + BlockReadF(f,buf1,header4.b4len[0],temp); + If NOT (temp = header4.b4len[0]) then + begin + CloseF(f); + EXIT; + end; + + APACK_decompress(buf1,pattdata^[0]); + For temp2 := 1 to 15 do + If ((header4.patts-1) DIV 8 > PRED(temp2)) then + begin + BlockReadF(f,buf1,header4.b4len[temp2],temp); + If NOT (temp = header4.b4len[temp2]) then + begin + CloseF(f); + EXIT; + end; + + If (temp2*8+8 <= max_patterns) then + APACK_decompress(buf1,pattdata^[temp2]) + else limit_exceeded := TRUE; + end; + end; + + If (header.ffver = 10) then + begin + ResetF(f); + BlockReadF(f,header5,SizeOf(header5),temp); + If NOT ((temp = SizeOf(header5)) and (header5.ident = id)) then + begin + CloseF(f); + EXIT; + end; + + crc := DWORD_NULL; + BlockReadF(f,buf1,header5.b0len,temp); + If NOT (temp = header5.b0len) then + begin + CloseF(f); + EXIT; + end; + + crc := Update32(buf1,temp,crc); + BlockReadF(f,buf1,header5.b1len,temp); + If NOT (temp = header5.b1len) then + begin + CloseF(f); + EXIT; + end; + + crc := Update32(buf1,temp,crc); + BlockReadF(f,buf1,header5.b2len,temp); + If NOT (temp = header5.b2len) then + begin + CloseF(f); + EXIT; + end; + + crc := Update32(buf1,temp,crc); + BlockReadF(f,buf1,header5.b3len,temp); + If NOT (temp = header5.b3len) then + begin + CloseF(f); + EXIT; + end; + + crc := Update32(buf1,temp,crc); + BlockReadF(f,buf1,header5.b4len[0],temp); + If NOT (temp = header5.b4len[0]) then + begin + CloseF(f); + EXIT; + end; + + crc := Update32(buf1,temp,crc); + For temp2 := 1 to 15 do + If ((header5.patts-1) DIV 8 > PRED(temp2)) then + begin + BlockReadF(f,buf1,header5.b4len[temp2],temp); + If NOT (temp = header5.b4len[temp2]) then + begin + CloseF(f); + EXIT; + end; + crc := Update32(buf1,temp,crc); + end; + + crc := Update32(header5.b0len,2,crc); + crc := Update32(header5.b1len,2,crc); + crc := Update32(header5.b2len,2,crc); + crc := Update32(header5.b3len,2,crc); + + For temp2 := 0 to 15 do + crc := Update32(header5.b4len[temp2],2,crc); + + If (crc <> header5.crc32) then + begin + CloseF(f); + EXIT; + end; + + init_songdata; + load_flag := 0; + + SeekF(f,SizeOf(header5)); + If (IOresult <> 0) then + begin + CloseF(f); + EXIT; + end; + + BlockReadF(f,buf1,header5.b0len,temp); + If NOT (temp = header5.b0len) then + begin + CloseF(f); + EXIT; + end; + + APACK_decompress(buf1,songdata.instr_data); + BlockReadF(f,buf1,header5.b1len,temp); + If NOT (temp = header5.b1len) then + begin + CloseF(f); + EXIT; + end; + + APACK_decompress(buf1,songdata.instr_macros); + BlockReadF(f,buf1,header5.b2len,temp); + If NOT (temp = header5.b2len) then + begin + CloseF(f); + EXIT; + end; + + APACK_decompress(buf1,songdata.macro_table); + BlockReadF(f,buf1,header5.b3len,temp); + If NOT (temp = header5.b3len) then + begin + CloseF(f); + EXIT; + end; + + songdata.tempo := header5.tempo; + songdata.speed := header5.speed; + songdata.common_flag := header5.cflag; + songdata.patt_len := header5.patln; + songdata.nm_tracks := header5.nmtrk; + songdata.macro_speedup := header5.mcspd; + songdata.flag_4op := header5.is4op; + Move(header5.locks,songdata.lock_flags,SizeOf(songdata.lock_flags)); + + APACK_decompress(buf1,songdata.pattern_order); + BlockReadF(f,buf1,header5.b4len[0],temp); + If NOT (temp = header5.b4len[0]) then + begin + CloseF(f); + EXIT; + end; + + APACK_decompress(buf1,pattdata^[0]); + For temp2 := 1 to 15 do + If ((header5.patts-1) DIV 8 > PRED(temp2)) then + begin + BlockReadF(f,buf1,header5.b4len[temp2],temp); + If NOT (temp = header5.b4len[temp2]) then + begin + CloseF(f); + EXIT; + end; + + If (temp2*8+8 <= max_patterns) then + APACK_decompress(buf1,pattdata^[temp2]) + else limit_exceeded := TRUE; + end; + end; + + If (header.ffver = 11) then + begin + crc := DWORD_NULL; + BlockReadF(f,buf1,header.b0len,temp); + If NOT (temp = header.b0len) then + begin + CloseF(f); + EXIT; + end; + + crc := Update32(buf1,temp,crc); + BlockReadF(f,buf1,header.b1len,temp); + If NOT (temp = header.b1len) then + begin + CloseF(f); + EXIT; + end; + + crc := Update32(buf1,temp,crc); + BlockReadF(f,buf1,header.b2len,temp); + If NOT (temp = header.b2len) then + begin + CloseF(f); + EXIT; + end; + + crc := Update32(buf1,temp,crc); + BlockReadF(f,buf1,header.b3len,temp); + If NOT (temp = header.b3len) then + begin + CloseF(f); + EXIT; + end; + + crc := Update32(buf1,temp,crc); + BlockReadF(f,buf1,header.b4len,temp); + If NOT (temp = header.b4len) then + begin + CloseF(f); + EXIT; + end; + + crc := Update32(buf1,temp,crc); + BlockReadF(f,buf1,header.b5len[0],temp); + If NOT (temp = header.b5len[0]) then + begin + CloseF(f); + EXIT; + end; + + crc := Update32(buf1,temp,crc); + For temp2 := 1 to 15 do + If ((header.patts-1) DIV 8 > PRED(temp2)) then + begin + BlockReadF(f,buf1,header.b5len[temp2],temp); + If NOT (temp = header.b5len[temp2]) then + begin + CloseF(f); + EXIT; + end; + crc := Update32(buf1,temp,crc); + end; + + crc := Update32(header.b0len,2,crc); + crc := Update32(header.b1len,2,crc); + crc := Update32(header.b2len,2,crc); + crc := Update32(header.b3len,2,crc); + crc := Update32(header.b4len,2,crc); + + For temp2 := 0 to 15 do + crc := Update32(header.b5len[temp2],2,crc); + + If (crc <> header.crc32) then + begin + CloseF(f); + EXIT; + end; + + init_songdata; + load_flag := 0; + + SeekF(f,SizeOf(header)); + If (IOresult <> 0) then + begin + CloseF(f); + EXIT; + end; + + BlockReadF(f,buf1,header.b0len,temp); + If NOT (temp = header.b0len) then + begin + CloseF(f); + EXIT; + end; + + APACK_decompress(buf1,songdata.instr_data); + BlockReadF(f,buf1,header.b1len,temp); + If NOT (temp = header.b1len) then + begin + CloseF(f); + EXIT; + end; + + APACK_decompress(buf1,songdata.instr_macros); + BlockReadF(f,buf1,header.b2len,temp); + If NOT (temp = header.b2len) then + begin + CloseF(f); + EXIT; + end; + + APACK_decompress(buf1,songdata.macro_table); + BlockReadF(f,buf1,header.b3len,temp); + If NOT (temp = header.b3len) then + begin + CloseF(f); + EXIT; + end; + + APACK_decompress(buf1,songdata.dis_fmreg_col); + BlockReadF(f,buf1,header.b4len,temp); + If NOT (temp = header.b4len) then + begin + CloseF(f); + EXIT; + end; + + songdata.tempo := header.tempo; + songdata.speed := header.speed; + songdata.common_flag := header.cflag; + songdata.patt_len := header.patln; + songdata.nm_tracks := header.nmtrk; + songdata.macro_speedup := header.mcspd; + songdata.flag_4op := header.is4op; + Move(header.locks,songdata.lock_flags,SizeOf(songdata.lock_flags)); + + APACK_decompress(buf1,songdata.pattern_order); + BlockReadF(f,buf1,header.b5len[0],temp); + If NOT (temp = header.b5len[0]) then + begin + CloseF(f); + EXIT; + end; + + APACK_decompress(buf1,pattdata^[0]); + For temp2 := 1 to 15 do + If ((header.patts-1) DIV 8 > PRED(temp2)) then + begin + BlockReadF(f,buf1,header.b5len[temp2],temp); + If NOT (temp = header.b5len[temp2]) then + begin + CloseF(f); + EXIT; + end; + + If (temp2*8+8 <= max_patterns) then + APACK_decompress(buf1,pattdata^[temp2]) + else limit_exceeded := TRUE; + end; + end; + + speed := songdata.speed; + tempo := songdata.tempo; + + CloseF(f); + songdata_title := NameOnly(songdata_source); + Case header.ffver of + 1..4: load_flag := 3; + else load_flag := 4; + end; +end; + + +function dec2hex(dec: Byte): Byte; +begin dec2hex := (dec DIV 10)*16 +(dec MOD 10); end; + +function truncate_string(str: String): String; +begin + While (Length(str) > 0) and (str[Length(str)] in [#0,#32,#255]) do + Delete(str,Length(str),1); + truncate_string := str; +end; + +procedure amd_file_loader; + +type + tPATDAT = array[0..$24] of + array[0..$3f] of array[1..9] of + array[0..2] of Byte; +type + tINSDAT = Record + iName: array[1..23] of Char; { Instrument name } + iData: array[0..10] of Byte; { Instrument data } + end; +type + tHEADER = Record + sname: array[1..24] of Char; { Name of song [ASCIIZ] } + aname: array[1..24] of Char; { Name of author [ASCIIZ] } + instr: array[0..25] of tINSDAT; { 26 instruments } + snlen: Byte; { Song length } + nopat: Byte; { Number of patterns -1 } + order: array[0..$7f] of Byte; { Pattern table } + ident: array[1..9] of Char; { ID } + versn: Byte; { Version 10h=normal module } + { 11h=packed module } + end; +const + id_amd = ' 0) then + chunk.instr_def := (byte2 SHR 4)+(byte1 AND 1) SHL 4; + + If (byte1 SHR 4 in [1..12]) and ((byte1 SHR 1) AND 7 in [0..7]) then + chunk.note := 12*((byte1 SHR 1) AND 7)+(byte1 SHR 4); + + param := byte3 AND $7f; + Case byte2 AND $0f of + { ARPEGGIO } + $00: begin + chunk.effect_def := ef_Arpeggio; + chunk.effect := dec2hex(param); + end; + + { SLIDE FREQUENCY UP } + $01: begin + chunk.effect_def := ef_FSlideUp; + chunk.effect := param; + end; + + { SLIDE FREQUENCY DOWN } + $02: begin + chunk.effect_def := ef_FSlideDown; + chunk.effect := param; + end; + + { SET CARRIER/MODULATOR INTENSITY } + $03: If (param DIV 10 in [1..9]) then + begin + chunk.effect_def := ef_SetCarrierVol; + chunk.effect := (param DIV 10)*7; + end + else If (param MOD 10 in [1..9]) then + begin + chunk.effect_def := ef_SetModulatorVol; + chunk.effect := (param MOD 10)*7; + end; + + { SET THE VOLUME } + $04: begin + chunk.effect_def := ef_SetInsVolume; + If (param < 64) then chunk.effect := param + else chunk.effect := 63; + end; + + { JUMP INTO PATTERN } + $05: begin + chunk.effect_def := ef_PositionJump; + If (param < 100) then chunk.effect := param + else chunk.effect := 99; + end; + + { PATTERNBREAK } + $06: begin + chunk.effect_def := ef_PatternBreak; + If (param < 64) then chunk.effect := param + else chunk.effect := 63; + end; + + { SET SONGSPEED } + $07: If (param < 99) then + If (param in [1..31]) then + begin + chunk.effect_def := ef_SetSpeed; + chunk.effect := param; + end + else begin + chunk.effect_def := ef_SetTempo; + If (param = 0) then chunk.effect := 18 + else chunk.effect := param; + end; + + { TONEPORTAMENTO } + $08: begin + chunk.effect_def := ef_TonePortamento; + chunk.effect := param; + end; + + { EXTENDED COMMAND } + $09: If (param < 60) then + Case param DIV 10 of + { DEFINE CELL-TREMOLO } + 0: If (param MOD 10 < 2) then + begin + chunk.effect_def := ef_Extended; + chunk.effect := dec2hex(param); + end; + + { DEFINE CELL-VIBRATO } + 1: If (param MOD 10 < 2) then + begin + chunk.effect_def := ef_Extended; + chunk.effect := $10+dec2hex(param); + end; + + { INCREASE VOLUME FAST } + 2: begin + chunk.effect_def := ef_VolSlide; + chunk.effect := (param MOD 10)*16; + end; + + { DECREASE VOLUME FAST } + 3: begin + chunk.effect_def := ef_VolSlide; + chunk.effect := param MOD 10; + end; + + { INCREASE VOLUME FINE } + 4: begin + chunk.effect_def := ef_Extended2; + chunk.effect := ef_ex2_VolSlideUpXF*16+(param MOD 10); + end; + + { DECREASE VOLUME FINE } + 5: begin + chunk.effect_def := ef_Extended2; + chunk.effect := ef_ex2_VolSlideDnXF*16+(param MOD 10); + end; + end; + end; + +// specific corrections for Amusic event + If (chunk.note = 0) then chunk.instr_def := 0; + put_chunk(pattern,line,channel,chunk); +end; + +procedure import_amd_packed_patterns(var data; patterns: Byte); + +var + temp,temp2,temp3,temp4,temp5: Word; + count: Byte; + +var + tracks: Word; + track_order: array[0..$3f] of array[1..9] of Word; + track: array[0..$3f] of tCHUNK; + +begin + temp := (patterns+1)*9*SizeOf(WORD); + Move(data,track_order,temp); + + tracks := tDUMMY_BUFF(data)[temp]+(tDUMMY_BUFF(data)[temp+1]) SHL 8; + Inc(temp,2); + + temp3 := 0; + temp4 := 0; + count := 0; + + Repeat + If (count = 0) then + begin + If (temp3 = 0) then + begin + temp2 := tDUMMY_BUFF(data)[temp]+(tDUMMY_BUFF(data)[temp+1]) SHL 8; + Inc(temp,2); + end; + + If (tDUMMY_BUFF(data)[temp] OR $80 <> tDUMMY_BUFF(data)[temp]) then + begin + If (temp2 DIV 9 <= $3f) and (temp2 MOD 9 < 9) then + import_amd_event(temp2 DIV 9,temp3,temp2 MOD 9 +1, + tDUMMY_BUFF(data)[temp+2], + tDUMMY_BUFF(data)[temp+1], + tDUMMY_BUFF(data)[temp+0]); + Inc(temp,3); + end + else + begin + count := (tDUMMY_BUFF(data)[temp] AND $7f)-1; + Inc(temp); + end; + end + else Dec(count); + + Inc(temp3); + If (temp3 > $3f) then + begin + temp3 := 0; + count := 0; + Inc(temp4); + end; + until NOT (temp4 < tracks); + + For temp := 0 to patterns do + For temp2 := 1 to 9 do + begin + temp3 := track_order[temp][temp2]; + temp4 := temp3 DIV 9; + + If (temp3 < 64*9) then + begin + For temp5 := 0 to $3f do + get_chunk(temp4,temp5,temp3 MOD 9 +1,track[temp5]); + For temp5 := 0 to $3f do + put_chunk( temp,temp5,temp2,track[temp5]); + end; + end; +end; + +function get_byte(var pos: Longint): Byte; +begin + If (pos = SizeOf(buf1)) then + begin + Move(buf3,buf1,SizeOf(buf3)); + pos := 0; + end; + get_byte := buf1[pos]; + Inc(pos); +end; + +begin + {$i-} + Assign(f,songdata_source); + ResetF(f); + {$i+} + If (IOresult <> 0) then + begin + CloseF(f); + EXIT; + end; + + BlockReadF(f,header,SizeOf(header),temp); + If NOT ((temp = SizeOf(header)) and + ((header.ident = id_amd) or (header.ident = id_xms))) then + begin + CloseF(f); + EXIT; + end; + + load_flag := $7f; + If NOT (header.versn in [$10,$11]) then + begin + CloseF(f); + EXIT; + end; + + FillChar(buf1,SizeOf(buf1),0); + BlockReadF(f,buf1,SizeOf(buf1),temp); + If (IOresult <> 0) then + begin + CloseF(f); + EXIT; + end; + + tmp2 := WORD_NULL; + If (temp = SizeOf(buf1)) then + begin + FillChar(buf3,SizeOf(buf3),0); + BlockReadF(f,buf3,SizeOf(buf3),tmp2); + If (IOresult <> 0) then + begin + CloseF(f); + EXIT; + end; + end; + + init_songdata; + load_flag := 0; + + songdata.patt_len := 64; + If adjust_tracks then songdata.nm_tracks := 9 + else If (songdata.nm_tracks < 9) then songdata.nm_tracks := 9; + + tempo := 50; + speed := 6; + + songdata.tempo := tempo; + songdata.speed := speed; + + For temp2 := 0 to header.snlen-1 do + If (temp2 < 128) and (header.order[temp2] in [0..header.nopat]) then + songdata.pattern_order[temp2] := header.order[temp2]; + + For temp2 := 0 to 25 do + begin + import_amd_instrument(temp2+1,header.instr[temp2].iData); + songdata.instr_names[temp2+1] := + Copy(songdata.instr_names[temp2+1],1,9)+ + truncate_string(header.instr[temp2].iName); + end; + + temp := 0; + If (header.versn = $10) then + For temp2 := 0 to header.nopat do + For temp3 := 0 to $3f do + For temp4 := 1 to 9 do + begin + byte3 := get_byte(temp); + byte2 := get_byte(temp); + byte1 := get_byte(temp); + import_amd_event(temp2,temp3,temp4,byte1,byte2,byte3); + end + else + import_amd_packed_patterns(buf1,header.nopat); + + songdata.common_flag := songdata.common_flag OR $80; + songdata.songname := CutStr(asciiz_string(header.sname)); + songdata.composer := CutStr(asciiz_string(header.aname)); + import_old_flags; + + CloseF(f); + songdata_title := NameOnly(songdata_source); + If (header.ident = id_amd) then load_flag := 5 + else load_flag := 6; +end; + +procedure import_hsc_instrument(inst: Byte; var data); forward; + +procedure import_cff_event(patt,line,chan,byte0,byte1,byte2: Byte); + +var + chunk: tCHUNK; + temp1,temp2,temp3,temp4: Byte; + +begin + FillChar(chunk,SizeOf(chunk),0); + temp1 := byte2; + temp2 := temp1 DIV 16; + temp3 := temp1 MOD 16; + + Case CHAR(byte1) of + { SET SPEED } + 'A': If (temp1 > 0) then + begin + chunk.effect_def := ef_SetSpeed; + chunk.effect := temp1; + end; + + { SET CARRIER WAVEFORM } + 'B': If (temp1 < 4) then + begin + chunk.effect_def := ef_SetWaveform; + chunk.effect := temp1*16; + end; + + { SET MODULATOR VOLUME } + 'C': begin + chunk.effect_def := ef_SetModulatorVol; + If (temp1 < 64) then chunk.effect := 63-temp1 + else chunk.effect := 0; + end; + + { VOLUME SLIDE UP/DOWN } + 'D': begin + chunk.effect_def := ef_VolSlide; + chunk.effect := temp1; + end; + + { SLIDE DOWN } + 'E': If (temp1 <> 0) then + begin + chunk.effect_def := ef_FSlideDown; + chunk.effect := temp1; + end; + + { SLIDE UP } + 'F': If (temp1 <> 0) then + begin + chunk.effect_def := ef_FSlideUp; + chunk.effect := temp1; + end; + + { SET CARRIER VOLUME } + 'G': begin + chunk.effect_def := ef_SetCarrierVol; + If (temp1 < 64) then chunk.effect := 63-temp1 + else chunk.effect := 0; + end; + + { SET TEMPO } + 'H': If (temp1 > 0) then + begin + chunk.effect_def := ef_SetTempo; + If NOT (temp1 > 21) then temp1 := 125; + temp4 := 1412926 DIV LONGINT(temp1 SHR 1); + chunk.effect := 1; + While (1193180 DIV chunk.effect > temp4) and + (chunk.effect < 255) do + Inc(chunk.effect); + end; + + { SET INSTRUMENT } + 'I': If (temp1 < 47) then + begin + chunk.effect_def := ef_Extended; + chunk.effect := ef_ex_ExtendedCmd*16+ef_ex_cmd_ResetVol; + chunk.instr_def := temp1+1; + end; + + { ARPEGGIO } + 'J': begin + chunk.effect_def := ef_Arpeggio; + chunk.effect := temp1; + end; + + { JUMP TO ORDER } + 'K': If (temp1 < 128) then + begin + chunk.effect_def := ef_PositionJump; + chunk.effect := temp1; + end; + + { JUMP TO NEXT PATTERN IN ORDER } + 'L': chunk.effect_def := ef_PatternBreak; + + { SET TREMOLO HIGHER / SET VIBRATO DEEPER } + 'M': begin + chunk.effect_def := ef_Extended; + If (temp2 = 1) and (temp3 = 0) then chunk.effect := dec2hex(01); + If (temp2 = 0) and (temp3 = 1) then chunk.effect := dec2hex(10); + If (temp2 = 1) and (temp3 = 1) then chunk.effect := dec2hex(11); + end; + end; + + Case byte0 of + { REGULAR NOTE } + 1..12*8+1: begin + If NOT fix_c_note_bug then chunk.note := byte0 + else begin + chunk.note := byte0+1; + If (chunk.note > 12*8+1) then + chunk.note := 12*8+1; + end; + end; + { PAUSE } + $6d: chunk.note := BYTE_NULL; + end; + + put_chunk(patt,line,chan,chunk); +end; + +procedure import_cff_patterns(var data; patterns: Byte); + +type + tPATDAT = array[0..$24] of + array[0..$3f] of array[1..9] of + array[0..2] of Byte; + +var + voice: array[1..9] of Byte; + arpgg: array[1..9] of Byte; + chunk: tCHUNK; + temp,temp2,temp3,temp4: Byte; + order,patt: Byte; + patt_break: Byte; + patts: String; + +function _empty_event(var data): Boolean; +begin + _empty_event := (tDUMMY_BUFF(data)[0] = 0) and + (tDUMMY_BUFF(data)[1] = 0) and + (tDUMMY_BUFF(data)[2] = 0); +end; + +begin + patts := ''; + FillChar(arpgg,SizeOf(arpgg),0); + If NOT accurate_conv then + For temp := 1 to 9 do voice[temp] := temp + else For temp := 1 to 9 do voice[temp] := 0; + + For temp := 0 to $24 do + For temp2 := 0 to $3f do + For temp3 := 1 to 9 do + If NOT _empty_event(tPATDAT(data)[temp][temp2][temp3]) then + import_cff_event(temp,temp2,temp3,tPATDAT(data)[temp][temp2][temp3][0], + tPATDAT(data)[temp][temp2][temp3][1], + tPATDAT(data)[temp][temp2][temp3][2]); + order := 0; + patt := BYTE_NULL; + + Repeat + If (songdata.pattern_order[order] > $24) then Inc(order) + else + begin + patt := songdata.pattern_order[order]; + patt_break := BYTE_NULL; + For temp2 := 0 to $3f do + For temp3 := 1 to 9 do + begin + get_chunk(patt,temp2,temp3,chunk); + temp4 := tPATDAT(data)[patt][temp2][temp3][2]; + + Case CHAR(tPATDAT(data)[patt][temp2][temp3][1]) of + { SET MODULATOR VOLUME } + 'C': If (chunk.instr_def = 0) and NOT accurate_conv then + chunk.instr_def := voice[temp3] + else If (chunk.instr_def = 0) and + (voice[temp3] = 0) then chunk.instr_def := temp3; + + { SET CARRIER VOLUME } + 'G': If (chunk.instr_def = 0) and NOT accurate_conv then + chunk.instr_def := voice[temp3] + else If (chunk.instr_def = 0) and + (voice[temp3] = 0) then chunk.instr_def := temp3; + + { SET INSTRUMENT } + 'I': If (temp4 < 47) then + If (temp2 <> patt_break) then + begin + voice[temp3] := temp4+1; + If NOT accurate_conv then + chunk.instr_def := voice[temp3]; + end; + + { ARPEGGIO } + 'J': begin + chunk.effect_def := ef_Arpeggio; + If (temp4 <> 0) then + begin + chunk.effect := temp4; + arpgg[temp3] := temp4; + end + else chunk.effect := arpgg[temp3]; + end; + + { JUMP TO ORDER } + 'K': If (temp4 < 128) then + patt_break := temp2+1; + + { JUMP TO NEXT PATTERN IN ORDER } + 'L': patt_break := temp2+1; + end; + + Case tPATDAT(data)[patt][temp2][temp3][0] of + { REGULAR NOTE } + 1..12*8+1: begin + If accurate_conv then + If (voice[temp3] = 0) then + begin + voice[temp3] := temp3; + chunk.instr_def := voice[temp3]; + end; + + If NOT accurate_conv then + chunk.instr_def := voice[temp3]; + end; + end; + + If (Pos(CHR(songdata.pattern_order[order]),patts) = 0) then + put_chunk(patt,temp2,temp3,chunk); + end; + Inc(order); + patts := patts+CHR(patt); + end; + until (patt >= patterns) or (order > $40); +end; + +procedure cff_file_loader; + +type + tHEADER = Record + ident: array[1..16] of Char; { Identification } + versn: Byte; { Format version } + fsize: Word; { Filesize -32 } + cflag: Byte; { Flag 1=compressed data } + resrv: array[0..11] of Byte; { Reserved } + end; +type + tINSDAT = Record + iData: array[0..11] of Byte; { Instrument data } + iName: array[1..20] of Char; { Instrument name } + end; +type + tHEADR2 = Record + instr: array[0..46] of tINSDAT; { 47 instruments } + nopat: Byte; { Number of patterns } + ascii: array[1..31] of Char; { ASCII blab } + writr: array[1..20] of Char; { Song writer } + sname: array[1..20] of Char; { Song name } + order: array[0..64] of Byte; { Pattern order } + end; +const + _PRE_ASCII_BLAB_SIZE = $5e1; // SizeOf(tHEADR2.instr)+SizeOf(tHEADR2.nopat) + +const + id = ''+#26+CHR($de)+CHR($e0); + ascii_blab = 'CUD-FM-File - SEND A POSTCARD -'; + +var + f: File; + header: tHEADER; + headr2: tHEADR2; + temp,temp2: Longint; + offs,out_size: Longint; + +function LZTYR_decompress(var input,output): Longint; + +type + tSTRING = array[0..255] of Byte; + +var + input_idx: Longint; + + the_string, + temp_string: tSTRING; + + old_code_length: Byte; + repeat_length: Byte; + repeat_counter: Longint; + output_length: Longint; + code_length: Byte; + bits_buffer: Longint; + bits_left: Word; + old_code: Longint; + new_code: Longint; + idx: Word; + + _cff_heap_length: Word; + _cff_dictionary_length: Word; + _cff_dictionary: array[0..32767] of Pointer; + +function get_code: Longint; + +var + code: Longint; + +begin + While (bits_left < code_length) do + begin + bits_buffer := bits_buffer OR (tDUMMY_BUFF(input)[input_idx] SHL + bits_left); + Inc(input_idx); + Inc(bits_left,8); + end; + + code := bits_buffer AND ((1 SHL code_length)-1); + bits_buffer := bits_buffer SHR code_length; + Dec(bits_left,code_length); + get_code := code; +end; + +procedure translate_code(code: Longint; var str: tSTRING); + +var + translated_string: tSTRING; + +begin + If (code >= $104) then + Move(_cff_dictionary[code-$104]^,translated_string, + BYTE(_cff_dictionary[code-$104]^)+1) + else begin + translated_string[0] := 1; + translated_string[1] := (code-4) AND $0ff; + end; + + Move(translated_string,str,256); +end; + +procedure startup; + +var + idx: Longint; + +begin + old_code := get_code; + translate_code(old_code,the_string); + + If (the_string[0] > 0) then + For idx := 0 to the_string[0]-1 do + begin + tDUMMY_BUFF(output)[output_length] := the_string[idx+1]; + Inc(output_length); + end; +end; + +procedure cleanup; +begin + code_length := 9; + bits_buffer := 0; + bits_left := 0; + _cff_heap_length := 0; + _cff_dictionary_length := 0; +end; + +procedure expand__cff_dictionary(str: tSTRING); +begin + If (str[0] >= $0f0) then EXIT; + Move(str,buf3[_cff_heap_length],str[0]+1); + _cff_dictionary[_cff_dictionary_length] := Addr(buf3[_cff_heap_length]); + Inc(_cff_dictionary_length); + Inc(_cff_heap_length,str[0]+1); +end; + +begin + input_idx := 0; + output_length := 0; + cleanup; + startup; + + Repeat + new_code := get_code; + + // $00: end of data + If (new_code = 0) then BREAK; + + // $01: end of block + If (new_code = 1) then + begin + cleanup; + startup; + CONTINUE; + end; + + // $02: expand code length + If (new_code = 2) then + begin + Inc(code_length); + CONTINUE; + end; + + // $03: RLE + If (new_code = 3) then + begin + old_code_length := code_length; + code_length := 2; + repeat_length := get_code+1; + code_length := 4 SHL get_code; + repeat_counter := get_code; + + For idx := 0 to PRED(repeat_counter*repeat_length) do + begin + tDUMMY_BUFF(output)[output_length] := + tDUMMY_BUFF(output)[output_length-repeat_length]; + Inc(output_length); + end; + + code_length := old_code_length; + startup; + CONTINUE; + end; + + If (new_code >= $104+_cff_dictionary_length) then + begin + Inc(the_string[0]); + the_string[the_string[0]] := the_string[1]; + end + else begin + translate_code(new_code,temp_string); + Inc(the_string[0]); + the_string[the_string[0]] := temp_string[1]; + end; + + expand__cff_dictionary(the_string); + translate_code(new_code,the_string); + + For idx := 0 to PRED(the_string[0]) do + begin + tDUMMY_BUFF(output)[output_length] := the_string[idx+1]; + Inc(output_length); + end; + + old_code := new_code; + until FALSE; + + LZTYR_decompress := output_length; +end; + +begin + {$i-} + Assign(f,songdata_source); + ResetF(f); + {$i+} + If (IOresult <> 0) then + begin + CloseF(f); + EXIT; + end; + + BlockReadF(f,header,SizeOf(header),temp); + If NOT ((temp = SizeOf(header)) and (header.ident = id)) or + (FileSize(f) > SizeOf(buf1)) then + begin + CloseF(f); + EXIT; + end; + + load_flag := $7f; + If (header.cflag = 1) then + begin + FillChar(buf1,SizeOf(buf1),0); + ResetF(f); + BlockReadF(f,buf1,SizeOf(buf1),temp); + If (IOresult <> 0) then + begin + CloseF(f); + EXIT; + end; + + CloseF(f); + temp := LZTYR_decompress(buf1[$30],hash_buffer); + out_size := temp; + + offs := SensitiveScan(hash_buffer,0,temp,ascii_blab); + If (offs <> _PRE_ASCII_BLAB_SIZE) then + begin + EXIT; + end; + + FillChar(buf1,SizeOf(buf1),0); + Move(hash_buffer,headr2,SizeOf(headr2)); + Move(POINTER(Ofs(hash_buffer)+SizeOf(headr2))^,buf1,out_size-SizeOf(headr2)); + end + else + begin + BlockReadF(f,headr2,SizeOf(headr2),temp); + If NOT ((temp = SizeOf(headr2)) and (headr2.ascii = ascii_blab)) then + begin + CloseF(f); + EXIT; + end; + + FillChar(buf1,SizeOf(buf1),0); + BlockReadF(f,buf1,SizeOf(buf1),temp); + If (IOresult <> 0) then + begin + CloseF(f); + EXIT; + end; + CloseF(f); + end; + + init_songdata; + load_flag := 0; + + songdata.patt_len := 64; + If adjust_tracks then songdata.nm_tracks := 9 + else If (songdata.nm_tracks < 9) then songdata.nm_tracks := 9; + + tempo := 51; + speed := 6; + + songdata.tempo := tempo; + songdata.speed := speed; + + For temp2 := 0 to 64 do + If (headr2.order[temp2] in [0..headr2.nopat]) then + songdata.pattern_order[temp2] := headr2.order[temp2]; + + For temp2 := 0 to 46 do + begin + import_hsc_instrument(temp2+1,headr2.instr[temp2].iData); + songdata.instr_data[temp2+1].fine_tune := 0; + songdata.instr_names[temp2+1] := + Copy(songdata.instr_names[temp2+1],1,9)+ + truncate_string(headr2.instr[temp2].iName); + end; + + songdata.common_flag := songdata.common_flag OR 2; + songdata.songname := CutStr(headr2.sname); + songdata.composer := CutStr(headr2.writr); + import_old_flags; + + import_cff_patterns(buf1,headr2.nopat); + songdata_title := NameOnly(songdata_source); + load_flag := 7; +end; + +procedure import_standard_instrument(inst: Byte; var data); +begin + With songdata.instr_data[inst] do + begin + fm_data.AM_VIB_EG_modulator := tDUMMY_BUFF(data)[0]; + fm_data.AM_VIB_EG_carrier := tDUMMY_BUFF(data)[1]; + fm_data.KSL_VOLUM_modulator := tDUMMY_BUFF(data)[2]; + fm_data.KSL_VOLUM_carrier := tDUMMY_BUFF(data)[3]; + fm_data.ATTCK_DEC_modulator := tDUMMY_BUFF(data)[4]; + fm_data.ATTCK_DEC_carrier := tDUMMY_BUFF(data)[5]; + fm_data.SUSTN_REL_modulator := tDUMMY_BUFF(data)[6]; + fm_data.SUSTN_REL_carrier := tDUMMY_BUFF(data)[7]; + fm_data.WAVEFORM_modulator := tDUMMY_BUFF(data)[8] AND 3; + fm_data.WAVEFORM_carrier := tDUMMY_BUFF(data)[9] AND 3; + fm_data.FEEDBACK_FM := tDUMMY_BUFF(data)[10] AND $0f; + end; + + songdata.instr_data[inst].panning := 0; + songdata.instr_data[inst].fine_tune := 0; +end; + +procedure dfm_file_loader; + +const + id = 'DFM'+#26; + +var + header: Record + ident: array[1..4] of Char; + versn: Word; + sname: String[32]; + tempo: Byte; + instn: array[1..32] of String[11]; + instd: array[1..32] of tFM_INST_DATA; + order: array[1..128] of Byte; + patts: Byte; + end; + +var + f: File; + temp,temp2,temp3: Longint; + pattern,line,channel,byte1,byte2: Byte; + +procedure import_dfm_event(patt,line,chan,byte1,byte2: Byte); + +var + chunk: tCHUNK; + +begin + FillChar(chunk,SizeOf(chunk),0); + If (byte1 AND $0f in [1..12,15]) and ((byte1 SHR 4) AND 7 in [0..7]) then + If (byte1 AND $0f <> 15) then + chunk.note := SUCC(PRED(byte1 AND $0f)+((byte1 SHR 4) AND 7)*12) + else chunk.note := BYTE_NULL; + + Case byte2 SHR 5 of + { INSTRUMENT CHANGE } + 1: chunk.instr_def := SUCC(byte2 AND $1f); + + { SET INSTRUMENT VOLUME } + 2: begin + chunk.effect_def := ef_SetInsVolume; + chunk.effect := (byte2 AND $1f)*2; + end; + + { TEMPO CHANGE } + 3: begin + chunk.effect_def := ef_SetSpeed; + chunk.effect := SUCC(byte2 AND $1f); + end; + + { SLIDE UP } + 4: begin + chunk.effect_def := ef_FSlideUpFine; + chunk.effect := byte2 AND $1f; + end; + + { SLIDE DOWN } + 5: begin + chunk.effect_def := ef_FSlideDownFine; + chunk.effect := byte2 AND $1f; + end; + + { END OF PATTERN } + 7: chunk.effect_def := ef_PatternBreak; + end; + + put_chunk(patt,line,chan,chunk); +end; + +procedure process_dfm_patterns(patterns: Byte); + +var + chunk: tCHUNK; + temp2,temp3: Byte; + order,patt: Byte; + patts: String; + instr_cache: array[1..18] of Byte; + +begin + patts := ''; + FillChar(instr_cache,SizeOf(instr_cache),0); + order := 0; + patt := BYTE_NULL; + + Repeat + If (songdata.pattern_order[order] >= $80) then Inc(order) + else + begin + patt := songdata.pattern_order[order]; + For temp2 := 0 to $3f do + For temp3 := 1 to 9 do + begin + get_chunk(patt,temp2,temp3,chunk); + If (chunk.instr_def <> 0) then + begin + chunk.effect_def := ef_Extended; + chunk.effect := ef_ex_ExtendedCmd*16+ef_ex_cmd_ResetVol; + instr_cache[temp3] := chunk.instr_def; + If NOT (chunk.note in [1..12*8+1]) and + NOT accurate_conv then + chunk.instr_def := 0; + end + else If (chunk.note in [1..12*8+1]) and + (chunk.instr_def = 0) and NOT accurate_conv then + chunk.instr_def := instr_cache[temp3]; + + If (Pos(CHR(songdata.pattern_order[order]),patts) = 0) then + put_chunk(patt,temp2,temp3,chunk); + end; + Inc(order); + patts := patts+CHR(patt); + end; + until (patt >= patterns) or (order > $7f); +end; + +begin + {$i-} + Assign(f,songdata_source); + ResetF(f); + {$i+} + If (IOresult <> 0) then + begin + CloseF(f); + EXIT; + end; + + BlockReadF(f,header,SizeOf(header),temp); + If NOT ((temp = SizeOf(header)) and (header.ident = id)) then + begin + CloseF(f); + EXIT; + end; + + load_flag := $7f; + FillChar(buf1,SizeOf(buf1),0); + BlockReadF(f,buf1,SizeOf(buf1),temp); + If (IOresult <> 0) then + begin + CloseF(f); + EXIT; + end; + + init_songdata; + load_flag := 0; + + songdata.patt_len := 64; + If adjust_tracks then songdata.nm_tracks := 9 + else If (songdata.nm_tracks < 9) then songdata.nm_tracks := 9; + + tempo := 135; + speed := SUCC(header.tempo); + + songdata.songname := CutStr(header.sname); + songdata.tempo := tempo; + songdata.speed := speed; + songdata.common_flag := songdata.common_flag OR 1; + songdata.common_flag := songdata.common_flag OR 2; + songdata.common_flag := songdata.common_flag OR 8; + songdata.common_flag := songdata.common_flag OR $10; + import_old_flags; + + For temp2 := 1 to 128 do + If (header.order[temp2] in [0..$7f]) then + songdata.pattern_order[temp2-1] := header.order[temp2] + else If (header.order[temp2] = $80) then BREAK + else songdata.pattern_order[temp2-1] := $80+temp2; + + For temp2 := 1 to 32 do + begin + songdata.instr_names[temp2] := + Copy(songdata.instr_names[temp2],1,9)+ + CutStr(header.instn[temp2]); + While (BYTE(songdata.instr_names[temp2][ + Length(songdata.instr_names[temp2])]) < 32) and + (Length(songdata.instr_names[temp2]) <> 0) do + Delete(songdata.instr_names[temp2], + Length(songdata.instr_names[temp2]),1); + import_standard_instrument(temp2,header.instd[temp2]); + end; + + temp2 := 0; + temp3 := 0; + Repeat + pattern := buf1[temp2]; + If (pattern > 127) then + begin + CloseF(f); + EXIT; + end; + + Inc(temp2); + Inc(temp3); + + For line := 0 to $3f do + For channel := 1 to 9 do + begin + byte1 := buf1[temp2]; + If (temp2 >= temp) then + begin + CloseF(f); + EXIT; + end + else Inc(temp2); + + If (byte1 OR $80 <> byte1) then byte2 := 0 + else begin + byte2 := buf1[temp2]; + Inc(temp2); + end; + import_dfm_event(pattern,line,channel,byte1,byte2); + end; + until (temp2 >= temp); + + process_dfm_patterns(temp3); + CloseF(f); + + songdata_title := NameOnly(songdata_source); + load_flag := 8; +end; + +type + tHSC_PATTERNS = array[0..$31] of + array[0..$3f] of array[1..9] of Word; +type + tHSC_DATA = Record + instr: array[0..$7f] of array[0..$0b] of Byte; + order: array[0..$31] of Byte; + patts: tHSC_PATTERNS; + end; + +procedure import_hsc_event(patt,line,chan: Byte; event: Word); + +var + chunk: tCHUNK; + +begin + FillChar(chunk,SizeOf(chunk),0); + Case HI(event) of + { REGULAR NOTE } + 1..12*8+1: If NOT fix_c_note_bug then chunk.note := HI(event) + else begin + chunk.note := HI(event)+1; + If (chunk.note > 12*8+1) then + chunk.note := 12*8+1; + end; + { PAUSE } + $7f: chunk.note := BYTE_NULL; + + { INSTRUMENT } + $80: begin + chunk.effect_def := ef_Extended; + chunk.effect := ef_ex_ExtendedCmd*16+ef_ex_cmd_ResetVol; + chunk.instr_def := LO(event)+1; + chunk.note := BYTE_NULL; + end; + end; + + If (HI(event) <> $80) then + Case (LO(event) AND $0f0) of + { PATTERNBREAK } + $00: If (LO(event) AND $0f = 1) then + chunk.effect_def := ef_PatternBreak; + + { MANUAL SLIDE UP } + $10: begin + chunk.effect_def := ef_Extended2; + chunk.effect := ef_ex2_FineTuneUp*16+ + max(LO(event) AND $0f +1,15); + end; + + { MANUAL SLIDE DOWN } + $20: begin + chunk.effect_def := ef_Extended2; + chunk.effect := ef_ex2_FineTuneDown*16+ + max(LO(event) AND $0f +1,15); + end; + + { SET CARRIER VOLUME } + $a0: begin + chunk.effect_def := ef_SetCarrierVol; + chunk.effect := 63-(LO(event) AND $0f)*4; + chunk.instr_def := LO(event)+1; + end; + + { SET MODULATOR VOLUME } + $b0: begin + chunk.effect_def := ef_SetModulatorVol; + chunk.effect := 63-(LO(event) AND $0f)*4; + end; + + { SET INSTRUMENT VOLUME } + $c0: begin + chunk.effect_def := ef_SetInsVolume; + chunk.effect := 63-(LO(event) AND $0f)*4; + end; + + { SET SPEED } + $f0: begin + chunk.effect_def := ef_SetSpeed; + chunk.effect := (LO(event) AND $0f)+1; + end; + end; + put_chunk(patt,line,chan,chunk); +end; + +procedure import_hsc_patterns(var data; patterns: Byte); + +var + voice: array[1..9] of Byte; + event: Word; + chunk: tCHUNK; + temp,temp2,temp3: Byte; + order,patt: Byte; + patt_break: Byte; + patts: String; + +function _hsc_event(patt,line,chan: Byte): Word; +begin + _hsc_event := LO(tHSC_PATTERNS(data)[patt][line][chan+1])+ + HI(tHSC_PATTERNS(data)[patt][line][chan]) SHL 8; +end; + +begin { import_hsc_patterns } + patts := ''; + If NOT accurate_conv then + For temp := 1 to 9 do voice[temp] := temp + else For temp := 1 to 9 do voice[temp] := 0; + + For temp := 0 to $31 do + For temp2 := 0 to $3f do + For temp3 := 1 to 9 do + If (_hsc_event(temp,temp2,temp3) <> 0) then + import_hsc_event(temp,temp2,temp3,_hsc_event(temp,temp2,temp3)); + + order := 0; + patt := BYTE_NULL; + + Repeat + If (songdata.pattern_order[order] > $31) then Inc(order) + else + begin + patt := songdata.pattern_order[order]; + patt_break := BYTE_NULL; + For temp2 := 0 to $3f do + For temp3 := 1 to 9 do + begin + get_chunk(patt,temp2,temp3,chunk); + event := _hsc_event(patt,temp2,temp3); + + Case HI(event) of + { REGULAR NOTE } + 1..12*8+1: begin + If accurate_conv then + If (voice[temp3] = 0) then + begin + voice[temp3] := temp3; + chunk.instr_def := voice[temp3]; + end; + + If NOT accurate_conv then + chunk.instr_def := voice[temp3]; + end; + + { INSTRUMENT } + $80: If (temp2 <> patt_break) then + begin + voice[temp3] := LO(event)+1; + If NOT accurate_conv then + begin + chunk.instr_def := voice[temp3]; + chunk.note := BYTE_NULL; + end; + end; + end; + + If (HI(event) <> $80) then + Case (LO(event) AND $0f0) of + { PATTERNBREAK } + $00: If (LO(event) AND $0f = 1) then + patt_break := temp2+1; + + { SET CARRIER VOLUME } + $a0: If (chunk.instr_def = 0) and NOT accurate_conv then + chunk.instr_def := voice[temp3] + else If (chunk.instr_def = 0) and + (voice[temp3] = 0) then chunk.instr_def := temp3; + + { SET MODULATOR VOLUME } + $b0: If (chunk.instr_def = 0) and NOT accurate_conv then + chunk.instr_def := voice[temp3] + else If (chunk.instr_def = 0) and + (voice[temp3] = 0) then chunk.instr_def := temp3; + + { SET INSTRUMENT VOLUME } + $c0: If (chunk.instr_def = 0) and NOT accurate_conv then + chunk.instr_def := voice[temp3] + else If (chunk.instr_def = 0) and + (voice[temp3] = 0) then chunk.instr_def := temp3; + end; + + If (Pos(CHR(songdata.pattern_order[order]),patts) = 0) then + put_chunk(patt,temp2,temp3,chunk); + end; + Inc(order); + patts := patts+CHR(patt); + end; + until (patt >= patterns) or (order > $7f); +end; + +procedure import_hsc_instrument(inst: Byte; var data); +begin + With songdata.instr_data[inst] do + begin + fm_data.AM_VIB_EG_carrier := tDUMMY_BUFF(data)[0]; + fm_data.AM_VIB_EG_modulator := tDUMMY_BUFF(data)[1]; + fm_data.KSL_VOLUM_carrier := tDUMMY_BUFF(data)[2]; + fm_data.KSL_VOLUM_modulator := tDUMMY_BUFF(data)[3]; + fm_data.ATTCK_DEC_carrier := tDUMMY_BUFF(data)[4]; + fm_data.ATTCK_DEC_modulator := tDUMMY_BUFF(data)[5]; + fm_data.SUSTN_REL_carrier := tDUMMY_BUFF(data)[6]; + fm_data.SUSTN_REL_modulator := tDUMMY_BUFF(data)[7]; + fm_data.FEEDBACK_FM := tDUMMY_BUFF(data)[8] AND $0f; + fm_data.WAVEFORM_carrier := tDUMMY_BUFF(data)[9] AND 3; + fm_data.WAVEFORM_modulator := tDUMMY_BUFF(data)[10] AND 3; + end; + + songdata.instr_data[inst].panning := 0; + songdata.instr_data[inst].fine_tune := tDUMMY_BUFF(data)[11] SHR 4; +end; + +var + hscbuf: tHSC_DATA; + +procedure hsc_file_loader; + +const + HSC_KSL: array[0..3] of Byte = (0,3,2,1); + +var + f: File; + temp,temp2,temp3: Longint; + +begin + If (Lower(ExtOnly(songdata_source)) <> 'hsc') then + begin + load_flag := $7f; + EXIT; + end; + + {$i-} + Assign(f,songdata_source); + ResetF(f); + {$i+} + If (IOresult <> 0) then + begin + CloseF(f); + EXIT; + end; + + FillChar(hscbuf,SizeOf(hscbuf),0); + BlockReadF(f,hscbuf,SizeOf(hscbuf),temp); + If (temp < SizeOf(hscbuf.instr)+SizeOf(hscbuf.order)) then + begin + CloseF(f); + EXIT; + end; + + For temp2 := 0 to $31 do + If (hscbuf.order[temp2] > $b0) then hscbuf.order[temp2] := $080; + + temp3 := 0; + While (temp3 < temp-SizeOf(hscbuf.instr)-SizeOf(hscbuf.order)) do + begin + If NOT (tDUMMY_BUFF(Addr(hscbuf.patts)^)[temp3+1] in + [1..12*8+1,$00,$7f,$80]) or + NOT (tDUMMY_BUFF(Addr(hscbuf.patts)^)[temp3] AND $0f0 in + [$00,$10,$20,$a0,$b0,$c0,$f0]) then + begin + If NOT (tDUMMY_BUFF(Addr(hscbuf.patts)^)[temp3+1] in + [1..12*8+1,$00,$7f,$80]) then + tDUMMY_BUFF(Addr(hscbuf.patts)^)[temp3+1] := $00; + + If NOT (tDUMMY_BUFF(Addr(hscbuf.patts)^)[temp3] AND $0f0 in + [$00,$10,$20,$a0,$b0,$c0,$f0]) then + tDUMMY_BUFF(Addr(hscbuf.patts)^)[temp3] := 0; + end; + Inc(temp3,2); + end; + + init_songdata; + load_flag := 0; + + songdata.patt_len := 64; + If adjust_tracks then songdata.nm_tracks := 9 + else If (songdata.nm_tracks < 9) then songdata.nm_tracks := 9; + + tempo := 18; + speed := 2; + + songdata.common_flag := songdata.common_flag OR 2; + songdata.tempo := tempo; + songdata.speed := speed; + import_old_flags; + + For temp2 := 0 to $31 do + songdata.pattern_order[temp2] := hscbuf.order[temp2]; + + import_hsc_patterns(hscbuf.patts,(temp-SizeOf(hscbuf.instr) + -SizeOf(hscbuf.order)-1) DIV $480); + +// specific corrections for HSC-Tracker instrument + For temp2 := 0 to $7f do + begin + import_hsc_instrument(temp2+1,hscbuf.instr[temp2]); + With songdata.instr_data[temp2+1].fm_data do + begin + KSL_VOLUM_modulator := KSL_VOLUM_modulator AND $3f+ + HSC_KSL[KSL_VOLUM_modulator SHR 6] SHL 6; + KSL_VOLUM_carrier := KSL_VOLUM_carrier AND $3f+ + HSC_KSL[KSL_VOLUM_carrier SHR 6] SHL 6; + end; + end; + + CloseF(f); + songdata_title := NameOnly(songdata_source); + load_flag := 9; +end; + +type + tMTK_DATA = Record + sname: String[33]; + compo: String[33]; + instn: array[0..$7f] of String[33]; + instt: array[0..$7f] of array[0..$0b] of Byte; + order: array[0..$7f] of Byte; + patts: tHSC_PATTERNS; + dummy: Byte; + end; + +var + buffer2: tMTK_DATA; + +procedure mtk_file_loader; + +var + f: File; + temp,temp2: Longint; + crc: Word; + old_c_fix: Boolean; + +const + id = 'mpu401tr’kkîr@data'; + +var + header: Record + id_string: array[1..18] of Char; + crc_16bit: Word; + data_size: Word; + end; +begin + {$i-} + Assign(f,songdata_source); + ResetF(f); + {$i+} + If (IOresult <> 0) then + begin + CloseF(f); + EXIT; + end; + + BlockReadF(f,header,SizeOf(header),temp); + If NOT ((temp = SizeOf(header)) and (header.id_string = id)) then + begin + CloseF(f); + EXIT; + end; + + load_flag := $7f; + FillChar(buf1,SizeOf(buf1),0); + BlockReadF(f,buf1,SizeOf(buf1),temp); + + crc := 0; + crc := Update16(buf1,temp,crc); + If (crc <> header.crc_16bit) then + begin + CloseF(f); + EXIT; + end; + + FillChar(buffer2,SizeOf(buffer2),0); + temp2 := RDC_decompress(buf1,buffer2,temp); + If NOT (temp2 = header.data_size) then + begin + CloseF(f); + EXIT; + end; + + init_songdata; + load_flag := 0; + + songdata.patt_len := 64; + If adjust_tracks then songdata.nm_tracks := 9 + else If (songdata.nm_tracks < 9) then songdata.nm_tracks := 9; + + tempo := 18; + speed := 2; + + songdata.common_flag := songdata.common_flag OR 2; + songdata.tempo := tempo; + songdata.speed := speed; + import_old_flags; + + For temp2 := 0 to $31 do + If (buffer2.order[temp2] <> $ff) then songdata.pattern_order[temp2] := buffer2.order[temp2] + else songdata.pattern_order[temp2] := $080; + + old_c_fix := fix_c_note_bug; + fix_c_note_bug := FALSE; + import_hsc_patterns(buffer2.patts, + (header.data_size-SizeOf(buffer2.sname) + -SizeOf(buffer2.compo) + -SizeOf(buffer2.instn) + -SizeOf(buffer2.instt) + -SizeOf(buffer2.order)-1) DIV $480); + fix_c_note_bug := old_c_fix; + +// specific corrections for MPU-401 TR’KKîR instrument + For temp2 := 0 to $7f do + begin + import_hsc_instrument(temp2+1,buffer2.instt[temp2]); + With songdata.instr_data[temp2+1].fm_data do + begin + If (KSL_VOLUM_modulator > 128) then + KSL_VOLUM_modulator := KSL_VOLUM_modulator DIV 3; + If (KSL_VOLUM_carrier > 128) then + KSL_VOLUM_carrier := KSL_VOLUM_carrier DIV 3; + end; + + songdata.instr_names[temp2+1] := + Copy(songdata.instr_names[temp2+1],1,9)+ + truncate_string(Copy(buffer2.instn[temp2],10,32)); + end; + + songdata.songname := CutStr(buffer2.sname); + songdata.composer := CutStr(buffer2.compo); + + CloseF(f); + songdata_title := NameOnly(songdata_source); + load_flag := 10; +end; + +procedure rad_file_loader; + +const + id = 'RAD by REALiTY!!'; + +var + header: Record + ident: array[1..16] of Char; { Use this to recognize a RAD tune } + rmver: Byte; { Version of RAD file (10h) } + xbyte: Byte; { bit7 Set if a description follows } + end; { bit6 Set if it's a "slow-timer" tune } + { bit[4..0] The initial speed of the tune } +var + f: File; + dscbuf: array[0..PRED(80*22)] of Char; + pattoffs: array[0..$1f] of Word; + temp,temp2,temp3,temp4,temp5,offs0: Longint; + +procedure import_rad_event(pattern,line,channel,byte1,byte2,byte3: Byte); + +var + chunk: tCHUNK; + +begin + FillChar(chunk,SizeOf(chunk),0); + If ((byte2 SHR 4)+(byte1 SHR 7) SHL 4 <> 0) then + chunk.instr_def := (byte2 SHR 4)+(byte1 SHR 7) SHL 4; + + If (byte1 AND $0f in [1..12]) then chunk.note := 12*((byte1 SHR 4) AND 7)+(byte1 AND $0f)+1 + else If (byte1 AND $0f = $0f) then chunk.note := BYTE_NULL; + + Case byte2 AND $0f of + { PORTAMENTO (FREQUENCY SLIDE) UP } + $01: begin + chunk.effect_def := ef_FSlideUp; + chunk.effect := byte3; + end; + + { PORTAMENTO (FREQUENCY SLIDE) DOWN } + $02: begin + chunk.effect_def := ef_FSlideDown; + chunk.effect := byte3; + end; + + { PORTAMENTO TO NOTE } + $03: begin + chunk.effect_def := ef_TonePortamento; + chunk.effect := byte3; + end; + + { PORTAMENTO TO NOTE WITH VOLUME SLIDE } + $05: If (byte3 in [1..49]) then + begin + chunk.effect_def := ef_TPortamVolSlide; + chunk.effect := max(byte3,15); + + If (byte3 > 15) then + begin + chunk.effect_def2 := ef_TPortamVolSlide; + chunk.effect2 := max(byte3-15,15); + end; + end + else If (byte3 in [51..99]) then + begin + chunk.effect_def := ef_TPortamVolSlide; + chunk.effect := max(byte3-50,15)*16; + + If (byte3-50 > 15) then + begin + chunk.effect_def2 := ef_TPortamVolSlide; + chunk.effect2 := max(byte3-50-15,15); + end; + end; + + { VOLUME SLIDE } + $0a: If (byte3 in [1..49]) then + begin + chunk.effect_def := ef_VolSlide; + chunk.effect := max(byte3,15); + + If (byte3 > 15) then + begin + chunk.effect_def2 := ef_VolSlide; + chunk.effect2 := max(byte3-15,15); + end; + end + else If (byte3 in [51..99]) then + begin + chunk.effect_def := ef_VolSlide; + chunk.effect := max(byte3-50,15)*16; + + If (byte3-50 > 15) then + begin + chunk.effect_def2 := ef_VolSlide; + chunk.effect2 := max(byte3-50-15,15); + end; + end; + + { SET VOLUME } + $0c: begin + chunk.effect_def := ef_SetInsVolume; + If (byte3 < 64) then chunk.effect := byte3 + else chunk.effect := 63; + end; + + { JUMP TO NEXT PATTERN IN ORDER LIST } + $0d: begin + chunk.effect_def := ef_PatternBreak; + If (byte3 < 64) then chunk.effect := byte3 + else chunk.effect := 63; + end; + + { SET SPEED } + $0f: begin + chunk.effect_def := ef_SetSpeed; + chunk.effect := byte3; + end; + end; + +// specific corrections for RAd-Tracker event + If (chunk.effect_def in [ef_TonePortamento, + ef_TPortamVolSlide]) and + (chunk.note = BYTE_NULL) then chunk.note := 0; + If (chunk.effect_def in [ef_TonePortamento, + ef_TPortamVolSlide]) then chunk.instr_def := 0; + If (chunk.note = 0) then chunk.instr_def := 0; + put_chunk(pattern,line,channel+1,chunk); +end; + + +begin + {$i-} + Assign(f,songdata_source); + ResetF(f); + {$i+} + If (IOresult <> 0) then + begin + CloseF(f); + EXIT; + end; + + BlockReadF(f,header,SizeOf(header),temp); + If NOT ((temp = SizeOf(header)) and (header.ident = id)) then + begin + CloseF(f); + EXIT; + end; + + load_flag := $7f; + FillChar(buf1,SizeOf(buf1),0); + BlockReadF(f,buf1,SizeOf(buf1),temp); + If (IOresult <> 0) then + begin + CloseF(f); + EXIT; + end; + + temp2 := 0; + offs0 := SizeOf(header); + + If (header.xbyte OR $80 = header.xbyte) then + begin + While (temp2 < temp) and (buf1[temp2] <> 0) do Inc(temp2); + If (temp2 >= temp) then + begin + CloseF(f); + EXIT; + end; + + Inc(offs0,temp2+1); + Dec(temp,temp2+1); + Move(buf1,dscbuf,temp2+1); + Move(buf1[temp2+1],buf1,temp); + end; + + + init_songdata; + load_flag := 0; + + songdata.patt_len := 64; + If adjust_tracks then songdata.nm_tracks := 9 + else If (songdata.nm_tracks < 9) then songdata.nm_tracks := 9; + + If (header.xbyte OR $40 = header.xbyte) then tempo := 18 + else tempo := 50; + + If (header.xbyte AND $1f in [1..31]) then speed := header.xbyte AND $1f + else speed := 2; + + songdata.tempo := tempo; + songdata.speed := speed; + + temp2 := 0; + Repeat + temp3 := buf1[temp2]; + Inc(temp2); + If (temp3 <> 0) and (temp2+11 < temp) then + begin + import_hsc_instrument(temp3,buf1[temp2]); + songdata.instr_data[temp3].fine_tune := 0; + Inc(temp2,11); + end; + until (temp3 = 0) or (temp3 >= temp); + + Inc(offs0,temp2); + Dec(temp,temp2); + Move(buf1[temp2],buf1,temp); + + Inc(offs0,buf1[0]+1); + If (buf1[0] <> 0) then + Move(buf1[1],songdata.pattern_order,buf1[0]); + + Inc(offs0,32*SizeOf(WORD)); + Dec(temp,buf1[0]+1+32*SizeOf(WORD)); + + Move(buf1[buf1[0]+1],pattoffs,32*SizeOf(WORD)); + Move(buf1[buf1[0]+32*SizeOf(WORD)+1],buf1,temp); + + temp5 := temp; + For temp := 0 to 31 do + begin + temp2 := 0; + temp3 := 0; + If (pattoffs[temp] <> 0) and + (pattoffs[temp] <= FileSize(f)) then + Repeat + temp2 := buf1[pattoffs[temp]-offs0+temp3]; + Repeat + Inc(temp3); + temp4 := buf1[pattoffs[temp]-offs0+temp3]; + If (buf1[pattoffs[temp]-offs0+temp3+2] AND $0f <> 0) then + begin + If (temp4 AND $0f in [0..8]) then + import_rad_event(temp,temp2 AND $3f,temp4 AND $0f, + buf1[pattoffs[temp]-offs0+temp3+1], + buf1[pattoffs[temp]-offs0+temp3+2], + buf1[pattoffs[temp]-offs0+temp3+3]); + Inc(temp3,3); + end + else begin + If (temp4 AND $0f in [0..8]) then + import_rad_event(temp,temp2 AND $3f,temp4 AND $0f, + buf1[pattoffs[temp]-offs0+temp3+1], + buf1[pattoffs[temp]-offs0+temp3+2], + 0); + Inc(temp3,2); + end; + until (temp4 OR $80 = temp4) or (temp3 > temp5); + Inc(temp3); + until (temp2 OR $80 = temp2) or (temp3 > temp5); + end; + + CloseF(f); + songdata_title := NameOnly(songdata_source); + load_flag := 11; +end; + +const + temp_ef_Arpeggio = $0f0; + temp_ef_rep = $0f1; + temp_ef_XFVSlide = $0f2; + +var + ins_c4factor: array[1..99] of Shortint; + +procedure fix_s3m_commands(patterns: Byte); + +var + chunk,chunk2: tCHUNK; + temp,temp4: Byte; + patt_break: Byte; + order,patt: Byte; + patts: String; + ins_cache, + misc_cache, + arpg_cache, + volsld_cache, + slide_cache, + note_cache, + patloop_cache: array[1..20] of Byte; + prev_cache: array[1..20] of Record + effect_def, + effect, + effect_def2, + effect2: Byte; + end; + +procedure fix_single_pattern(patt: Byte); + +var + temp2,temp3: Byte; + +begin + FillChar(prev_cache,SizeOf(prev_cache),0); + FillChar(patloop_cache,SizeOf(patloop_cache),BYTE_NULL); + patt_break := BYTE_NULL; + + For temp2 := 0 to $3f do + For temp3 := 1 to 20 do + begin + get_chunk(patt,temp2,temp3,chunk); + If (chunk.effect_def in [ef_PositionJump,ef_PatternBreak]) then + patt_break := temp2; + + If (chunk.instr_def <> 0) and (temp2 <= patt_break) then + ins_cache[temp3] := chunk.instr_def; + + If (chunk.note in [1..12*8+1]) and (temp2 <= patt_break) then + note_cache[temp3] := chunk.note; + + If (chunk.instr_def <> 0) or ((chunk.instr_def = 0) and + (chunk.note in [1..12*8+1]) and + (ins_cache[temp3] <> 0)) then + begin + If (chunk.instr_def <> 0) then temp4 := chunk.instr_def + else temp4 := ins_cache[temp3]; + If (ins_c4factor[temp4] <> 0) and + NOT (Pos(CHR(songdata.pattern_order[order]),patts) <> 0) then + begin + If (ins_c4factor[temp4] <> -127) then + chunk.note := min(max(chunk.note+ins_c4factor[temp4],12*8+1),1) + else chunk.note := 1; + put_chunk(patt,temp2,temp3,chunk); + end; + end; + + If (chunk.effect_def = ef_Extended) and + (chunk.effect DIV 16 = ef_ex_PatternLoop) and + (chunk.effect MOD 16 <> 0) then + If NOT (patloop_cache[temp3] in [0,BYTE_NULL]) and (temp2 <> 0) then + begin + If (prev_cache[temp3].effect_def = 0) and + (prev_cache[temp3].effect = 0) then + begin + get_chunk(patt,PRED(temp2),temp3,chunk2); + chunk2.effect_def := ef_Extended; + chunk2.effect := ef_ex_PatternLoop*16; + If NOT ((chunk2.effect_def = chunk2.effect_def2) and + (chunk2.effect = chunk2.effect2)) then + begin + put_chunk(patt,PRED(temp2),temp3,chunk2); + prev_cache[temp3].effect_def := chunk.effect_def; + prev_cache[temp3].effect := chunk.effect; + end; + end + else If (prev_cache[temp3].effect_def2 = 0) and + (prev_cache[temp3].effect2 = 0) then + begin + get_chunk(patt,PRED(temp2),temp3,chunk2); + chunk2.effect_def2 := ef_Extended; + chunk2.effect2 := ef_ex_PatternLoop*16; + If NOT ((chunk2.effect_def2 = chunk2.effect_def) and + (chunk2.effect2 = chunk2.effect)) then + begin + put_chunk(patt,PRED(temp2),temp3,chunk2); + prev_cache[temp3].effect_def2 := chunk.effect_def2; + prev_cache[temp3].effect2 := chunk.effect2; + end; + end; + end + else If (patloop_cache[temp3] <> 0) and (temp2 <> 0) then + begin + get_chunk(patt,0,temp3,chunk2); + If (chunk2.effect_def = 0) and + (chunk2.effect = 0) then + begin + chunk2.effect_def := ef_Extended; + chunk2.effect := ef_ex_PatternLoop*16; + If NOT ((chunk2.effect_def = chunk2.effect_def2) and + (chunk2.effect = chunk2.effect2)) then + put_chunk(patt,0,temp3,chunk2); + end + else If (chunk2.effect_def2 = 0) and + (chunk2.effect2 = 0) then + begin + chunk2.effect_def2 := ef_Extended; + chunk2.effect2 := ef_ex_PatternLoop*16; + If NOT ((chunk2.effect_def2 = chunk2.effect_def) and + (chunk2.effect2 = chunk2.effect)) then + put_chunk(patt,0,temp3,chunk2); + end; + end; + + If (temp2 <= patt_break) then + begin + If (chunk.effect DIV 16 <> 0) then + misc_cache[temp3] := chunk.effect AND $0f0+ + misc_cache[temp3] AND $0f + else If (chunk.effect_def in [ef_Vibrato, + ef_ExtraFineVibrato, + ef_Tremolo, + ef_Tremor, + ef_MultiRetrigNote]) then + begin + chunk.effect := misc_cache[temp3] AND $0f0+ + chunk.effect AND $0f; + put_chunk(patt,temp2,temp3,chunk); + end; + + If (chunk.effect MOD 16 <> 0) then + misc_cache[temp3] := misc_cache[temp3] AND $0f0+ + chunk.effect AND $0f + else If (chunk.effect_def in [ef_Vibrato, + ef_ExtraFineVibrato, + ef_Tremolo, + ef_Tremor, + ef_MultiRetrigNote]) then + begin + chunk.effect := chunk.effect AND $0f0+ + misc_cache[temp3] AND $0f; + put_chunk(patt,temp2,temp3,chunk); + end; + + If (chunk.effect_def = temp_ef_Arpeggio) then + If (chunk.effect <> 0) then arpg_cache[temp3] := chunk.effect + else begin + chunk.effect := arpg_cache[temp3]; + put_chunk(patt,temp2,temp3,chunk); + end; + + If (chunk.effect_def in [ef_FSlideDown,ef_FSlideDownFine, + ef_FSlideUp,ef_FSlideUpFine, + ef_TonePortamento]) then + If (chunk.effect <> 0) then slide_cache[temp3] := chunk.effect + else begin + chunk.effect := slide_cache[temp3]; + put_chunk(patt,temp2,temp3,chunk); + end; + + // experimental method to fix up frequency slide + If (chunk.effect_def in [ef_FSlideDown,ef_FSlideDownFine, + ef_FSlideUp,ef_FSlideUpFine, + ef_Vibrato, + ef_ExtraFineVibrato, + ef_TonePortamento]) then + If (note_cache[temp3] <> 0) then + begin + If (chunk.effect_def in [ef_Vibrato,ef_ExtraFineVibrato]) then + begin + temp := chunk.effect AND $0f0; + chunk.effect := chunk.effect MOD 16; + end; + + Case SUCC(PRED(note_cache[temp3]) DIV 12) of + 1: chunk.effect := max(Round(chunk.effect*0.55),255); + 2: chunk.effect := max(Round(chunk.effect*0.75),255); + 3: chunk.effect := max(Round(chunk.effect*0.95),255); + 4: chunk.effect := max(Round(chunk.effect*1.15),255); + 5: chunk.effect := max(Round(chunk.effect*1.35),255); + 6: chunk.effect := max(Round(chunk.effect*1.55),255); + 7: chunk.effect := max(Round(chunk.effect*1.75),255); + 8: chunk.effect := max(Round(chunk.effect*1.95),255); + end; + + If (chunk.effect_def in [ef_Vibrato,ef_ExtraFineVibrato]) then + chunk.effect := max(chunk.effect,15)+temp; + + put_chunk(patt,temp2,temp3,chunk); + end; + + If (chunk.effect_def = ef_Extended2) and + (chunk.effect DIV 16 in [ef_ex2_FreqSlideDnXF,ef_ex2_FreqSlideUpXF]) then + If (chunk.effect MOD 16 <> 0) then slide_cache[temp3] := chunk.effect MOD 16 + else begin + chunk.effect := chunk.effect AND $0f0+slide_cache[temp3] AND $0f; + put_chunk(patt,temp2,temp3,chunk); + end; + + If (chunk.effect_def in [ef_TPortamVolSlide,ef_VibratoVolSlide, + ef_VolSlide,ef_VolSlideFine]) and + (temp2 <= patt_break) then + begin + If (chunk.effect <> 0) then volsld_cache[temp3] := chunk.effect + else begin + chunk.effect := volsld_cache[temp3];; + put_chunk(patt,temp2,temp3,chunk); + end; + end; + + If (chunk.effect_def = ef_Extended2) and + (chunk.effect DIV 16 in [ef_ex2_VolSlideDnXF,ef_ex2_VolSlideUpXF]) then + If (chunk.effect MOD 16 <> 0) then + Case chunk.effect DIV 16 of + ef_ex2_VolSlideDnXF: + volsld_cache[temp3] := chunk.effect MOD 16; + ef_ex2_VolSlideUpXF: + volsld_cache[temp3] := chunk.effect MOD 16 SHL 4; + end + else begin + Case chunk.effect DIV 16 of + ef_ex2_VolSlideDnXF: + chunk.effect := chunk.effect AND $0f0+volsld_cache[temp3] AND $0f; + ef_ex2_VolSlideUpXF: + chunk.effect := volsld_cache[temp3] AND $0f0+chunk.effect AND $0f; + end; + put_chunk(patt,temp2,temp3,chunk); + end; + end; + + If (prev_cache[temp3].effect_def in [ef_Vibrato,ef_ExtraFineVibrato,ef_VibratoVolSlide]) and + NOT (chunk.effect_def in [ef_Vibrato,ef_ExtraFineVibrato,ef_VibratoVolSlide]) then + If (chunk.effect_def = 0) and (chunk.effect = 0) then + begin + chunk2 := chunk; + chunk2.effect_def := ef_Extended; + chunk2.effect := ef_ex_ExtendedCmd*16+ef_ex_cmd_VibrOff; + If NOT ((chunk2.effect_def = chunk2.effect_def2) and + (chunk2.effect = chunk2.effect2)) then + begin + put_chunk(patt,temp2,temp3,chunk2); + chunk := chunk2; + end; + end + else If (chunk.effect_def2 = 0) and (chunk.effect2 = 0) then + begin + chunk2 := chunk; + chunk2.effect_def2 := ef_Extended; + chunk2.effect2 := ef_ex_ExtendedCmd*16+ef_ex_cmd_VibrOff; + If NOT ((chunk2.effect_def2 = chunk2.effect_def) and + (chunk2.effect2 = chunk2.effect)) then + begin + put_chunk(patt,temp2,temp3,chunk2); + chunk := chunk2; + end; + end; + + If (chunk.effect_def = ef_Extended) and + (chunk.effect DIV 16 = ef_ex_PatternLoop) then + patloop_cache[temp3] := chunk.effect MOD 16; + + prev_cache[temp3].effect_def := chunk.effect_def; + prev_cache[temp3].effect := chunk.effect; + prev_cache[temp3].effect_def2 := chunk.effect_def2; + prev_cache[temp3].effect2 := chunk.effect2; + + If (chunk.effect_def = temp_ef_Arpeggio) then + begin + chunk2 := chunk; + chunk2.effect_def := ef_Arpeggio; + put_chunk(patt,temp2,temp3,chunk2); + end; + end; +end; + +begin { fix_s3m_commands } + FillChar(ins_cache,SizeOf(ins_cache),0); + FillChar(note_cache,SizeOf(note_cache),0); + FillChar(volsld_cache,SizeOf(volsld_cache),0); + FillChar(slide_cache,SizeOf(slide_cache),0); + FillChar(misc_cache,SizeOf(misc_cache),0); + FillChar(arpg_cache,SizeOf(arpg_cache),0); + + patts := ''; + order := 0; patt := BYTE_NULL; + + Repeat + If (songdata.pattern_order[order] >= $80) then Inc(order) + else + begin + patt := songdata.pattern_order[order]; + If NOT (Pos(CHR(patt),patts) <> 0) then + fix_single_pattern(patt); + Inc(order); + patts := patts+CHR(patt); + end; + until (patt >= patterns) or (order > $7f); + + For patt := 0 to PRED(patterns) do + If NOT (Pos(CHR(patt),patts) <> 0) then + fix_single_pattern(patt); +end; + +procedure s3m_file_loader; + +type + tS3M_HEADER = Record + songname: array[1..28] of Char; { ASCIIZ } + byte1a: Byte; { 1Ah } + ftype: Byte; { File type: 16=ST3 module } + resrvd1: array[0..1] of Byte; + ordnum: Word; { Number of orders in file (should be even!) } + insnum: Word; { Number of instruments in file } + patnum: Word; { Number of patterns in file } + flags: Word; { [ These are old flags for Ffv1. Not supported in ST3.01 } + { | +1:st2vibrato } + { | +2:st2tempo } + { | +4:amigaslides } + { | +32:enable filter/sfx with sb } + { ] } + { +8: 0vol optimizations } + { Automatically turn off looping notes whose volume } + { is zero for >2 note rows. } + { +16: amiga limits } + { Disallow any notes that go beyond the amiga hardware } + { limits (like amiga does). This means that sliding } + { up stops at B#5 etc. Also affects some minor amiga } + { compatibility issues. } + { +64: st3.00 volumeslides } + { Normally volumeslide is NOT performed on first } + { frame of each row (this is according to amiga } + { playing). If this is set, volumeslide is performed } + { ALSO on the first row. This is set by default } + { if the Cwt/v files is 0x1300 } + { +128: special custom data in file (see below) } + cwt_v: Word; { Created with tracker / version: &0xfff=version, >>12=tracker } + { ST3.00:0x1300 (NOTE: volumeslides on EVERY frame) } + { ST3.01:0x1301 } + { ST3.03:0x1303 } + { ST3.20:0x1320 } + ffi: Word; { File format information } + { 1=[VERY OLD] signed samples } + { 2=unsigned samples } + id: array[1..4] of Char; { "SCRM" } + g_v: Byte; { global volume (see next section) } + i_s: Byte; { initial speed (command A) } + + i_t: Byte; { initial tempo (command T) } + m_v: Byte; { master volume (see next section) 7 lower bits } + { bit 8: stereo(1) / mono(0) } + u_c: Byte; { ultra click removal } + d_p: Byte; { 252 when default channel pan positions are present } + { in the end of the header (xxx3). If !=252 ST3 doesn't } + { try to load channel pan settings. } + resrvd2: array[0..7] of Byte; + special: Word; + chan_set: array[1..32] of Byte; + end; +type + tS3M_ADLINS = Record + itype: Byte; { 2:amel 3:abd 4:asnare 5:atom 6:acym 7:ahihat } + dosname: array[1..12] of Char; + id0: array[0..2] of Char; + fmdata: array[0..11] of Byte; { D00..D0B contains the adlib instrument specs packed like this: } + { modulator: carrier: } + { D00=[freq.muliplier]+[?scale env.]*16+[?sustain]*32+ =D01 } + { [?pitch vib]*64+[?vol.vib]*128 } + { D02=[63-volume]+[levelscale&1]*128+[l.s.&2]*64 =D03 } + { D04=[attack]*16+[decay] =D05 } + { D06=[15-sustain]*16+[release] =D07 } + { D08=[wave select] =D09 } + { D0A=[modulation feedback]*2+[?additive synthesis] } + { D0B=unused } + vol: Byte; { Default volume 0..64 } + dsk: Byte; + resrvd1: array[0..1] of Byte; + c2spd: Word; { 'Herz' for middle C. ST3 only uses lower 16 bits. } + { Actually this is a modifier since there is no } + { clear frequency for adlib instruments. It scales } + { the note freq sent to adlib. } + hi_c2sp: Word; + resrvd2: array[0..11] of Byte; + smpname: array[1..28] of Char; { ASCIIZ } + id: array[1..4] of Char; { "SCRI" or "SCRS" } + end; +const + id_mod = 'SCRM'; + id_ins_adl = 'SCRI'; + id_ins_smp = 'SCRS'; + +var + f: File; + header: tS3M_HEADER; + order_list: array[0..254] of Byte; + paraptr_ins: array[1..99] of Word; + default_vol: array[1..99] of Byte; + paraptr_pat: array[0..99] of Word; + temp,temp2: Longint; + insdata: tS3M_ADLINS; + pat,row,chan: Byte; + note,ins,vol,cmd,info: Byte; + patlen,index: Word; + +procedure import_s3m_event(pattern,line,channel,note,ins,vol,cmd,info: Byte); + +var + chunk: tCHUNK; + +function scale_slide(slide: Byte): Byte; +begin + If (slide > 16) then scale_slide := Round(16+slide/8) + else scale_slide := Round(slide*(2-slide/16)); +end; + +begin + FillChar(chunk,SizeOf(chunk),0); + chunk.instr_def := ins; + + Case note of + 254: chunk.note := BYTE_NULL; + 255: chunk.note := 0; + else If (note AND $0f in [0..11]) then + chunk.note := 12*((note SHR 4) AND 7)+(note AND $0f)+1 + end; + + If (vol <> BYTE_NULL) then + begin + chunk.effect_def2 := ef_SetInsVolume; + chunk.effect2 := max(vol,63); + end + else + If NOT (note in [254,255]) and + (ins <> 0) and + (max(default_vol[ins],63) <> 63) then + begin + chunk.effect_def2 := ef_SetInsVolume; + chunk.effect2 := max(default_vol[ins],63); + end; + + Case CHR(cmd+ORD('A')-1) of + { NONE } + '@': chunk.effect := info; + + { SET SPEED } + 'A': If (info <> 0) then + begin + chunk.effect_def := ef_SetSpeed; + chunk.effect := info; + end; + + { JUMP TO ORDER } + 'B': If (info <= 254) then + begin + chunk.effect_def := ef_PositionJump; + chunk.effect := info; + end; + + { BREAK PATTERN } + 'C': If (info < 64) then + begin + chunk.effect_def := ef_PatternBreak; + chunk.effect := Str2num(Num2str(info,16),10); + end; + + { VOLUME SLIDE } + 'D': { VOLUME SLIDE DOWN } + Case info DIV 16 of + { NORMAL } + 0: begin + chunk.effect_def := ef_VolSlide; + chunk.effect := info MOD 16; + end; + + { FINE } + 15: begin + chunk.effect_def := ef_VolSlideFine; + chunk.effect := info MOD 16; + end; + else + { VOLUME SLIDE UP } + Case info MOD 16 of + { NORMAL } + 0: begin + chunk.effect_def := ef_VolSlide; + chunk.effect := info AND $0f0; + end; + + { FINE } + 15: begin + chunk.effect_def := ef_VolSlideFine; + chunk.effect := info AND $0f0; + end; + end; + end; + + { SLIDE DOWN } + 'E': Case info DIV 16 of + { NORMAL } + 0..13: begin + chunk.effect_def := ef_FSlideDown; + chunk.effect := scale_slide(info); + end; + + { EXTRA FINE } + 14: begin + chunk.effect_def := ef_Extended2; + If (info <> 0) then + chunk.effect := ef_ex2_FreqSlideDnXF*16+min((info AND $0f) DIV 4,1) + else chunk.effect := ef_ex2_FreqSlideDnXF*16; + end; + + { FINE } + 15: begin + chunk.effect_def := ef_FSlideDownFine; + chunk.effect := info AND $0f; + end; + end; + + { SLIDE UP } + 'F': Case info DIV 16 of + { NORMAL } + 0..13: begin + chunk.effect_def := ef_FSlideUp; + chunk.effect := scale_slide(info); + end; + + { EXTRA FINE } + 14: begin + chunk.effect_def := ef_Extended2; + If (info <> 0) then + chunk.effect := ef_ex2_FreqSlideUpXF*16+min((info AND $0f) DIV 4,1) + else chunk.effect := ef_ex2_FreqSlideUpXF*16; + end; + + { FINE } + 15: begin + chunk.effect_def := ef_FSlideUpFine; + chunk.effect := info AND $0f; + end; + end; + + { TONE PORTAMENTO } + 'G': begin + chunk.effect_def := ef_TonePortamento; + chunk.effect := scale_slide(info); + end; + + { VIBRATO } + 'H': begin + chunk.effect_def := ef_Vibrato; + chunk.effect := info; + end; + + { FINE VIBRATO } + 'U': begin + chunk.effect_def := ef_ExtraFineVibrato; + chunk.effect := info; + end; + + { TREMOR } + 'I': begin + chunk.effect_def := ef_Tremor; + chunk.effect := info; + end; + + { ARPEGGIO } + 'J': begin + chunk.effect_def := temp_ef_Arpeggio; + chunk.effect := info; + end; + + { VIBRATO + VOLUME SLIDE } + 'K': begin + chunk.effect_def := ef_VibratoVolSlide; + chunk.effect := info; + end; + + { TONE PORTAMENTO + VOLUME SLIDE } + 'L': begin + chunk.effect_def := ef_TPortamVolSlide; + chunk.effect := info; + end; + + { RETRIG NOTE + VOLUME SLIDE } + 'Q': begin + chunk.effect_def := ef_MultiRetrigNote; + chunk.effect := (info MOD 16)*16+info DIV 16; + end; + + { TREMOLO } + 'R': begin + chunk.effect_def := ef_Tremolo; + chunk.effect := info; + end; + + { SPECIAL COMMAND } + 'S': Case info DIV 16 of + { PATTERN LOOP } + $0b: begin + chunk.effect_def := ef_Extended; + chunk.effect := ef_ex_PatternLoop*16+info MOD 16; + end; + + { NOTE CUT } + $0c: begin + chunk.effect_def := ef_Extended2; + chunk.effect := ef_ex2_NoteCut*16+info MOD 16; + end; + + { NOTE DELAY } + $0d: begin + chunk.effect_def := ef_Extended2; + chunk.effect := ef_ex2_NoteDelay*16+info MOD 16; + end; + + { PATTERN DELAY } + $0e: begin + chunk.effect_def := ef_Extended2; + chunk.effect := ef_ex2_PatDelayRow*16+info MOD 16; + end; + end; + + { TEMPO } + 'T': If (info >= 32) then + begin + chunk.effect_def := ef_SetTempo; + chunk.effect := Round(info/2.5); + end; + + { SET GLOBAL VOLUME } + 'V': begin + chunk.effect_def := ef_SetGlobalVolume; + chunk.effect := max(info,63); + end; + end; + + If (chunk.effect_def = 0) and (chunk.effect <> 0) then + chunk.effect := 0; + put_chunk(pattern,line,channel,chunk); +end; + +// experimental method to fix up note fine-tuning +function find_scale_factor(freq: Longint; var fine_tune: Shortint): Shortint; + +const + _factor: array[-3..3+1] of Real = (1/8,1/4,1/2,1,2,4,8,16); + +const + _freq: array[1..12+1] of Word = + { C-2 C#2 D-2 } + ( 33453 DIV 4,35441 DIV 4,37679 DIV 4, + { D#2 E-2 F-2 } + 39772 DIV 4,42441 DIV 4,44744 DIV 4, + { F#2 G-2 G#2 } + 47727 DIV 4,50416 DIV 4,53426 DIV 4, + { A-2 A#2 B-2 } + 56370 DIV 4,59658 DIV 4,63354 DIV 4, + { C-3 } + 33453 DIV 2); + +const + _fm_freq: array[1..12+1] of Word = + ($156, $16b, $181, $198, $1b0, $1ca, + $1e5, $202, $220, $241, $263, $287, + $2ae); + +var + factor: Real; + temp,scaler: Shortint; + +begin + scaler := -3; + fine_tune := 0; + + For scaler := -3 to 3+1 do + For temp := 1 to 12 do + begin + factor := _factor[scaler]; + If (freq >= Round(_freq[temp]*factor)) and + (freq <= Round(_freq[SUCC(temp)]*factor)) then + If (freq-Round(_freq[temp]*factor) < Round(_freq[SUCC(temp)]*factor)-freq) then + begin + fine_tune := Round((_fm_freq[SUCC(temp)]-_fm_freq[temp])/ + (_freq[SUCC(temp)]-_freq[temp])* + (freq-Round(_freq[temp]*factor))); + find_scale_factor := scaler*12+PRED(temp); + EXIT; + end + else + begin + fine_tune := Round((_fm_freq[SUCC(temp)]-_fm_freq[temp])/ + (_freq[SUCC(temp)]-_freq[temp])* + (freq-Round(_freq[SUCC(temp)]*factor))); + If (temp <> 12) then find_scale_factor := scaler*12+temp + else find_scale_factor := SUCC(scaler)*12; + EXIT; + end; + end; + + find_scale_factor := -127; + fine_tune := 0; +end; + +(* // another method -- it's hard to say whether more or less accurate :) +function find_scale_factor(freq: Longint; var fine_tune: Shortint): Shortint; + +const + _factor: array[-3..3+1] of Real = (1/8,1/4,1/2,1,2,4,8,16); + _finetune_factor: array[-3..3+1] of Real = (8,4,2,1,1/2,1/4,1/8,1/16); + +const + _freq: array[1..12+1] of Word = + { C-2 C#2 D-2 } + ( 33453 DIV 4,35441 DIV 4,37679 DIV 4, + { D#2 E-2 F-2 } + 39772 DIV 4,42441 DIV 4,44744 DIV 4, + { F#2 G-2 G#2 } + 47727 DIV 4,50416 DIV 4,53426 DIV 4, + { A-2 A#2 B-2 } + 56370 DIV 4,59658 DIV 4,63354 DIV 4, + { C-3 } + 33453 DIV 2); + +var + factor: Real; + temp,scaler: Shortint; + +begin + scaler := -3; + fine_tune := 0; + + For scaler := -3 to 3+1 do + For temp := 1 to 12 do + begin + factor := _factor[scaler]; + If (freq >= Round(_freq[temp]*factor)) and + (freq <= Round(_freq[SUCC(temp)]*factor)) then + If (freq-Round(_freq[temp]*factor) < Round(_freq[SUCC(temp)]*factor)-freq) then + begin + fine_tune := Round((freq-Round(_freq[temp]*factor))/ + Round(16/_finetune_factor[scaler])); + find_scale_factor := scaler*12+PRED(temp); + EXIT; + end + else + begin + If (temp = 12) then Inc(scaler); + fine_tune := Round((freq-Round(_freq[SUCC(temp)]*factor))/ + Round(16/_finetune_factor[scaler])); + If (temp = 12) then temp := 0; + find_scale_factor := scaler*12+temp; + EXIT; + end; + end; + + find_scale_factor := -127; + fine_tune := 0; +end; +*) + +begin + {$i-} + Assign(f,songdata_source); + ResetF(f); + {$i+} + If (IOresult <> 0) then + begin + CloseF(f); + EXIT; + end; + + BlockReadF(f,header,SizeOf(header),temp); + If NOT ((temp = SizeOf(header)) and (header.id = id_mod)) then + begin + CloseF(f); + EXIT; + end; + + load_flag := $7f; + If (header.byte1a <> $1a) or (header.ftype <> $10) then + begin + CloseF(f); + EXIT; + end; + + BlockReadF(f,order_list,header.ordnum,temp); + If (IOresult <> 0) or (temp <> header.ordnum) then + begin + CloseF(f); + EXIT; + end; + + BlockReadF(f,paraptr_ins,header.insnum*2,temp); + If (IOresult <> 0) or (temp <> header.insnum*2) then + begin + CloseF(f); + EXIT; + end; + + BlockReadF(f,paraptr_pat,header.patnum*2,temp); + If (IOresult <> 0) or (temp <> header.patnum*2) then + begin + CloseF(f); + EXIT; + end; + + init_songdata; + load_flag := 0; + + If (header.i_s <> 0) then speed := header.i_s + else speed := 1; + + If (Round(header.i_t/2.5) < 255) then tempo := Round(header.i_t/2.5) + else tempo := 255; + + songdata.tempo := tempo; + songdata.speed := speed; + songdata.songname := truncate_string(asciiz_string(header.songname)); + songdata.common_flag := songdata.common_flag OR $80; + import_old_flags; + + For temp := 32 downto 1 do + If (header.chan_set[temp] <> 255) then BREAK; + + + songdata.patt_len := 64; + If adjust_tracks then songdata.nm_tracks := max(temp,18) + else If (songdata.nm_tracks < 18) then songdata.nm_tracks := 18; + + For temp := 1 to max(header.ordnum,128) do + Case order_list[temp-1] of + 254: songdata.pattern_order[temp-1] := $80+temp; + 255: songdata.pattern_order[temp-1] := $80; + else songdata.pattern_order[temp-1] := order_list[temp-1]; + end; + + FillChar(ins_c4factor,SizeOf(ins_c4factor),0); + For temp := 1 to header.insnum do + begin + SeekF(f,paraptr_ins[temp]*16); + If (IOresult <> 0) then + begin + CloseF(f); + EXIT; + end; + + BlockReadF(f,insdata,SizeOf(insdata),temp2); + If (IOresult <> 0) or (temp2 <> SizeOf(insdata)) then + begin + CloseF(f); + EXIT; + end; + + If (truncate_string(insdata.smpname) <> '') then + songdata.instr_names[temp] := + Copy(songdata.instr_names[temp],1,9)+ + Copy(truncate_string(asciiz_string(insdata.smpname)),1,32) + else + songdata.instr_names[temp] := + Copy(songdata.instr_names[temp],1,9)+ + truncate_string(insdata.dosname); + + If (insdata.itype in [2..7]) then + begin + If (insdata.id <> id_ins_adl) and (insdata.id <> id_ins_smp) then + begin + CloseF(f); + EXIT; + end; + + import_standard_instrument(temp,insdata.fmdata); + end; + + default_vol[temp] := insdata.vol; + If (insdata.c2spd <> 0) and + (insdata.c2spd <> 8363) then + ins_c4factor[temp] := find_scale_factor(insdata.c2spd,songdata.instr_data[temp].fine_tune); + end; + + For pat := 0 to PRED(header.patnum) do + begin + SeekF(f,paraptr_pat[pat]*16); + If (IOresult <> 0) then + begin + CloseF(f); + EXIT; + end; + + BlockReadF(f,patlen,SizeOf(patlen),temp2); + If (temp2 <> SizeOf(patlen)) then + begin + CloseF(f); + EXIT; + end; + + If (patlen = 0) then CONTINUE; + FillChar(buf1,SizeOf(buf1),0); + BlockReadF(f,buf1,patlen-2,temp2); + + index := 0; + row := 0; + + Repeat + If (buf1[index] <> 0) then + begin + note := BYTE_NULL; + ins := 0; + vol := BYTE_NULL; + cmd := 0; + info := 0; + temp := buf1[index]; + Inc(index); + + chan := SUCC(temp AND 31); + If (temp OR $20 = temp) then + begin + note := buf1[index]; + Inc(index); + ins := buf1[index]; + Inc(index); + end; + + If (temp OR $40 = temp) then + begin + vol := buf1[index]; + Inc(index); + end; + + If (temp OR $80 = temp) then + begin + cmd := buf1[index]; + Inc(index); + info := buf1[index]; + Inc(index); + end; + + If (chan > songdata.nm_tracks) then songdata.nm_tracks := max(chan,18); + If (chan in [1..songdata.nm_tracks]) then + import_s3m_event(pat,row,chan,note,ins,vol,cmd,info); + end + else + begin + Inc(row); + Inc(index); + end; + until (row = 64); + end; + + fix_s3m_commands(header.patnum); + CloseF(f); + songdata_title := NameOnly(songdata_source); + load_flag := 12; +end; + +procedure fix_fmk_commands(patterns: Byte); + +var + chunk,chunk2, + chunk3: tCHUNK; + patt_break: Byte; + order,patt: Byte; + patts: String; + ins_cache, + misc_cache, + arpg_cache, + forcevol_cache, + volsld_cache, + xfvolsld_cache, + slide_cache: array[1..20] of Byte; + _1st_ins_load: array[1..20] of Boolean; + _speed_table_fixed: array[0..$7f] of Boolean; + prev_cache: array[1..20] of Record + effect_def, + effect, + effect_def2, + effect2: Byte; + end; + +procedure fix_single_pattern(patt: Byte); + +var + temp2,temp3: Byte; + +begin + FillChar(prev_cache,SizeOf(prev_cache),0); + patt_break := BYTE_NULL; + + If NOT _speed_table_fixed[patt] then + For temp2 := 0 to $3f do + begin + For temp3 := 1 to 20 do + begin + get_chunk(patt,temp2,temp3,chunk); + If (chunk.effect_def = 0) then + begin + chunk.effect_def := ef_SetCustomSpeedTab; + chunk.effect := $0fa; + put_chunk(patt,temp2,temp3,chunk); + _speed_table_fixed[patt] := TRUE; + end + else If (chunk.effect_def2 = 0) then + begin + chunk.effect_def2 := ef_SetCustomSpeedTab; + chunk.effect2 := $0fa; + put_chunk(patt,temp2,temp3,chunk); + _speed_table_fixed[patt] := TRUE; + end; + If _speed_table_fixed[patt] then BREAK; + end; + If _speed_table_fixed[patt] then BREAK; + end; + + For temp2 := 0 to $3f do + For temp3 := 1 to 20 do + begin + get_chunk(patt,temp2,temp3,chunk); + If (chunk.effect_def = temp_ef_rep) then + begin + chunk.effect_def := prev_cache[temp3].effect_def; + put_chunk(patt,temp2,temp3,chunk); + end; + + If (chunk.effect_def = temp_ef_XFVSlide) then + begin + chunk.effect_def := ef_Extended2; + If (xfvolsld_cache[temp3] <> 0) then + chunk.effect := ef_ex2_VolSlideUpXF*16+volsld_cache[temp3] DIV 16 + else chunk.effect := ef_ex2_VolSlideDnXF*16+volsld_cache[temp3] MOD 16; + put_chunk(patt,temp2,temp3,chunk); + end; + + If (chunk.effect_def in [ef_PositionJump,ef_PatternBreak]) then + patt_break := temp2; + + If (temp2 <= patt_break) and + (chunk.instr_def <> ins_cache[temp3]) and + (chunk.effect_def2 <> ef_ForceInsVolume) then + If (chunk.instr_def <> 0) then + forcevol_cache[temp3] := 0; + + If ((chunk.effect_def = ef_Extended) and + (chunk.effect = ef_ex_ExtendedCmd*16+ef_ex_cmd_ResetVol)) or + ((chunk.effect_def2 = ef_Extended) and + (chunk.effect2 = ef_ex_ExtendedCmd*16+ef_ex_cmd_ResetVol)) then + forcevol_cache[temp3] := 0; + + If (chunk.effect_def2 = ef_ForceInsVolume) and + (temp2 <= patt_break) then + forcevol_cache[temp3] := 1; + + If (chunk.instr_def <> 0) and (temp2 <= patt_break) then + ins_cache[temp3] := chunk.instr_def; + + If (chunk.instr_def <> 0) or ((chunk.instr_def = 0) and + (chunk.note in [1..12*8+1]) and + (ins_cache[temp3] <> 0)) then + put_chunk(patt,temp2,temp3,chunk); + + If (temp2 <= patt_break) then + begin + If (chunk.effect DIV 16 <> 0) then + misc_cache[temp3] := chunk.effect AND $0f0+ + misc_cache[temp3] AND $0f + else If (chunk.effect_def in [ef_Vibrato, + ef_Tremolo]) then + begin + chunk.effect := misc_cache[temp3] AND $0f0+ + chunk.effect AND $0f; + put_chunk(patt,temp2,temp3,chunk); + end; + + If (chunk.effect MOD 16 <> 0) then + misc_cache[temp3] := misc_cache[temp3] AND $0f0+ + chunk.effect AND $0f + else If (chunk.effect_def in [ef_Vibrato, + ef_Tremolo]) then + begin + chunk.effect := chunk.effect AND $0f0+ + misc_cache[temp3] AND $0f; + put_chunk(patt,temp2,temp3,chunk); + end; + + If (chunk.effect_def = ef_RetrigNote) then + If (chunk.effect <> 0) then misc_cache[temp3] := chunk.effect + else begin + chunk.effect := misc_cache[temp3]; + put_chunk(patt,temp2,temp3,chunk); + end; + + If (chunk.effect_def = temp_ef_Arpeggio) then + If (chunk.effect <> 0) then arpg_cache[temp3] := chunk.effect + else begin + chunk.effect := arpg_cache[temp3]; + put_chunk(patt,temp2,temp3,chunk); + end; + + If (chunk.effect_def in [ef_FSlideDown,ef_FSlideDownFine, + ef_FSlideUp,ef_FSlideUpFine, + ef_TonePortamento]) then + If (chunk.effect <> 0) then slide_cache[temp3] := chunk.effect + else begin + chunk.effect := slide_cache[temp3]; + put_chunk(patt,temp2,temp3,chunk); + end; + + If (chunk.effect_def = ef_Extended2) and + (chunk.effect DIV 16 in [ef_ex2_FreqSlideDnXF,ef_ex2_FreqSlideUpXF]) then + If (chunk.effect MOD 16 <> 0) then slide_cache[temp3] := chunk.effect MOD 16 + else begin + chunk.effect := chunk.effect AND $0f0+slide_cache[temp3] AND $0f; + put_chunk(patt,temp2,temp3,chunk); + end; + + If (chunk.effect_def in [ef_TPortamVolSlide,ef_VibratoVolSlide, + ef_VolSlide,ef_VolSlideFine]) and + (temp2 <= patt_break) then + begin + If (chunk.effect <> 0) then volsld_cache[temp3] := chunk.effect + else begin + chunk.effect := volsld_cache[temp3];; + put_chunk(patt,temp2,temp3,chunk); + end; + end; + + If (chunk.effect_def = ef_Extended2) and + (chunk.effect DIV 16 in [ef_ex2_VolSlideDnXF,ef_ex2_VolSlideUpXF]) then + If (chunk.effect MOD 16 <> 0) then + Case chunk.effect DIV 16 of + ef_ex2_VolSlideDnXF: + begin + volsld_cache[temp3] := chunk.effect MOD 16; + xfvolsld_cache[temp3] := 0; + end; + + ef_ex2_VolSlideUpXF: + begin + volsld_cache[temp3] := chunk.effect MOD 16*16; + xfvolsld_cache[temp3] := 1; + end; + end; + end; + + If (prev_cache[temp3].effect_def in [ef_Vibrato,ef_VibratoVolSlide]) and + NOT (chunk.effect_def in [ef_Vibrato,ef_VibratoVolSlide]) then + If (chunk.effect_def = 0) and (chunk.effect = 0) then + begin + chunk2 := chunk; + chunk2.effect_def := ef_Extended; + chunk2.effect := ef_ex_ExtendedCmd*16+ef_ex_cmd_VibrOff; + If NOT ((chunk2.effect_def = chunk2.effect_def2) and + (chunk2.effect = chunk2.effect2)) then + begin + put_chunk(patt,temp2,temp3,chunk2); + chunk := chunk2; + end; + end + else If (chunk.effect_def2 = 0) and (chunk.effect2 = 0) then + begin + chunk2 := chunk; + chunk2.effect_def2 := ef_Extended; + chunk2.effect2 := ef_ex_ExtendedCmd*16+ef_ex_cmd_VibrOff; + If NOT ((chunk2.effect_def2 = chunk2.effect_def) and + (chunk2.effect2 = chunk2.effect)) then + begin + put_chunk(patt,temp2,temp3,chunk2); + chunk := chunk2; + end; + end; + + If (_1st_ins_load[temp3] and (chunk.instr_def <> 0)) or + (forcevol_cache[temp3] <> 0) and + (temp2 <= patt_break) and + (chunk.instr_def <> 0) then + If (chunk.effect_def2+chunk.effect2 = 0) then + If NOT (chunk.effect_def in [ef_SetModulatorVol,ef_SetCarrierVol]) then + begin + chunk.effect_def2 := ef_Extended; + chunk.effect2 := ef_ex_ExtendedCmd*16+ef_ex_cmd_ResetVol; + put_chunk(patt,temp2,temp3,chunk); + forcevol_cache[temp3] := 0; + _1st_ins_load[temp3] := FALSE; + end + else begin + chunk.effect_def2 := chunk.effect_def; + chunk.effect2 := chunk.effect; + chunk.effect_def := ef_Extended; + chunk.effect := ef_ex_ExtendedCmd*16+ef_ex_cmd_ResetVol; + put_chunk(patt,temp2,temp3,chunk); + forcevol_cache[temp3] := 0; + _1st_ins_load[temp3] := FALSE; + end; + + prev_cache[temp3].effect_def := chunk.effect_def; + prev_cache[temp3].effect := chunk.effect; + prev_cache[temp3].effect_def2 := chunk.effect_def2; + prev_cache[temp3].effect2 := chunk.effect2; + + If is_4op_chan(temp3) and + (temp3 in [1,3,5,10,12,14]) then + begin + get_chunk(patt,temp2,SUCC(temp3),chunk3); + If (chunk.instr_def = 0) and (chunk3.instr_def <> 0) then + begin + If (ins_cache[temp3] <> 0) then + chunk.instr_def := ins_cache[temp3] + else chunk.instr_def := chunk3.instr_def; + put_chunk(patt,temp2,temp3,chunk); + end; + end; + + If (chunk.effect_def = temp_ef_Arpeggio) then + begin + chunk2 := chunk; + chunk2.effect_def := ef_Arpeggio; + put_chunk(patt,temp2,temp3,chunk2); + end; + + If (chunk.effect_def in [ef_SetModulatorVol,ef_SetCarrierVol]) and + (chunk.effect_def2 = ef_ForceInsVolume) then + begin + chunk2 := chunk; + chunk2.effect_def := chunk.effect_def2; + chunk2.effect := chunk.effect2; + chunk2.effect_def2 := chunk.effect_def; + chunk2.effect2 := chunk.effect; + put_chunk(patt,temp2,temp3,chunk2); + end; + end; +end; + +begin { fix_fmk_commands } + FillChar(ins_cache,SizeOf(ins_cache),0); + FillChar(_1st_ins_load,SizeOf(_1st_ins_load),TRUE); + FillChar(_speed_table_fixed,SizeOf(_speed_table_fixed),FALSE); + FillChar(xfvolsld_cache,SizeOf(volsld_cache),0); + FillChar(volsld_cache,SizeOf(volsld_cache),0); + FillChar(slide_cache,SizeOf(slide_cache),0); + FillChar(misc_cache,SizeOf(misc_cache),0); + FillChar(arpg_cache,SizeOf(arpg_cache),0); + FillChar(forcevol_cache,SizeOf(forcevol_cache),0); + + patts := ''; + order := 0; patt := BYTE_NULL; + + Repeat + If (songdata.pattern_order[order] >= $80) then Inc(order) + else + begin + patt := songdata.pattern_order[order]; + fix_single_pattern(patt); + Inc(order); + patts := patts+CHR(patt); + end; + until (patt >= patterns) or (order > $7f); + + For patt := 0 to PRED(patterns) do + If NOT (Pos(CHR(patt),patts) <> 0) then + fix_single_pattern(patt); +end; + +procedure import_fin_instrument(inst: Byte; var data); +begin + With songdata.instr_data[inst] do + begin + fm_data.AM_VIB_EG_modulator := tDUMMY_BUFF(data)[0]; + fm_data.AM_VIB_EG_carrier := tDUMMY_BUFF(data)[1]; + fm_data.KSL_VOLUM_modulator := tDUMMY_BUFF(data)[2]; + fm_data.KSL_VOLUM_carrier := tDUMMY_BUFF(data)[3]; + fm_data.ATTCK_DEC_modulator := tDUMMY_BUFF(data)[4]; + fm_data.ATTCK_DEC_carrier := tDUMMY_BUFF(data)[5]; + fm_data.SUSTN_REL_modulator := tDUMMY_BUFF(data)[6]; + fm_data.SUSTN_REL_carrier := tDUMMY_BUFF(data)[7]; + fm_data.WAVEFORM_modulator := tDUMMY_BUFF(data)[8] AND 7; + fm_data.WAVEFORM_carrier := tDUMMY_BUFF(data)[9] AND 7; + fm_data.FEEDBACK_FM := tDUMMY_BUFF(data)[10] AND $0f; + end; + + songdata.instr_data[inst].panning := 0; + songdata.instr_data[inst].fine_tune := 0; +end; + +procedure fmk_file_loader; + +type + tFMK_HEADER = Record + id: array[1..4] of Char; { FMK! } + songname: array[1..28] of Char; { Song name (28) } + composer: array[1..28] of Char; { Composer name (28) } + bytef4: Byte; { Value 244 (f4h), just for check. } + ftype: Byte; { File type {1=evolution 1, 2=evolution 2 } + glob_var: Byte; { Global variables, bits : 0 = stereo, 1 = opl3, 2 = rhythm } + { 3 = 4.8 db tremolo 4 = 14 cent vibrato. } + base_spd: Byte; { Song basespeed, ticks / second. this version : fixed 50. } + init_spd: Byte; { Song initial speed. } + reserved: array[0..8] of Byte; { Reserved } + ordnum: Byte; { Length of song (order). } + insnum: Byte; { Number of instruments. } + patnum: Byte; { Number of patterns. } + trk_pan: array[1..5] of Byte; { Track stereo pan positions, bits 0-1, 2-3, 4-5, 6-7. } + { value 0 = left 1 = both 2 = right, from track 1 to 18. } + trk_set: array[1..20] of Byte; { Track initial settings, 255=unused, bits : } + { 0-2, type value: 0 = normal 1=hihat 2=cymbal 3=tom tom 4=snare 5=bass } + { 6 = 4op 7=unused } + { 3-7, OPL-channel number (1-18), 21 = none. } +{ ### if ftype=2 --> trk_set: 1..18; type_value: 0 = normal 6 = 4op 7=unused } + end; +const + id = 'FMK!'; + +const + _conv_fmk_pan: array[0..2] of Byte = (1,0,2); + +type + tFIN_DATA = Record + dname: array[1..12] of Char; + iname: array[1..27] of Char; + idata: tFM_INST_DATA; + end; +var + f: File; + header: tFMK_HEADER; + order_list: array[0..254] of Byte; + paraptr_ins: array[1..99] of Word; + paraptr_pat: array[0..63] of Longint; + paraptr_msg: Word; + insdata: tFIN_DATA; + temp,temp2,fpos_bak: Longint; + pat,row,chan, + desc_rows: Byte; + note,ins,vol,cmd,info: Byte; + patlen,index: Word; + dscbuf: array[0..PRED(20*24)] of Char; + + +procedure import_fmk_event(pattern,line,channel,note,ins,vol,cmd,info: Byte); + +var + chunk: tCHUNK; + +begin + FillChar(chunk,SizeOf(chunk),0); + If (ins in [1..99]) then chunk.instr_def := ins; + + Case note of + 254: chunk.note := BYTE_NULL; + 255: chunk.note := 0; + else If (note AND $0f in [1..12]) then + chunk.note := 12*(note SHR 4)+(note AND $0f) + end; + + If (vol <> BYTE_NULL) then + begin + chunk.effect_def2 := ef_ForceInsVolume; + chunk.effect2 := 63-max(vol,63) + end; + + Case CHR(cmd+ORD('A')-1) of + { SET SPEED } + 'A': If (info <> 0) then + begin + chunk.effect_def := ef_SetSpeed; + chunk.effect := info; + end; + + { JUMP TO ORDER } + 'B': If (info <= 254) then + begin + chunk.effect_def := ef_PositionJump; + chunk.effect := info; + end; + + { CARRIER PARAM } + 'C': Case info DIV 16 of + 1: begin + chunk.effect_def := ef_Extended3; + chunk.effect := ef_ex3_SetMultipC*16+info MOD 16; + end; + + 2: begin + chunk.effect_def := ef_Extended3; + chunk.effect := ef_ex3_SetKslC*16+(info MOD 16) AND 3; + end; + + 3: begin + chunk.effect_def := ef_Extended; + chunk.effect := ef_ex_SetAttckRateC*16+info MOD 16; + end; + + 4: begin + chunk.effect_def := ef_Extended; + chunk.effect := ef_ex_SetDecayRateC*16+info MOD 16; + end; + + 5: begin + chunk.effect_def := ef_Extended; + chunk.effect := ef_ex_SetSustnLevelC*16+info MOD 16; + end; + + 6: begin + chunk.effect_def := ef_Extended; + chunk.effect := ef_ex_SetRelRateC*16+info MOD 16; + end; + + 7: begin + chunk.effect_def := ef_SetWaveform; + chunk.effect := info AND 7 SHL 4+$0f; + end; + + 8: begin + chunk.effect_def := ef_Extended; + chunk.effect := ef_ex_SetFeedback*16+info AND 7; + end; + end; + + { VOLUME SLIDE } + 'D': { VOLUME SLIDE DOWN } + Case info DIV 16 of + { NORMAL } + 0: If (info MOD 16 = 0) then chunk.effect_def := temp_ef_XFVSlide + else begin + chunk.effect_def := ef_Extended2; + chunk.effect := ef_ex2_VolSlideDnXF*16+info MOD 16 + end; + { FINE } + 15: begin + chunk.effect_def := ef_VolSlideFine; + chunk.effect := info MOD 16; + end; + else + { VOLUME SLIDE UP } + Case info MOD 16 of + { NORMAL } + 0: If (info DIV 16 = 0) then chunk.effect_def := temp_ef_XFVSlide + else begin + chunk.effect_def := ef_Extended2; + chunk.effect := ef_ex2_VolSlideUpXF*16+info DIV 16; + end; + { FINE } + 15: begin + chunk.effect_def := ef_VolSlideFine; + chunk.effect := info AND $0f0; + end; + end; + end; + + { SLIDE DOWN } + 'E': Case info DIV 16 of + { NORMAL } + 0..14: begin + chunk.effect_def := ef_FSlideDown; + chunk.effect := info; + end; + + { FINE } + 15: begin + chunk.effect_def := ef_FSlideDownFine; + chunk.effect := info AND $0f; + end; + end; + + { SLIDE UP } + 'F': Case info DIV 16 of + { NORMAL } + 0..14: begin + chunk.effect_def := ef_FSlideUp; + chunk.effect := info; + end; + + { FINE } + 15: begin + chunk.effect_def := ef_FSlideUpFine; + chunk.effect := info AND $0f; + end; + end; + + { TONE PORTAMENTO } + 'G': begin + chunk.effect_def := ef_TonePortamento; + chunk.effect := info; + end; + + { VIBRATO } + 'H': begin + chunk.effect_def := ef_Vibrato; + If (info <> 0) and (info DIV 16 = 0) then + chunk.effect := $10+info AND $0f + else If (info <> 0) and (info MOD 16 = 0) then + chunk.effect := info AND $0f0+1 + else chunk.effect := info; + end; + + { RETRIG NOTE } + 'I': begin + chunk.effect_def := ef_RetrigNote; + If (info <> 0) then chunk.effect := max(info*2,255); + end; + + { ARPEGGIO } + 'J': begin + chunk.effect_def := temp_ef_Arpeggio; + chunk.effect := info; + end; + + { MODLATOR PARAM } + 'M': Case info DIV 16 of + 1: begin + chunk.effect_def := ef_Extended3; + chunk.effect := ef_ex3_SetMultipM*16+info MOD 16; + end; + + 2: begin + chunk.effect_def := ef_Extended3; + chunk.effect := ef_ex3_SetKslM*16+(info MOD 16) AND 3; + end; + + 3: begin + chunk.effect_def := ef_Extended; + chunk.effect := ef_ex_SetAttckRateM*16+info MOD 16; + end; + + 4: begin + chunk.effect_def := ef_Extended; + chunk.effect := ef_ex_SetDecayRateM*16+info MOD 16; + end; + + 5: begin + chunk.effect_def := ef_Extended; + chunk.effect := ef_ex_SetSustnLevelM*16+info MOD 16; + end; + + 6: begin + chunk.effect_def := ef_Extended; + chunk.effect := ef_ex_SetRelRateM*16+info MOD 16; + end; + + 7: begin + chunk.effect_def := ef_SetWaveform; + chunk.effect := $0f0+info AND 7; + end; + + 8: begin + chunk.effect_def := ef_Extended; + chunk.effect := ef_ex_SetFeedback*16+info AND 7; + end; + end; + + { SET VIBRATO/TREMOLO WAVEFORM } + 'N': ; + + { BREAK PATTERN } + 'P': If (info < 64) then + begin + chunk.effect_def := ef_PatternBreak; + chunk.effect := Str2num(Num2str(info,16),10); + end; + + { TREMOLO } + 'R': begin + chunk.effect_def := ef_Tremolo; + If (info <> 0) and (info DIV 16 = 0) then + chunk.effect := $10+info AND $0f + else If (info <> 0) and (info MOD 16 = 0) then + chunk.effect := info AND $0f0+1 + else chunk.effect := info; + end; + + { STEREO CONTROL } + 'S': If (header.glob_var AND 1 = 1) then + begin + chunk.effect_def := ef_Extended; + Case info of + 1: chunk.effect := ef_ex_SetPanningPos*16+1; + 2: chunk.effect := ef_ex_SetPanningPos*16+0; + 3: chunk.effect := ef_ex_SetPanningPos*16+2; + end; + end; + + { MODULATOR VOLUME } + 'T': begin + chunk.effect_def := ef_SetModulatorVol; + chunk.effect := info AND $3f; + end; + + { CARRIER VOLUME } + 'U': begin + chunk.effect_def := ef_SetCarrierVol; + chunk.effect := info AND $3f; + end; + end; + + If (chunk.effect_def = 0) and (chunk.effect <> 0) then + chunk.effect := 0; + put_chunk(pattern,line,channel,chunk); +end; + +begin + {$i-} + Assign(f,songdata_source); + ResetF(f); + {$i+} + If (IOresult <> 0) then + begin + CloseF(f); + EXIT; + end; + + BlockReadF(f,header,SizeOf(header),temp); + If NOT ((temp = SizeOf(header)) and (header.id = id)) then + begin + CloseF(f); + EXIT; + end; + + load_flag := $7f; + If (header.bytef4 <> $f4) or NOT (header.ftype in [1,2]) then + begin + CloseF(f); + EXIT; + end; + + If (header.ftype = 2) then + begin + SeekF(f,SizeOf(header)-2); + If (IOresult <> 0) then + begin + CloseF(f); + EXIT; + end; + end; + + If (header.ordnum <> 0) then + begin + BlockReadF(f,order_list,header.ordnum,temp); + If (IOresult <> 0) or (temp <> header.ordnum) then + begin + CloseF(f); + EXIT; + end; + end; + + BlockReadF(f,paraptr_msg,SizeOf(paraptr_msg),temp); + If (IOresult <> 0) or (temp <> SizeOf(paraptr_msg)) then + begin + CloseF(f); + EXIT; + end; + + fpos_bak := FilePos(f); + If (paraptr_msg <> 0) then + begin + SeekF(f,paraptr_msg); + If (IOresult <> 0) then + begin + CloseF(f); + EXIT; + end; + + BlockReadF(f,desc_rows,SizeOf(desc_rows),temp); + If (IOresult <> 0) or (temp <> SizeOf(desc_rows)) then + begin + CloseF(f); + EXIT; + end; + + If (desc_rows <> 0) then + begin + BlockReadF(f,dscbuf,desc_rows*20,temp); + If (IOresult <> 0) or (temp <> desc_rows*20) then + begin + CloseF(f); + EXIT; + end; + end; + + end; + + SeekF(f,fpos_bak); + If (IOresult <> 0) then + begin + CloseF(f); + EXIT; + end; + + If (header.insnum <> 0) then + begin + BlockReadF(f,paraptr_ins,header.insnum*2,temp); + If (IOresult <> 0) or (temp <> header.insnum*2) then + begin + CloseF(f); + EXIT; + end; + end; + + If (header.patnum <> 0) then + begin + BlockReadF(f,paraptr_pat,header.patnum*4,temp); + If (IOresult <> 0) or (temp <> header.patnum*4) then + begin + CloseF(f); + EXIT; + end; + end; + + init_songdata; + load_flag := 0; + + If (header.init_spd <> 0) then speed := header.init_spd + else speed := 1; + + If (header.base_spd <> 0) then tempo := header.base_spd + else tempo := 50; + + songdata.tempo := tempo; + songdata.speed := speed; + songdata.songname := truncate_string(header.songname); + songdata.composer := truncate_string(header.composer); + songdata.common_flag := songdata.common_flag OR 1; + songdata.common_flag := songdata.common_flag OR 2; + songdata.common_flag := songdata.common_flag OR $80; + + For temp := 18 downto 1 do + If NOT (header.trk_set[temp] AND 7 = 7) then BREAK; + + songdata.patt_len := 64; + If adjust_tracks then songdata.nm_tracks := temp + else If (songdata.nm_tracks < 18) then songdata.nm_tracks := 18; + + For temp2 := 1 to temp do + If (header.trk_set[temp2] AND 7 = 6) then + Case temp2 of + 1,2: songdata.flag_4op := songdata.flag_4op OR 1; + 3,4: songdata.flag_4op := songdata.flag_4op OR 2; + 5,6: songdata.flag_4op := songdata.flag_4op OR 4; + 10,11: songdata.flag_4op := songdata.flag_4op OR 8; + 12,13: songdata.flag_4op := songdata.flag_4op OR $10; + 14,15: songdata.flag_4op := songdata.flag_4op OR $20; + end; + + If (header.glob_var AND 1 = 1) then + songdata.common_flag := songdata.common_flag OR $20; + + If (header.glob_var SHR 3 AND 1 = 1) then + songdata.common_flag := songdata.common_flag OR 8; + + If (header.glob_var SHR 4 AND 1 = 1) then + songdata.common_flag := songdata.common_flag OR $10; + + import_old_flags; + If (header.glob_var AND 1 = 1) then + begin + Inc(songdata.lock_flags[1], _conv_fmk_pan[header.trk_pan[1] AND 3]); + Inc(songdata.lock_flags[2], _conv_fmk_pan[header.trk_pan[1] SHR 2 AND 3]); + Inc(songdata.lock_flags[3], _conv_fmk_pan[header.trk_pan[1] SHR 4 AND 3]); + Inc(songdata.lock_flags[4], _conv_fmk_pan[header.trk_pan[1] SHR 6 AND 3]); + Inc(songdata.lock_flags[5], _conv_fmk_pan[header.trk_pan[2] AND 3]); + Inc(songdata.lock_flags[6], _conv_fmk_pan[header.trk_pan[2] SHR 2 AND 3]); + Inc(songdata.lock_flags[7], _conv_fmk_pan[header.trk_pan[2] SHR 4 AND 3]); + Inc(songdata.lock_flags[8], _conv_fmk_pan[header.trk_pan[2] SHR 6 AND 3]); + Inc(songdata.lock_flags[9], _conv_fmk_pan[header.trk_pan[3] AND 3]); + Inc(songdata.lock_flags[10],_conv_fmk_pan[header.trk_pan[3] SHR 2 AND 3]); + Inc(songdata.lock_flags[11],_conv_fmk_pan[header.trk_pan[3] SHR 4 AND 3]); + Inc(songdata.lock_flags[12],_conv_fmk_pan[header.trk_pan[3] SHR 6 AND 3]); + Inc(songdata.lock_flags[13],_conv_fmk_pan[header.trk_pan[4] AND 3]); + Inc(songdata.lock_flags[14],_conv_fmk_pan[header.trk_pan[4] SHR 2 AND 3]); + Inc(songdata.lock_flags[15],_conv_fmk_pan[header.trk_pan[4] SHR 4 AND 3]); + Inc(songdata.lock_flags[16],_conv_fmk_pan[header.trk_pan[4] SHR 6 AND 3]); + Inc(songdata.lock_flags[17],_conv_fmk_pan[header.trk_pan[5] AND 3]); + Inc(songdata.lock_flags[18],_conv_fmk_pan[header.trk_pan[5] SHR 2 AND 3]); + end; + + For temp := 1 to max(header.ordnum,128) do + Case order_list[temp-1] of + 255: songdata.pattern_order[temp-1] := $80; + else songdata.pattern_order[temp-1] := order_list[temp-1]; + end; + + For temp := 1 to header.insnum do + begin + SeekF(f,paraptr_ins[temp]); + If (IOresult <> 0) then + begin + CloseF(f); + EXIT; + end; + + BlockReadF(f,insdata,SizeOf(insdata),temp2); + If (IOresult <> 0) or (temp2 <> SizeOf(insdata)) then + begin + CloseF(f); + EXIT; + end; + + If (truncate_string(insdata.iname) <> '') then + songdata.instr_names[temp] := + Copy(songdata.instr_names[temp],1,9)+ + Copy(truncate_string(insdata.iname),1,32) + else + songdata.instr_names[temp] := + Copy(songdata.instr_names[temp],1,9)+ + truncate_string(insdata.dname); + + import_fin_instrument(temp,insdata.idata); + end; + + For pat := 0 to PRED(header.patnum) do + begin + SeekF(f,paraptr_pat[pat]); + If (IOresult <> 0) then + begin + CloseF(f); + EXIT; + end; + + If (paraptr_pat[pat] = 0) then CONTINUE; + BlockReadF(f,patlen,SizeOf(patlen),temp2); + If (temp2 <> SizeOf(patlen)) then + begin + CloseF(f); + EXIT; + end; + + If (patlen = 0) then CONTINUE; + FillChar(buf1,SizeOf(buf1),0); + BlockReadF(f,buf1,patlen,temp2); + + index := 0; + row := 0; + + Repeat + If (buf1[index] <> 0) then + begin + note := BYTE_NULL; + ins := 0; + vol := BYTE_NULL; + cmd := 0; + info := 0; + temp := buf1[index]; + Inc(index); + + chan := SUCC(temp AND 31); + If (temp OR $20 = temp) then + begin + note := buf1[index]; + Inc(index); + ins := buf1[index]; + Inc(index); + end; + + If (temp OR $40 = temp) then + begin + vol := buf1[index]; + Inc(index); + end; + + If (temp OR $80 = temp) then + begin + cmd := buf1[index]; + Inc(index); + info := buf1[index]; + Inc(index); + end; + + If (PRED(chan) in [1..18]) then + import_fmk_event(pat,row,PRED(chan),note,ins,vol,cmd,info); + end + else + begin + Inc(row); + Inc(index); + end; + until (row = 64); + end; + + fix_fmk_commands(header.patnum); + CloseF(f); + songdata_title := NameOnly(songdata_source); + load_flag := 13; +end; + +procedure import_sat_instrument(inst: Byte; var data); +begin + With songdata.instr_data[inst] do + begin + fm_data.FEEDBACK_FM := tDUMMY_BUFF(data)[0] AND $0f; + fm_data.AM_VIB_EG_modulator := tDUMMY_BUFF(data)[1]; + fm_data.AM_VIB_EG_carrier := tDUMMY_BUFF(data)[2]; + fm_data.ATTCK_DEC_modulator := tDUMMY_BUFF(data)[3]; + fm_data.ATTCK_DEC_carrier := tDUMMY_BUFF(data)[4]; + fm_data.SUSTN_REL_modulator := tDUMMY_BUFF(data)[5]; + fm_data.SUSTN_REL_carrier := tDUMMY_BUFF(data)[6]; + fm_data.WAVEFORM_modulator := tDUMMY_BUFF(data)[7] AND 3; + fm_data.WAVEFORM_carrier := tDUMMY_BUFF(data)[8] AND 3; + fm_data.KSL_VOLUM_modulator := tDUMMY_BUFF(data)[9]; + fm_data.KSL_VOLUM_carrier := tDUMMY_BUFF(data)[10]; + end; + + songdata.instr_data[inst].panning := 0; + songdata.instr_data[inst].fine_tune := 0; +end; + +function import_sat_instrument_name(var data; inst: Byte): String; + +var + temp1: Word; + temp2: Byte; + temp3: String; + +begin + temp1 := 0; + temp2 := 0; + temp3 := ''; + + While (temp1 < 496) do + begin + If (tDUMMY_BUFF(data)[temp1] = BYTE('')) then Inc(temp2); + Inc(temp1); + If (temp2 = inst+1) then + begin + While (tDUMMY_BUFF(data)[temp1] in [$20..$0ff]) and + (Length(temp3) < 22) do + begin + temp3 := temp3+CHR(tDUMMY_BUFF(data)[temp1]); + Inc(temp1); + end; + BREAK; + end; + end; + + import_sat_instrument_name := temp3; +end; + +procedure import_sa2_effect(effect,def1,def2: Byte; + var out1,out2: Byte); forward; +procedure sat_file_loader; + +type + tHEADER = Record { version 1 } + ident: array[1..4] of Char; { ident_string } + vernm: Byte; { version_number (1) } + instt: array[0..$1e] of { 31_instruments } + array[0..$0a] of Byte; + instn: array[0..495] of Byte; { 31_instrument_names } + order: array[0..254] of Byte; { pattern_order } + nopat: Word; { number of patterns } + snlen: Byte; { song_length } + rspos: Byte; { restart_position } + calls: Word; { calls_per_second } + end; +type + tHEADR2 = Record { version 6 } + ident: array[1..4] of Char; { ident_string } + vernm: Byte; { version_number (1) } + instt: array[0..$1e] of { 31_instruments } + array[0..$0e] of Byte; + instn: array[0..495] of Byte; { 31_instrument_names } + order: array[0..$7f] of Byte; { pattern_order } + nopat: Word; { number of patterns } + snlen: Byte; { song_length } + rspos: Byte; { restart_position } + calls: Word; { calls_per_second } + arpgd: array[1..512] of Byte; { arpeggio_data } + end; +const + id = 'SAdT'; + +var + f: File; + header: tHEADER; + headr2: tHEADR2; + SATver: Byte; + temp,tmp2,tmp3,temp2,temp3, + temp4,temp5: Longint; + byte1,byte2,byte3,byte4,byte5,note_inc: Byte; + +procedure import_sat_event(pattern,line,channel, + byte1,byte2,byte3,byte4,byte5: Byte); +var + chunk: tCHUNK; + +begin + FillChar(chunk,SizeOf(chunk),0); + If (byte2 in [1..31]) then chunk.instr_def := byte2; + If (byte1 in [1..12*8+1]) then chunk.note := byte1+note_inc; + + import_sa2_effect(byte3,byte4,byte5,chunk.effect_def,chunk.effect); + If (chunk.effect_def = ef_Extended) and + (chunk.effect = ef_ex_ExtendedCmd*16) and (chunk.note = 0) then + begin + chunk.note := BYTE_NULL; + chunk.effect_def := 0; + chunk.effect := 0; + end; + + put_chunk(pattern,line,channel,chunk); +end; + +var + absolute: Longint; + +function get_byte(var pos: Longint): Byte; +begin + If (pos = SizeOf(buf1)-5) then + begin + If NOT (absolute > SizeOf(buf1)-5) then Move(buf3,buf1,SizeOf(buf3)-5) + else Move(buf4,buf1,SizeOf(buf4)-5); + pos := 0; + end; + get_byte := buf1[pos]; + Inc(pos); + Inc(absolute); +end; + +begin + {$i-} + Assign(f,songdata_source); + ResetF(f); + {$i+} + If (IOresult <> 0) then + begin + CloseF(f); + EXIT; + end; + + BlockReadF(f,header,SizeOf(header),temp); + If NOT ((temp = SizeOf(header)) and (header.ident = id)) then + begin + CloseF(f); + EXIT; + end; + + If NOT (header.vernm in [1,5,6]) then + begin + CloseF(f); + EXIT; + end; + + load_flag := $7f; + SATver := header.vernm; + If (SATver in [5,6]) then + begin + SeekF(f,0); + If (IOresult <> 0) then + begin + CloseF(f); + EXIT; + end; + + BlockReadF(f,headr2,SizeOf(headr2),temp); + If (temp <> SizeOf(headr2)) then + begin + CloseF(f); + EXIT; + end; + end; + + temp5 := (FileSize(f)-temp) DIV (64*9*5); + FillChar(buf1,SizeOf(buf1),0); + BlockReadF(f,buf1,SizeOf(buf1)-5,temp); + If (IOresult <> 0) then + begin + CloseF(f); + EXIT; + end; + + tmp2 := WORD_NULL; + If (temp = SizeOf(buf1)-5) then + begin + FillChar(buf3,SizeOf(buf3),0); + BlockReadF(f,buf3,SizeOf(buf3)-5,tmp2); + If (IOresult <> 0) then + begin + CloseF(f); + EXIT; + end; + end; + + tmp3 := WORD_NULL; + If (tmp2 = SizeOf(buf3)-5) then + begin + FillChar(buf4,SizeOf(buf4),0); + BlockReadF(f,buf4,SizeOf(buf4)-5,tmp3); + If (IOresult <> 0) then + begin + CloseF(f); + EXIT; + end; + end; + + init_songdata; + load_flag := 0; + + songdata.common_flag := songdata.common_flag OR 8; + songdata.common_flag := songdata.common_flag OR $10; + import_old_flags; + + songdata.patt_len := 64; + If adjust_tracks then songdata.nm_tracks := 9 + else If (songdata.nm_tracks < 9) then songdata.nm_tracks := 9; + + For temp := 1 to 20 do + songdata.lock_flags[temp] := songdata.lock_flags[temp] OR 4 OR 8; + + If (SATver = 1) then + begin + speed := 6; + If (header.calls < 255) then tempo := header.calls + else tempo := 255; + + songdata.tempo := tempo; + songdata.speed := speed; + + For temp := 0 to max(header.snlen-1,127) do + If (temp < 128) and (header.order[temp] in [0..63]) then + songdata.pattern_order[temp] := header.order[temp]; + If (header.rspos < 128) and (SUCC(temp) < 128) then + songdata.pattern_order[SUCC(temp)] := $80+header.rspos; + + temp5 := max(temp5,header.nopat); + For temp := 0 to $1e do + begin + import_sat_instrument(temp+1,header.instt[temp]); + songdata.instr_names[temp+1] := + Copy(songdata.instr_names[temp+1],1,9)+ + truncate_string(import_sat_instrument_name(header.instn,temp)); + end; + end + else + begin + speed := 6; + If (headr2.calls < 255) then tempo := headr2.calls + else tempo := 255; + + songdata.tempo := tempo; + songdata.speed := speed; + + For temp := 0 to headr2.snlen-1 do + If (temp < 128) and (headr2.order[temp] in [0..63]) then + songdata.pattern_order[temp] := headr2.order[temp]; + If (headr2.rspos < 128) and (SUCC(temp) < 128) then + songdata.pattern_order[SUCC(temp)] := $80+headr2.rspos; + + temp5 := max(temp5,headr2.nopat); + For temp := 0 to $1e do + begin + import_sat_instrument(temp+1,headr2.instt[temp]); + songdata.instr_names[temp+1] := + Copy(songdata.instr_names[temp+1],1,9)+ + truncate_string(import_sat_instrument_name(headr2.instn,temp)); + end; + end; + + temp := 0; + absolute := 0; + + Case SATver of + 1: note_inc := 24; + 5: note_inc := 12; + 6: note_inc := 0; + end; + + For temp2 := 0 to temp5-1 do + For temp3 := 0 to 63 do + For temp4 := 1 to 9 do + begin + byte1 := get_byte(temp); + byte2 := get_byte(temp); + byte3 := get_byte(temp); + byte4 := get_byte(temp); + byte5 := get_byte(temp); + import_sat_event(temp2,temp3,temp4,byte1,byte2,byte3,byte4,byte5); + end; + + CloseF(f); + songdata_title := NameOnly(songdata_source); + load_flag := 14; +end; + +function _sal(op1,op2: Word): Byte; + +var + result: Byte; + +begin + asm + mov ax,op1 + mov cx,op2 + sal ax,cl + mov result,al + end; + _sal := result; +end; + +function _sar(op1,op2: Word): Byte; + +var + result: Byte; + +begin + asm + mov ax,op1 + mov cx,op2 + sar ax,cl + mov result,al + end; + _sar := result; +end; + +procedure import_sa2_effect(effect,def1,def2: Byte; + var out1,out2: Byte); +begin + Case effect of + { NORMAL PLAY OR ARPEGGIO } + $00: begin + out1 := ef_Arpeggio; + out2 := def1*16+def2; + end; + + { SLIDE UP } + $01: begin + out1 := ef_FSlideUp; + out2 := def1*16+def2; + end; + + { SLIDE DOWN } + $02: begin + out1 := ef_FSlideDown; + out2 := def1*16+def2; + end; + + { TONE PORTAMENTO } + $03: begin + out1 := ef_TonePortamento; + out2 := def1*16+def2; + end; + + { VIBRATO } + $04: begin + out1 := ef_Vibrato; + out2 := def1*16+def2; + end; + + { TONE PORTAMENTO + VOLUME SLIDE } + $05: If (def1+def2 <> 0) then + If (def1 in [1..15]) then + begin + out1 := ef_TPortamVolSlide; + out2 := min(_sar(def1,2),1)*16; + end + else begin + out1 := ef_TPortamVolSlide; + out2 := min(_sar(def2,2),1); + end + else + begin + out1 := ef_TPortamVolSlide; + out2 := def1*16+def2; + end; + + { VIBRATO + VOLUME SLIDE } + $06: If (def1+def2 <> 0) then + If (def1 in [1..15]) then + begin + out1 := ef_VibratoVolSlide; + out2 := min(_sar(def1,2),1)*16; + end + else begin + out1 := ef_VibratoVolSlide; + out2 := min(_sar(def2,2),1); + end + else + begin + out1 := ef_VibratoVolSlide; + out2 := def1*16+def2; + end; + + { RELEASE SUSTAINING SOUND } + $08: begin + out1 := ef_Extended; + out2 := ef_ex_ExtendedCmd*16+0; + end; + + { VOLUME SLIDE } + $0a: If (def1+def2 <> 0) then + If (def1 in [1..15]) then + begin + out1 := ef_VolSlide; + out2 := min(_sar(def1,2),1)*16; + end + else begin + out1 := ef_VolSlide; + out2 := min(_sar(def2,2),1); + end + else + begin + out1 := ef_VolSlide; + out2 := def1*16+def2; + end; + + { POSITION JUMP } + $0b: If (def1*16+def2 < 128) then + begin + out1 := ef_PositionJump; + out2 := def1*16+def2; + end; + + { SET VOLUME } + $0c: begin + out1 := ef_SetInsVolume; + out2 := def1*16+def2; + If (out2 > 63) then out2 := 63; + end; + + { PATTERN BREAK } + $0d: If (def1*16+def2 < 64) then + begin + out1 := ef_PatternBreak; + out2 := def1*16+def2; + end; + + { SET SPEED } + $0f: If (def1*16+def2 < $20) then + begin + out1 := ef_SetSpeed; + out2 := def1*16+def2; + end + else If (def1 < 16) and (def2 < 16) then + begin + out1 := ef_SetTempo; + out2 := Round((def1*16+def2)/2.5); + end; + else begin + out1 := 0; + out2 := 0; + end; + end; +end; + +procedure sa2_file_loader; + +type + tHEADER = Record + ident: array[1..4] of Char; { These bytes mark a song } + vernm: Byte; { Version number (9) } + instt: array[0..$1e] of { 31 instruments } + array[0..$0e] of Byte; + instn: array[0..495] of Byte; { 31_instrument_names } + order: array[0..$7f] of Byte; { Pattern order } + nopat: Word; { Number of patterns } + snlen: Byte; { Length of song } + rspos: Byte; { Restart position } + snbpm: Word; { BPM } + arpgd: array[1..512] of Byte; { Arpeggio data (list+commands) } + ordr2: array[0..63] of { Track order } + array[1..9] of Byte; + chans: Word; { Active channels } + end; +const + id = 'SAdT'; + +var + f: File; + header: tHEADER; + temp,temp2,temp3,temp4,temp5: Longint; + +procedure import_sa2_event(pattern,line,channel, + byte1,byte2,byte3: Byte); +var + chunk: tCHUNK; + temp: Byte; + +begin + FillChar(chunk,SizeOf(chunk),0); + temp := (byte1 AND 1) SHL 4 +(byte2 SHR 4); + If (temp in [1..31]) then chunk.instr_def := temp; + If (byte1 SHR 1 in [1..12*8+1]) then chunk.note := (byte1 SHR 1); + + import_sa2_effect(byte2 AND $0f,byte3 SHR 4,byte3 AND $0f, + chunk.effect_def,chunk.effect); + If (chunk.effect_def = ef_Extended) and + (chunk.effect = ef_ex_ExtendedCmd*16) and (chunk.note = 0) then + begin + chunk.note := BYTE_NULL; + chunk.effect_def := 0; + chunk.effect := 0; + end; + + put_chunk(pattern,line,channel,chunk); +end; + +begin { sa2_file_loader } + {$i-} + Assign(f,songdata_source); + ResetF(f); + {$i+} + If (IOresult <> 0) then + begin + CloseF(f); + EXIT; + end; + + BlockReadF(f,header,SizeOf(header),temp); + If NOT ((temp = SizeOf(header)) and (header.ident = id)) then + begin + CloseF(f); + EXIT; + end; + + If NOT (header.vernm in [8,9]) then + begin + CloseF(f); + EXIT; + end; + + load_flag := $7f; + If (header.vernm = 8) then + begin + SeekF(f,FilePos(f)-2); + If (IOresult <> 0) then + begin + CloseF(f); + EXIT; + end; + end; + + FillChar(buf1,SizeOf(buf1),0); + BlockReadF(f,buf1,SizeOf(buf1)-3,temp); + If (IOresult <> 0) then + begin + CloseF(f); + EXIT; + end; + + init_songdata; + load_flag := 0; + + songdata.common_flag := songdata.common_flag OR 8; + songdata.common_flag := songdata.common_flag OR $10; + import_old_flags; + + songdata.patt_len := 64; + If adjust_tracks then songdata.nm_tracks := 9 + else If (songdata.nm_tracks < 9) then songdata.nm_tracks := 9; + + For temp := 1 to 20 do + songdata.lock_flags[temp] := songdata.lock_flags[temp] OR 4 OR 8; + + speed := 6; + If (Round(header.snbpm/2.5) < 255) then tempo := Round(header.snbpm/2.5) + else tempo := 255; + + songdata.tempo := tempo; + songdata.speed := speed; + + temp2 := 0; + temp3 := 0; + temp4 := 1; + + Repeat + While (header.ordr2[temp2][temp4] = 0) and + (temp2 <= header.nopat-1) do + begin + Inc(temp4); + If (temp4 > 9) then begin temp4 := 1; Inc(temp2); end; + end; + + If (temp2 <= header.nopat-1) then + begin + temp5 := 64*3*(header.ordr2[temp2][temp4]-1)+temp3*3; + import_sa2_event(temp2,temp3,temp4,buf1[temp5], + buf1[temp5+1], + buf1[temp5+2]); + Inc(temp3); + If (temp3 > $3f) then + begin + temp3 := 0; + If (temp4 < 9) then Inc(temp4) + else begin temp4 := 1; Inc(temp2); end; + end; + end; + until (temp2 > header.nopat-1); + + For temp := 0 to header.snlen-1 do + If (temp < 128) and (header.order[temp] in [0..63]) then + songdata.pattern_order[temp] := header.order[temp]; + If (header.rspos < 128) and (SUCC(temp) < 128) then + songdata.pattern_order[SUCC(temp)] := $80+header.rspos; + + For temp := 0 to $1e do + begin + import_sat_instrument(temp+1,header.instt[temp]); + songdata.instr_names[temp+1] := Copy(songdata.instr_names[temp+1],1,9)+ + truncate_string(import_sat_instrument_name(header.instn,temp)); + end; + + CloseF(f); + songdata_title := NameOnly(songdata_source); + load_flag := 15; +end; diff --git a/16/ADT2PLAY/MAKE.BAT b/16/ADT2PLAY/MAKE.BAT new file mode 100644 index 00000000..b8903772 --- /dev/null +++ b/16/ADT2PLAY/MAKE.BAT @@ -0,0 +1,4 @@ +@echo off +del adt2play.exe >nul +echo Compiling ADT2PLAY... +tmtpc -$MAP+ -$W- adt2play >!log diff --git a/16/ADT2PLAY/STRINGIO.PAS b/16/ADT2PLAY/STRINGIO.PAS new file mode 100644 index 00000000..6a377d61 --- /dev/null +++ b/16/ADT2PLAY/STRINGIO.PAS @@ -0,0 +1,825 @@ +unit StringIO; +interface + +type + characters = Set of Char; + +function Capitalize(str: String): String; +function Upper(str: String): String; +function Lower(str: String): String; +function iCASE(str: String): String; +function RotStrL(str1,str2: String; shift: Byte): String; +function RotStrR(str1,str2: String; shift: Byte): String; +function ExpStrL(str: String; size: Byte; chr: Char): String; +function ExpStrR(str: String; size: Byte; chr: Char): String; +function DietStr(str: String; size: Byte): String; +function CutStr(str: String): String; +function FlipStr(str: String): String; +function FilterStr(str: String; chr0,chr1: Char): String; +function FilterStr2(str: String; chr0: characters; chr1: Char): String; +function Num2str(num: Longint; base: Byte): String; +function Str2num(str: String; base: Byte): Longint; + +type + tINPUT_STR_SETTING = Record + insert_mode, + replace_enabled, + append_enabled: Boolean; + character_set, + valid_chars, + word_characters: characters; + terminate_keys: array[1..50] of Word + end; +type + tINPUT_STR_ENVIRONMENT = Record + keystroke: Word; + locate_pos: Byte; + end; +const + is_setting: tINPUT_STR_SETTING = + (insert_mode: TRUE; + replace_enabled: TRUE; + append_enabled: TRUE; + character_set: [#$20..#$0ff]; + valid_chars: [#$20..#$0ff]; + word_characters: ['A'..'Z','a'..'z','0'..'9','_']; + terminate_keys: ($011b,$1c0d,$0000,$0000,$0000, + $0000,$0000,$0000,$0000,$0000, + $0000,$0000,$0000,$0000,$0000, + $0000,$0000,$0000,$0000,$0000, + $0000,$0000,$0000,$0000,$0000, + $0000,$0000,$0000,$0000,$0000, + $0000,$0000,$0000,$0000,$0000, + $0000,$0000,$0000,$0000,$0000, + $0000,$0000,$0000,$0000,$0000, + $0000,$0000,$0000,$0000,$0000)); +var + is_environment: tINPUT_STR_ENVIRONMENT; + +function InputStr(s: String; x,y,ln,ln1: Byte; atr1,atr2: Byte): String; +function SameName(str1,str2: String): Boolean; +function PathOnly(path: String): String; +function NameOnly(path: String): String; +function BaseNameOnly(path: String): String; +function ExtOnly(path: String): String; + +implementation + +uses + DOS,TxtScrIO; + +function Capitalize(str: String): String; assembler; +asm + mov esi,[str] + mov edi,@result + mov al,[esi] + inc esi + mov [edi],al + inc edi + xor ecx,ecx + mov cl,al + jecxz @@4 + mov al,[esi] + inc esi + cmp al,'a' + jb @@0 + cmp al,'z' + ja @@0 + sub al,20h +@@0: mov [edi],al + inc edi +@@1: mov ah,al + mov al,[esi] + inc esi + cmp ah,' ' + jnz @@2 + cmp al,'a' + jb @@2 + cmp al,'z' + ja @@2 + sub al,20h + jmp @@3 +@@2: cmp al,'A' + jb @@3 + cmp al,'Z' + ja @@3 + add al,20h +@@3: mov [edi],al + inc edi + loop @@1 +@@4: +end; + +function Upper(str: String): String; assembler; +asm + mov esi,[str] + mov edi,@result + mov al,[esi] + inc esi + mov [edi],al + inc edi + xor ecx,ecx + mov cl,al + jecxz @@3 +@@1: mov al,[esi] + inc esi + cmp al,'a' + jb @@2 + cmp al,'z' + ja @@2 + sub al,20h +@@2: mov [edi],al + inc edi + loop @@1 +@@3: +end; + +function Lower(str: String): String; assembler; +asm + mov esi,[str] + mov edi,@result + mov al,[esi] + inc esi + mov [edi],al + inc edi + xor ecx,ecx + mov cl,al + jecxz @@3 +@@1: mov al,[esi] + inc esi + cmp al,'A' + jb @@2 + cmp al,'Z' + ja @@2 + add al,20h +@@2: mov [edi],al + inc edi + loop @@1 +@@3: +end; + +function iCase(str: String): String; assembler; +asm + mov esi,[str] + mov edi,@result + mov al,[esi] + inc esi + mov [edi],al + inc edi + xor ecx,ecx + mov cl,al + jecxz @@5 + push edi + push ecx +@@1: mov al,[esi] + inc esi + cmp al,'a' + jb @@2 + cmp al,'z' + ja @@2 + sub al,20h +@@2: mov [edi],al + inc edi + loop @@1 + pop ecx + pop edi +@@3: mov al,[edi] + cmp al,'i'-20h + jnz @@4 + add al,20h +@@4: mov [edi],al + inc edi + loop @@3 +@@5: +end; + +function RotStrL(str1,str2: String; shift: Byte): String; +begin + RotStrL := Copy(str1,shift+1,Length(str1)-shift)+ + Copy(str2,1,shift); +end; + +function RotStrR(str1,str2: String; shift: Byte): String; +begin + RotStrR := Copy(str2,Length(str2)-shift+1,shift)+ + Copy(str1,1,Length(str1)-shift); +end; + +function ExpStrL(str: String; size: Byte; chr: Char): String; assembler; +asm + mov esi,[str] + mov edi,@result + cld + xor ecx,ecx + lodsb + cmp al,size + jge @@1 + mov ah,al + mov al,size + stosb + mov al,ah + mov cl,size + sub cl,al + mov al,chr + rep stosb + mov cl,ah + rep movsb + jmp @@2 +@@1: stosb + mov cl,al + rep movsb +@@2: +end; + +function ExpStrR(str: String; size: Byte; chr: Char): String; assembler; +asm + mov esi,[str] + mov edi,@result + cld + xor ecx,ecx + lodsb + cmp al,size + jge @@1 + mov ah,al + mov al,size + stosb + mov cl,ah + rep movsb + mov al,ah + mov cl,size + sub cl,al + mov al,chr + rep stosb + jmp @@2 +@@1: stosb + mov cl,al + rep movsb +@@2: +end; + +function DietStr(str: String; size: Byte): String; +begin + If (Length(str) <= size) then + begin + DietStr := str; + EXIT; + end; + + Repeat + Delete(str,size DIV 2,1) + until (Length(str)+3 = size); + + Insert('...',str,size DIV 2); + DietStr := str +end; + +function CutStr(str: String): String; +begin + While (str[0] <> #0) and (str[1] in [#00,#32]) do Delete(str,1,1); + While (str[0] <> #0) and (str[Length(str)] in [#00,#32]) do Delete(str,Length(str),1); + CutStr := str; +end; + +function FlipStr(str: String): String; assembler; +asm + mov esi,[str] + mov edi,@result + mov al,[esi] + inc esi + mov [edi],al + inc edi + dec edi + xor ecx,ecx + mov cl,al + jecxz @@2 + add edi,ecx +@@1: mov al,[esi] + inc esi + mov [edi],al + dec edi + loop @@1 +@@2: +end; + +function FilterStr(str: String; chr0,chr1: Char): String; assembler; +asm + mov esi,[str] + mov edi,@result + mov al,[esi] + inc esi + mov [edi],al + inc edi + xor ecx,ecx + mov cl,al + jecxz @@3 +@@1: mov al,[esi] + inc esi + cmp al,chr0 + jnz @@2 + mov al,chr1 +@@2: mov [edi],al + inc edi + loop @@1 +@@3: +end; + +const + _treat_char: array[$80..$a5] of Char = + 'CueaaaaceeeiiiAAE_AooouuyOU_____aiounN'; + +function FilterStr2(str: String; chr0: characters; chr1: Char): String; + +var + temp: Byte; + +begin + For temp := 1 to Length(str) do + If NOT (str[temp] in chr0) then + If (str[temp] >= #$80) and (str[temp] <= #$a5) then + str[temp] := _treat_char[BYTE(str[temp])] + else If (str[temp] = #0) then str[temp] := ' ' + else str[temp] := chr1; + FilterStr2 := str; +end; + +function Num2str(num: Longint; base: Byte): String; assembler; + +const + hexa: array[0..PRED(16)+32] of Char = '0123456789ABCDEF'+ + #0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0; +asm + xor eax,eax + xor edx,edx + xor edi,edi + xor esi,esi + mov eax,num + xor ebx,ebx + mov bl,base + cmp bl,2 + jb @@3 + cmp bl,16 + ja @@3 + mov edi,32 +@@1: dec edi + xor edx,edx + div ebx + mov esi,edx + mov dl,byte ptr [hexa+esi] + mov byte ptr [hexa+edi+16],dl + and eax,eax + jnz @@1 + mov esi,edi + mov ecx,32 + sub ecx,edi + mov edi,@result + mov al,cl + stosb +@@2: mov al,byte ptr [hexa+esi+16] + stosb + inc esi + loop @@2 + jmp @@4 +@@3: mov edi,@result + xor al,al + stosb +@@4: +end; + +const + digits: array[0..35] of Char = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'; + +function Digit2index(digit: Char): Byte; + +var + index: Byte; + +begin + digit := UpCase(digit); + index := 15; + While (index > 0) and (digit <> digits[index]) do Dec(index); + Digit2index := Index; +end; + +function position_value(position,base: Byte): Longint; + +var + value: Longint; + index: Byte; + +begin + value := 1; + For index := 2 to position do value := value*base; + position_value := value; +end; + +function Str2num(str: String; base: Byte): Longint; + +var + value: Longint; + index: Byte; + +begin + value := 0; + For index := 1 to Length(str) do + Inc(value,Digit2index(str[index])* + position_value(Length(str)-index+1,base)); + Str2num := value; +end; + +function InputStr(s: String; x,y,ln,ln1: Byte; atr1,atr2: Byte): String; + +var + appn,for1st,qflg,ins: Boolean; + cloc,xloc,xint,mx,attr: Byte; + key: Word; + cur: Longint; + s1,s2: String; + +function LookupKey(key: Word; var table; size: Byte): Boolean; assembler; +asm + mov esi,[table] + xor ecx,ecx + mov cl,size + mov al,1 + jecxz @@3 +@@1: lodsw + cmp ax,key + jz @@2 + loop @@1 +@@2: xor al,al + jecxz @@3 + mov al,1 +@@3: +end; + +function more(value1,value2: Byte): Byte; assembler; +asm + mov al,value1 + cmp al,value2 + jnb @@1 + mov al,value2 +@@1: +end; + +begin + s := Copy(s,1,ln); + If (is_environment.locate_pos > ln1) then + is_environment.locate_pos := ln1; + If (is_environment.locate_pos > Length(s)+1) then + is_environment.locate_pos := Length(s); + + cloc := is_environment.locate_pos; + xloc := is_environment.locate_pos; + xint := x; + qflg := FALSE; + ins := is_setting.insert_mode; + appn := NOT is_setting.append_enabled; + + Dec(x); + cur := GetCursor; + If ins then ThinCursor else WideCursor; + s1 := s; + If (BYTE(s1[0]) > ln1) then s1[0] := CHR(ln1); + + ShowStr(Ptr(v_seg,v_ofs)^,xint,y,ExpStrR('',ln1,' '),atr1); + ShowStr(Ptr(v_seg,v_ofs)^,xint,y,s1,atr2); + for1st := TRUE; + + Repeat + s2 := s1; + If (xloc = 1) then s1 := Copy(s,cloc,ln1) + else s1 := Copy(s,cloc-xloc+1,ln1); + + If NOT appn then attr := atr2 + else attr := atr1; + + If appn and for1st then + begin + ShowStr(Ptr(v_seg,v_ofs)^,xint,y,ExpStrR(s1,ln1,' '),atr1); + for1st := FALSE; + end; + + If (s2 <> s1) then + ShowStr(Ptr(v_seg,v_ofs)^,xint,y,ExpStrR(s1,ln1,' '),atr1); + + If (ln1 < ln) then + If (cloc-xloc > 0) and (Length(s) > 0) then + ShowStr(Ptr(v_seg,v_ofs)^,xint,y,'',(attr AND $0f0)+$0f) + else If (cloc-xloc = 0) and (Length(s) <> 0) then + ShowStr(Ptr(v_seg,v_ofs)^,xint,y,s[1],attr) + else + ShowStr(Ptr(v_seg,v_ofs)^,xint,y,' ',atr1); + + If (ln1 < ln) then + If (cloc-xloc+ln1 < Length(s)) then + ShowStr(Ptr(v_seg,v_ofs)^,xint+ln1-1,y,'',(attr AND $0f0)+$0f) + else If (cloc-xloc+ln1 = Length(s)) then + ShowStr(Ptr(v_seg,v_ofs)^,xint+ln1-1,y,s[Length(s)],attr) + else + ShowStr(Ptr(v_seg,v_ofs)^,xint+ln1-1,y,' ',atr1); + + GotoXY(x+xloc,y); + asm xor ah,ah; int 16h; mov key,ax end; + If LookupKey(key,is_setting.terminate_keys,50) then qflg := TRUE; + + If NOT qflg then + Case LO(key) of + $09: appn := TRUE; + $19: begin appn := TRUE; s := ''; cloc := 1; xloc := 1; end; + + $14: begin + appn := TRUE; + While (s[cloc] in is_setting.word_characters) and + (cloc <= Length(s)) do Delete(s,cloc,1); + + While NOT (s[cloc] in is_setting.word_characters) and + (cloc <= Length(s)) do Delete(s,cloc,1); + end; + + $7f: begin + appn := TRUE; + While (s[cloc-1] in is_setting.word_characters) and + (cloc > 1) do + begin + Dec(cloc); Delete(s,cloc,1); + If (xloc > 1) then Dec(xloc); + end; + + While NOT (s[cloc-1] in is_setting.word_characters) and + (cloc > 1) do + begin + Dec(cloc); Delete(s,cloc,1); + If (xloc > 1) then Dec(xloc); + end; + end; + + $11: begin appn := TRUE; Delete(s,cloc,Length(s)); end; + + $08: begin + appn := TRUE; + If (cloc > 1) then + begin + If (xloc > 1) then Dec(xloc); + Dec(cloc); Delete(s,cloc,1); + end; + end; + + $00: begin + If (HI(key) in [$73,$74,$4b,$4d,$52,$47,$4f]) then + appn := TRUE; + + Case (HI(key)) of + $73: begin + While (s[cloc] in is_setting.word_characters) and + (cloc > 1) do + begin + Dec(cloc); + If (xloc > 1) then Dec(xloc); + end; + + While NOT (s[cloc] in is_setting.word_characters) and + (cloc > 1) do + begin + Dec(cloc); + If (xloc > 1) then Dec(xloc); + end; + end; + + $74: begin + While (s[cloc] in is_setting.word_characters) and + (cloc < Length(s)) do + begin + Inc(cloc); + If (xloc < ln1) then Inc(xloc); + end; + + While NOT (s[cloc] in is_setting.word_characters) and + (cloc < Length(s)) do + begin + Inc(cloc); + If (xloc < ln1) then Inc(xloc); + end; + end; + + $4b: begin + If (cloc > 1) then Dec(cloc); + If (xloc > 1) then Dec(xloc); + end; + + $4d: begin + If (cloc < Length(s)) or ((cloc = Length(s)) and + ((Length(s) < more(ln,ln1)))) then + Inc(cloc); + If (xloc < ln1) and (xloc <= Length(s)) then Inc(xloc); + end; + + $53: begin + appn := TRUE; + If (cloc <= Length(s)) then Delete(s,cloc,1); + end; + + $52: If is_setting.replace_enabled then + begin + ins := NOT ins; + If ins then ThinCursor else WideCursor; + end; + + $47: begin cloc := 1; xloc := 1; end; + + $4f: begin + If (Length(s) < more(ln,ln1)) then cloc := Succ(Length(s)) + else cloc := Length(s); + If (cloc < ln1) then xloc := cloc else xloc := ln1; + end; + end; + end; + + else If NOT (LO(key) in [$09,$19,$0d,$14,$0b,$7f]) and + (CHR(LO(key)) in characters(is_setting.character_set)) then + begin + If NOT appn then begin s := ''; cloc := 1; xloc := 1; end; + appn := TRUE; + If ins and (Length(s) < ln) then + begin + Insert(CHR(LO(key)),s,cloc); + s := FilterStr2(s,is_setting.valid_chars,'_'); + If (cloc < ln) then Inc(cloc); + If (xloc < ln) and (xloc < ln1) then Inc(xloc) + end + else + If (Length(s) < ln) or NOT ins then + begin + If (cloc > Length(s)) and (Length(s) < ln) then + Inc(BYTE(s[0])); + + s[cloc] := CHR(LO(key)); + s := FilterStr2(s,is_setting.valid_chars,'_'); + If (cloc < ln) then Inc(cloc); + If (xloc < ln) and (xloc < ln1) then Inc(xloc); + end; + end; + end; + until qflg; + +// SetCursor(cur); + If (cloc = 0) then is_environment.locate_pos := 1 + else is_environment.locate_pos := cloc; + is_environment.keystroke := key; + InputStr := s; +end; + +function SameName(str1,str2: String): Boolean; assembler; + +var + LastW: Word; + +asm + xor eax,eax + xor ecx,ecx + mov esi,[str1] + mov edi,[str2] + xor ah,ah + mov al,[esi] + inc esi + mov cx,ax + mov al,[edi] + inc edi + mov bx,ax + or cx,cx + jnz @@1 + or bx,bx + jz @@13 + jmp @@14 + xor dh,dh +@@1: mov al,[esi] + inc esi + cmp al,'*' + jne @@2 + dec cx + jz @@13 + mov dh,1 + mov LastW,cx + jmp @@1 +@@2: cmp al,'?' + jnz @@3 + inc edi + or bx,bx + je @@12 + dec bx + jmp @@12 +@@3: or bx,bx + je @@14 + cmp al,'[' + jne @@11 + cmp word ptr [esi],']?' + je @@9 + mov ah,byte ptr [edi] + xor dl,dl + cmp byte ptr [esi],'!' + jnz @@4 + inc esi + dec cx + jz @@14 + inc dx +@@4: mov al,[esi] + inc esi + dec cx + jz @@14 + cmp al,']' + je @@7 + cmp ah,al + je @@6 + cmp byte ptr [esi],'-' + jne @@4 + inc esi + dec cx + jz @@14 + cmp ah,al + jae @@5 + inc esi + dec cx + jz @@14 + jmp @@4 +@@5: mov al,[esi] + inc esi + dec cx + jz @@14 + cmp ah,al + ja @@4 +@@6: or dl,dl + jnz @@14 + inc dx +@@7: or dl,dl + jz @@14 +@@8: cmp al,']' + je @@10 +@@9: mov al,[esi] + inc esi + cmp al,']' + loopne @@9 + jne @@14 +@@10: dec bx + inc edi + jmp @@12 +@@11: cmp [edi],al + jne @@14 + inc edi + dec bx +@@12: xor dh,dh + dec cx + jnz @@1 + or bx,bx + jnz @@14 +@@13: mov al,1 + jmp @@16 +@@14: or dh,dh + jz @@15 + jecxz @@15 + or bx,bx + jz @@15 + inc edi + dec bx + jz @@15 + mov ax,LastW + sub ax,cx + add cx,ax + sub esi,eax + dec esi + jmp @@1 +@@15: mov al,0 +@@16: +end; + +var + dir: DirStr; + name: NameStr; + ext: ExtStr; + +function PathOnly(path: String): String; +begin + FSplit(path,dir,name,ext); + PathOnly := dir; +end; + +function NameOnly(path: String): String; +begin + FSplit(path,dir,name,ext); + NameOnly := name+ext; +end; + +function BaseNameOnly(path: String): String; +begin + FSplit(path,dir,name,ext); + BaseNameOnly := name; +end; + +function ExtOnly(path: String): String; +begin + FSplit(path,dir,name,ext); + Delete(ext,1,1); + ExtOnly := ext; +end; + +begin + is_environment.locate_pos := 1; +end. diff --git a/16/ADT2PLAY/STRUCTRS.INC b/16/ADT2PLAY/STRUCTRS.INC new file mode 100644 index 00000000..37fb9b71 --- /dev/null +++ b/16/ADT2PLAY/STRUCTRS.INC @@ -0,0 +1,2231 @@ +procedure _font8x8; assembler; +asm + dd 0AAAA0000h,0000000AAh,0AAAA8080h,0808080AAh,0AAAAA0A0h,0A0A0A0AAh,0AAAAA8A8h,0A8A8A8AAh + dd 0AAAAAAAAh,0AAAAAAAAh,0FE387C38h,07C387CFEh,07C381010h,07C387CFEh,03C180000h,00000183Ch + dd 0C3E7FFFFh,0FFFFE7C3h,042663C00h,0003C6642h,0BD99C3FFh,0FFC399BDh,07D0F070Fh,078CCCCCCh + dd 06666663Ch,0187E183Ch,0303F333Fh,0E0F07030h,0637F637Fh,0C0E66763h,0E73C5A99h,0995A3CE7h + dd 0FEF8E080h,00080E0F8h,0FE3E0E02h,000020E3Eh,0187E3C18h,0183C7E18h,066666666h,000660066h + dd 07BDBDB7Fh,0001B1B1Bh,06C38633Eh,078CC386Ch,000000000h,0007E7E7Eh,0187E3C18h,0FF183C7Eh + dd 0187E3C18h,000181818h,018181818h,000183C7Eh,0FE0C1800h,00000180Ch,0FE603000h,000003060h + dd 0C0C00000h,00000FEC0h,0FF662400h,000002466h,07E3C1800h,00000FFFFh,07EFFFF00h,00000183Ch + dd 000000000h,000000000h,030787830h,000300030h,0006C6C6Ch,000000000h,06CFE6C6Ch,0006C6CFEh + dd 078C07C30h,00030F80Ch,018CCC600h,000C66630h,076386C38h,00076CCDCh,000C06060h,000000000h + dd 060603018h,000183060h,018183060h,000603018h,0FF3C6600h,00000663Ch,0FC303000h,000003030h + dd 000000000h,060303000h,0FC000000h,000000000h,000000000h,000303000h,030180C06h,00080C060h + dd 0DECEC67Ch,0007CE6F6h,030307030h,000FC3030h,0380CCC78h,000FCCC60h,0380CCC78h,00078CC0Ch + dd 0CC6C3C1Ch,0001E0CFEh,00CF8C0FCh,00078CC0Ch,0F8C06038h,00078CCCCh,0180CCCFCh,000303030h + dd 078CCCC78h,00078CCCCh,07CCCCC78h,00070180Ch,000303000h,000303000h,000303000h,060303000h + dd 0C0603018h,000183060h,000FC0000h,00000FC00h,00C183060h,000603018h,0180CCC78h,000300030h + dd 0DEDEC67Ch,00078C0DEh,0CCCC7830h,000CCCCFCh,07C6666FCh,000FC6666h,0C0C0663Ch,0003C66C0h + dd 066666CF8h,000F86C66h,0786862FEh,000FE6268h,0786862FEh,000F06068h,0C0C0663Ch,0003E66CEh + dd 0FCCCCCCCh,000CCCCCCh,030303078h,000783030h,00C0C0C1Eh,00078CCCCh,0786C66E6h,000E6666Ch + dd 0606060F0h,000FE6662h,0FEFEEEC6h,000C6C6D6h,0DEF6E6C6h,000C6C6CEh,0C6C66C38h,000386CC6h + dd 07C6666FCh,000F06060h,0CCCCCC78h,0001C78DCh,07C6666FCh,000E6666Ch,070E0CC78h,00078CC1Ch + dd 03030B4FCh,000783030h,0CCCCCCCCh,000FCCCCCh,0CCCCCCCCh,0003078CCh,0D6C6C6C6h,000C6EEFEh + dd 0386CC6C6h,000C66C38h,078CCCCCCh,000783030h,0188CC6FEh,000FE6632h,060606078h,000786060h + dd 0183060C0h,00002060Ch,018181878h,000781818h,0C66C3810h,000000000h,000000000h,0FF000000h + dd 000183030h,000000000h,00C780000h,00076CC7Ch,07C6060E0h,000DC6666h,0CC780000h,00078CCC0h + dd 07C0C0C1Ch,00076CCCCh,0CC780000h,00078C0FCh,0F0606C38h,000F06060h,0CC760000h,0F80C7CCCh + dd 0766C60E0h,000E66666h,030700030h,000783030h,00C0C000Ch,078CCCC0Ch,06C6660E0h,000E66C78h + dd 030303070h,000783030h,0FECC0000h,000C6D6FEh,0CCF80000h,000CCCCCCh,0CC780000h,00078CCCCh + dd 066DC0000h,0F0607C66h,0CC760000h,01E0C7CCCh,076DC0000h,000F06066h,0C07C0000h,000F80C78h + dd 0307C3010h,000183430h,0CCCC0000h,00076CCCCh,0CCCC0000h,0003078CCh,0D6C60000h,0006CFEFEh + dd 06CC60000h,000C66C38h,0CCCC0000h,0F80C7CCCh,098FC0000h,000FC6430h,0E030301Ch,0001C3030h + dd 000181818h,000181818h,01C3030E0h,000E03030h,00000DC76h,000000000h,06C381000h,000FEC6C6h + dd 0CCC0CC78h,0780C1878h,0CC00CC00h,0007ECCCCh,0CC78001Ch,00078C0FCh,0063CC37Eh,0003F663Eh + dd 00C7800CCh,0007ECC7Ch,00C7800E0h,0007ECC7Ch,00C783030h,0007ECC7Ch,0C0780000h,0380C78C0h + dd 0663CC37Eh,0003C607Eh,0CC7800CCh,00078C0FCh,0CC7800E0h,00078C0FCh,0307000CCh,000783030h + dd 01838C67Ch,0003C1818h,0307000E0h,000783030h,0C66C38C6h,000C6C6FEh,078003030h,000CCFCCCh + dd 060FC001Ch,000FC6078h,00C7F0000h,0007FCC7Fh,0FECC6C3Eh,000CECCCCh,07800CC78h,00078CCCCh + dd 07800CC00h,00078CCCCh,07800E000h,00078CCCCh,0CC00CC78h,0007ECCCCh,0CC00E000h,0007ECCCCh + dd 0CC00CC00h,0F80C7CCCh,0663C18C3h,000183C66h,0CCCC00CCh,00078CCCCh,0C07E1818h,018187EC0h + dd 0F0646C38h,000FCE660h,0FC78CCCCh,03030FC30h,0FACCCCF8h,0C7C6CFC6h,03C181B0Eh,070D81818h + dd 00C78001Ch,0007ECC7Ch,030700038h,000783030h,078001C00h,00078CCCCh,0CC001C00h,0007ECCCCh + dd 0F800F800h,000CCCCCCh,0ECCC00FCh,000CCDCFCh,03E6C6C3Ch,000007E00h,0386C6C38h,000007C00h + dd 060300030h,00078CCC0h,0FC000000h,00000C0C0h,0FC000000h,000000C0Ch,0DECCC6C3h,00FCC6633h + dd 0DBCCC6C3h,003CF6F37h,018001818h,000181818h,0CC663300h,000003366h,03366CC00h,00000CC66h + dd 088228822h,088228822h,0AA55AA55h,0AA55AA55h,0EEDB77DBh,0EEDB77DBh,018181818h,018181818h + dd 018181818h,0181818F8h,018F81818h,0181818F8h,036363636h,0363636F6h,000000000h,0363636FEh + dd 018F80000h,0181818F8h,006F63636h,0363636F6h,036363636h,036363636h,006FE0000h,0363636F6h + dd 006F63636h,0000000FEh,036363636h,0000000FEh,018F81818h,0000000F8h,000000000h,0181818F8h + dd 018181818h,00000001Fh,018181818h,0000000FFh,000000000h,0181818FFh,018181818h,01818181Fh + dd 000000000h,0000000FFh,018181818h,0181818FFh,0181F1818h,01818181Fh,036363636h,036363637h + dd 030373636h,00000003Fh,0303F0000h,036363637h,000F73636h,0000000FFh,000FF0000h,0363636F7h + dd 030373636h,036363637h,000FF0000h,0000000FFh,000F73636h,0363636F7h,000FF1818h,0000000FFh + dd 036363636h,0000000FFh,000FF0000h,0181818FFh,000000000h,0363636FFh,036363636h,00000003Fh + dd 0181F1818h,00000001Fh,0181F0000h,01818181Fh,000000000h,03636363Fh,036363636h,0363636FFh + dd 018FF1818h,0181818FFh,018181818h,0000000F8h,000000000h,01818181Fh,0FFFFFFFFh,0FFFFFFFFh + dd 000000000h,0FFFFFFFFh,0F0F0F0F0h,0F0F0F0F0h,00F0F0F0Fh,00F0F0F0Fh,0FFFFFFFFh,000000000h + dd 0DC760000h,00076DCC8h,0F8CC7800h,0C0C0F8CCh,0C0CCFC00h,000C0C0C0h,06C6CFE00h,0006C6C6Ch + dd 03060CCFCh,000FCCC60h,0D87E0000h,00070D8D8h,066666600h,0C0607C66h,018DC7600h,000181818h + dd 0CC7830FCh,0FC3078CCh,0FEC66C38h,000386CC6h,0C6C66C38h,000EE6C6Ch,07C18301Ch,00078CCCCh + dd 0DB7E0000h,000007EDBh,0DB7E0C06h,0C0607EDBh,0F8C06038h,0003860C0h,0CCCCCC78h,000CCCCCCh + dd 0FC00FC00h,00000FC00h,030FC3030h,000FC0030h,030183060h,000FC0060h,030603018h,000FC0018h + dd 0181B1B0Eh,018181818h,018181818h,070D8D818h,0FC003030h,000303000h,000DC7600h,00000DC76h + dd 0386C6C38h,000000000h,018000000h,000000018h,000000000h,000000018h,00C0C0C0Fh,01C3C6CECh + dd 06C6C6C78h,00000006Ch,060301870h,000000078h,03C3C0000h,000003C3Ch,000000000h,000000000h +end; + +procedure _font8x16; assembler; +asm + dd 000000000h,000000000h,000000000h,000000000h,0817E0000h,0A58181A5h,07E818199h,000000000h + dd 0FF7E0000h,0DBFFFFDBh,07EFFFFE7h,000000000h,000000000h,0FEFEFE6Ch,010387CFEh,000000000h + dd 000000000h,0FE7C3810h,00010387Ch,000000000h,018000000h,0E7E73C3Ch,03C1818E7h,000000000h + dd 018000000h,0FFFF7E3Ch,03C18187Eh,000000000h,000000000h,03C180000h,00000183Ch,000000000h + dd 0FFFFFFFFh,0C3E7FFFFh,0FFFFE7C3h,0FFFFFFFFh,000000000h,042663C00h,0003C6642h,000000000h + dd 0FFFFFFFFh,0BD99C3FFh,0FFC399BDh,0FFFFFFFFh,0061E0000h,0CC781A0Eh,078CCCCCCh,000000000h + dd 0663C0000h,03C666666h,018187E18h,000000000h,0333F0000h,03030303Fh,0E0F07030h,000000000h + dd 0637F0000h,06363637Fh,0E6E76763h,0000000C0h,018000000h,0E73CDB18h,01818DB3Ch,000000000h + dd 0E0C08000h,0F8FEF8F0h,080C0E0F0h,000000000h,00E060200h,03EFE3E1Eh,002060E1Eh,000000000h + dd 03C180000h,01818187Eh,000183C7Eh,000000000h,066660000h,066666666h,066660066h,000000000h + dd 0DB7F0000h,01B7BDBDBh,01B1B1B1Bh,000000000h,060C67C00h,0C6C66C38h,0C60C386Ch,00000007Ch + dd 000000000h,000000000h,0FEFEFEFEh,000000000h,03C180000h,01818187Eh,07E183C7Eh,000000000h + dd 03C180000h,01818187Eh,018181818h,000000000h,018180000h,018181818h,0183C7E18h,000000000h + dd 000000000h,0FE0C1800h,00000180Ch,000000000h,000000000h,0FE603000h,000003060h,000000000h + dd 000000000h,0C0C00000h,00000FEC0h,000000000h,000000000h,0FE6C2800h,00000286Ch,000000000h + dd 000000000h,07C383810h,000FEFE7Ch,000000000h,000000000h,07C7CFEFEh,000103838h,000000000h + dd 000000000h,000000000h,000000000h,000000000h,03C180000h,018183C3Ch,018180018h,000000000h + dd 066666600h,000000024h,000000000h,000000000h,06C000000h,06C6CFE6Ch,06C6CFE6Ch,000000000h + dd 0C67C1818h,0067CC0C2h,07CC68606h,000001818h,000000000h,0180CC6C2h,086C66030h,000000000h + dd 06C380000h,0DC76386Ch,076CCCCCCh,000000000h,030303000h,000000060h,000000000h,000000000h + dd 0180C0000h,030303030h,00C183030h,000000000h,018300000h,00C0C0C0Ch,030180C0Ch,000000000h + dd 000000000h,0FF3C6600h,00000663Ch,000000000h,000000000h,07E181800h,000001818h,000000000h + dd 000000000h,000000000h,018181800h,000000030h,000000000h,0FE000000h,000000000h,000000000h + dd 000000000h,000000000h,018180000h,000000000h,000000000h,0180C0602h,080C06030h,000000000h + dd 0C67C0000h,0F6DECEC6h,07CC6C6E6h,000000000h,038180000h,018181878h,07E181818h,000000000h + dd 0C67C0000h,030180C06h,0FEC6C060h,000000000h,0C67C0000h,0063C0606h,07CC60606h,000000000h + dd 01C0C0000h,0FECC6C3Ch,01E0C0C0Ch,000000000h,0C0FE0000h,006FCC0C0h,07CC60606h,000000000h + dd 060380000h,0C6FCC0C0h,07CC6C6C6h,000000000h,0C6FE0000h,0180C0606h,030303030h,000000000h + dd 0C67C0000h,0C67CC6C6h,07CC6C6C6h,000000000h,0C67C0000h,0067EC6C6h,0780C0606h,000000000h + dd 000000000h,000001818h,000181800h,000000000h,000000000h,000001818h,030181800h,000000000h + dd 006000000h,06030180Ch,0060C1830h,000000000h,000000000h,000007E00h,00000007Eh,000000000h + dd 060000000h,0060C1830h,06030180Ch,000000000h,0C67C0000h,018180CC6h,018180018h,000000000h + dd 07C000000h,0DEDEC6C6h,07CC0DCDEh,000000000h,038100000h,0FEC6C66Ch,0C6C6C6C6h,000000000h + dd 066FC0000h,0667C6666h,0FC666666h,000000000h,0663C0000h,0C0C0C0C2h,03C66C2C0h,000000000h + dd 06CF80000h,066666666h,0F86C6666h,000000000h,066FE0000h,068786862h,0FE666260h,000000000h + dd 066FE0000h,068786862h,0F0606060h,000000000h,0663C0000h,0DEC0C0C2h,03A66C6C6h,000000000h + dd 0C6C60000h,0C6FEC6C6h,0C6C6C6C6h,000000000h,0183C0000h,018181818h,03C181818h,000000000h + dd 00C1E0000h,00C0C0C0Ch,078CCCCCCh,000000000h,066E60000h,078786C66h,0E666666Ch,000000000h + dd 060F00000h,060606060h,0FE666260h,000000000h,0EEC60000h,0C6D6FEFEh,0C6C6C6C6h,000000000h + dd 0E6C60000h,0CEDEFEF6h,0C6C6C6C6h,000000000h,0C67C0000h,0C6C6C6C6h,07CC6C6C6h,000000000h + dd 066FC0000h,0607C6666h,0F0606060h,000000000h,0C67C0000h,0C6C6C6C6h,07CDED6C6h,000000E0Ch + dd 066FC0000h,06C7C6666h,0E6666666h,000000000h,0C67C0000h,00C3860C6h,07CC6C606h,000000000h + dd 07E7E0000h,01818185Ah,03C181818h,000000000h,0C6C60000h,0C6C6C6C6h,07CC6C6C6h,000000000h + dd 0C6C60000h,0C6C6C6C6h,010386CC6h,000000000h,0C6C60000h,0D6D6C6C6h,06CEEFED6h,000000000h + dd 0C6C60000h,038387C6Ch,0C6C66C7Ch,000000000h,066660000h,0183C6666h,03C181818h,000000000h + dd 0C6FE0000h,030180C86h,0FEC6C260h,000000000h,0303C0000h,030303030h,03C303030h,000000000h + dd 080000000h,03870E0C0h,002060E1Ch,000000000h,00C3C0000h,00C0C0C0Ch,03C0C0C0Ch,000000000h + dd 0C66C3810h,000000000h,000000000h,000000000h,000000000h,000000000h,000000000h,00000FF00h + dd 000183030h,000000000h,000000000h,000000000h,000000000h,07C0C7800h,076CCCCCCh,000000000h + dd 060E00000h,0666C7860h,07C666666h,000000000h,000000000h,0C0C67C00h,07CC6C0C0h,000000000h + dd 00C1C0000h,0CC6C3C0Ch,076CCCCCCh,000000000h,000000000h,0FEC67C00h,07CC6C0C0h,000000000h + dd 06C380000h,060F06064h,0F0606060h,000000000h,000000000h,0CCCC7600h,07CCCCCCCh,00078CC0Ch + dd 060E00000h,066766C60h,0E6666666h,000000000h,018180000h,018183800h,03C181818h,000000000h + dd 006060000h,006060E00h,006060606h,0003C6666h,060E00000h,0786C6660h,0E6666C78h,000000000h + dd 018380000h,018181818h,03C181818h,000000000h,000000000h,0D6FEEC00h,0C6D6D6D6h,000000000h + dd 000000000h,06666DC00h,066666666h,000000000h,000000000h,0C6C67C00h,07CC6C6C6h,000000000h + dd 000000000h,06666DC00h,07C666666h,000F06060h,000000000h,0CCCC7600h,07CCCCCCCh,0001E0C0Ch + dd 000000000h,06676DC00h,0F0606060h,000000000h,000000000h,060C67C00h,07CC60C38h,000000000h + dd 030100000h,03030FC30h,01C363030h,000000000h,000000000h,0CCCCCC00h,076CCCCCCh,000000000h + dd 000000000h,066666600h,0183C6666h,000000000h,000000000h,0D6C6C600h,06CFED6D6h,000000000h + dd 000000000h,0386CC600h,0C66C3838h,000000000h,000000000h,0C6C6C600h,07EC6C6C6h,000F80C06h + dd 000000000h,018CCFE00h,0FEC66030h,000000000h,0180E0000h,018701818h,00E181818h,000000000h + dd 018180000h,018001818h,018181818h,000000000h,018700000h,0180E1818h,070181818h,000000000h + dd 0DC760000h,000000000h,000000000h,000000000h,000000000h,0C66C3810h,000FEC6C6h,000000000h + dd 0663C0000h,0C0C0C0C2h,00C3C66C2h,000007C06h,000CC0000h,0CCCCCC00h,076CCCCCCh,000000000h + dd 030180C00h,0FEC67C00h,07CC6C0C0h,000000000h,06C381000h,07C0C7800h,076CCCCCCh,000000000h + dd 000CC0000h,07C0C7800h,076CCCCCCh,000000000h,018306000h,07C0C7800h,076CCCCCCh,000000000h + dd 0386C3800h,07C0C7800h,076CCCCCCh,000000000h,000000000h,06060663Ch,0060C3C66h,00000003Ch + dd 06C381000h,0FEC67C00h,07CC6C0C0h,000000000h,000C60000h,0FEC67C00h,07CC6C0C0h,000000000h + dd 018306000h,0FEC67C00h,07CC6C0C0h,000000000h,000660000h,018183800h,03C181818h,000000000h + dd 0663C1800h,018183800h,03C181818h,000000000h,018306000h,018183800h,03C181818h,000000000h + dd 01000C600h,0C6C66C38h,0C6C6C6FEh,000000000h,000386C38h,0C6C66C38h,0C6C6C6FEh,000000000h + dd 000603018h,07C6066FEh,0FE666060h,000000000h,000000000h,03676CC00h,06ED8D87Eh,000000000h + dd 06C3E0000h,0CCFECCCCh,0CECCCCCCh,000000000h,06C381000h,0C6C67C00h,07CC6C6C6h,000000000h + dd 000C60000h,0C6C67C00h,07CC6C6C6h,000000000h,018306000h,0C6C67C00h,07CC6C6C6h,000000000h + dd 0CC783000h,0CCCCCC00h,076CCCCCCh,000000000h,018306000h,0CCCCCC00h,076CCCCCCh,000000000h + dd 000C60000h,0C6C6C600h,07EC6C6C6h,000780C06h,07C00C600h,0C6C6C6C6h,07CC6C6C6h,000000000h + dd 0C600C600h,0C6C6C6C6h,07CC6C6C6h,000000000h,03C181800h,060606066h,018183C66h,000000000h + dd 0646C3800h,06060F060h,0FCE66060h,000000000h,066660000h,0187E183Ch,01818187Eh,000000000h + dd 0CCCCF800h,0DECCC4F8h,0C6CCCCCCh,000000000h,0181B0E00h,0187E1818h,018181818h,0000070D8h + dd 060301800h,07C0C7800h,076CCCCCCh,000000000h,030180C00h,018183800h,03C181818h,000000000h + dd 060301800h,0C6C67C00h,07CC6C6C6h,000000000h,060301800h,0CCCCCC00h,076CCCCCCh,000000000h + dd 0DC760000h,06666DC00h,066666666h,000000000h,0C600DC76h,0DEFEF6E6h,0C6C6C6CEh,000000000h + dd 06C6C3C00h,0007E003Eh,000000000h,000000000h,06C6C3800h,0007C0038h,000000000h,000000000h + dd 030300000h,060303000h,07CC6C6C0h,000000000h,000000000h,0C0FE0000h,000C0C0C0h,000000000h + dd 000000000h,006FE0000h,000060606h,000000000h,0C2C0C000h,03018CCC6h,00C86DC60h,000003E18h + dd 0C2C0C000h,03018CCC6h,03E9ECE66h,000000606h,018180000h,018181800h,0183C3C3Ch,000000000h + dd 000000000h,0D86C3600h,00000366Ch,000000000h,000000000h,0366CD800h,00000D86Ch,000000000h + dd 044114411h,044114411h,044114411h,044114411h,0AA55AA55h,0AA55AA55h,0AA55AA55h,0AA55AA55h + dd 077DD77DDh,077DD77DDh,077DD77DDh,077DD77DDh,018181818h,018181818h,018181818h,018181818h + dd 018181818h,0F8181818h,018181818h,018181818h,018181818h,0F818F818h,018181818h,018181818h + dd 036363636h,0F6363636h,036363636h,036363636h,000000000h,0FE000000h,036363636h,036363636h + dd 000000000h,0F818F800h,018181818h,018181818h,036363636h,0F606F636h,036363636h,036363636h + dd 036363636h,036363636h,036363636h,036363636h,000000000h,0F606FE00h,036363636h,036363636h + dd 036363636h,0FE06F636h,000000000h,000000000h,036363636h,0FE363636h,000000000h,000000000h + dd 018181818h,0F818F818h,000000000h,000000000h,000000000h,0F8000000h,018181818h,018181818h + dd 018181818h,01F181818h,000000000h,000000000h,018181818h,0FF181818h,000000000h,000000000h + dd 000000000h,0FF000000h,018181818h,018181818h,018181818h,01F181818h,018181818h,018181818h + dd 000000000h,0FF000000h,000000000h,000000000h,018181818h,0FF181818h,018181818h,018181818h + dd 018181818h,01F181F18h,018181818h,018181818h,036363636h,037363636h,036363636h,036363636h + dd 036363636h,03F303736h,000000000h,000000000h,000000000h,037303F00h,036363636h,036363636h + dd 036363636h,0FF00F736h,000000000h,000000000h,000000000h,0F700FF00h,036363636h,036363636h + dd 036363636h,037303736h,036363636h,036363636h,000000000h,0FF00FF00h,000000000h,000000000h + dd 036363636h,0F700F736h,036363636h,036363636h,018181818h,0FF00FF18h,000000000h,000000000h + dd 036363636h,0FF363636h,000000000h,000000000h,000000000h,0FF00FF00h,018181818h,018181818h + dd 000000000h,0FF000000h,036363636h,036363636h,036363636h,03F363636h,000000000h,000000000h + dd 018181818h,01F181F18h,000000000h,000000000h,000000000h,01F181F00h,018181818h,018181818h + dd 000000000h,03F000000h,036363636h,036363636h,036363636h,0FF363636h,036363636h,036363636h + dd 018181818h,0FF18FF18h,018181818h,018181818h,018181818h,0F8181818h,000000000h,000000000h + dd 000000000h,01F000000h,018181818h,018181818h,0FFFFFFFFh,0FFFFFFFFh,0FFFFFFFFh,0FFFFFFFFh + dd 000000000h,0FF000000h,0FFFFFFFFh,0FFFFFFFFh,0F0F0F0F0h,0F0F0F0F0h,0F0F0F0F0h,0F0F0F0F0h + dd 00F0F0F0Fh,00F0F0F0Fh,00F0F0F0Fh,00F0F0F0Fh,0FFFFFFFFh,000FFFFFFh,000000000h,000000000h + dd 000000000h,0D8DC7600h,076DCD8D8h,000000000h,0CC780000h,0CCD8CCCCh,0CCC6C6C6h,000000000h + dd 0C6FE0000h,0C0C0C0C6h,0C0C0C0C0h,000000000h,000000000h,06C6C6CFEh,06C6C6C6Ch,000000000h + dd 0FE000000h,0183060C6h,0FEC66030h,000000000h,000000000h,0D8D87E00h,070D8D8D8h,000000000h + dd 000000000h,066666666h,060607C66h,0000000C0h,000000000h,01818DC76h,018181818h,000000000h + dd 07E000000h,066663C18h,07E183C66h,000000000h,038000000h,0FEC6C66Ch,0386CC6C6h,000000000h + dd 06C380000h,06CC6C6C6h,0EE6C6C6Ch,000000000h,0301E0000h,0663E0C18h,03C666666h,000000000h + dd 000000000h,0DBDB7E00h,000007EDBh,000000000h,003000000h,0DBDB7E06h,0C0607EF3h,000000000h + dd 0301C0000h,0607C6060h,01C306060h,000000000h,07C000000h,0C6C6C6C6h,0C6C6C6C6h,000000000h + dd 000000000h,0FE0000FEh,000FE0000h,000000000h,000000000h,0187E1818h,0FF000018h,000000000h + dd 030000000h,00C060C18h,07E003018h,000000000h,00C000000h,030603018h,07E000C18h,000000000h + dd 01B0E0000h,01818181Bh,018181818h,018181818h,018181818h,018181818h,070D8D8D8h,000000000h + dd 000000000h,07E001818h,000181800h,000000000h,000000000h,000DC7600h,00000DC76h,000000000h + dd 06C6C3800h,000000038h,000000000h,000000000h,000000000h,018000000h,000000018h,000000000h + dd 000000000h,000000000h,000000018h,000000000h,00C0C0F00h,0EC0C0C0Ch,01C3C6C6Ch,000000000h + dd 06C6CD800h,0006C6C6Ch,000000000h,000000000h,030D87000h,000F8C860h,000000000h,000000000h + dd 000000000h,07C7C7C7Ch,0007C7C7Ch,000000000h,000000000h,000000000h,000000000h,000000000h +end; + +procedure _picture_palette; +asm + dd 000000000h,000003F1Fh,002000001h,000020000h,000000200h,003000002h,000030000h,000000300h + dd 004000003h,000040000h,000000400h,005000004h,000050000h,000000500h,006000005h,000060000h + dd 000000600h,007000006h,000070000h,000000700h,008000007h,000080000h,000000800h,009000008h + dd 000090000h,000000900h,00A000009h,0000A0000h,000000A00h,00B00000Ah,0000B0000h,000000B00h + dd 00C00000Bh,0000C0000h,000000C00h,00D00000Ch,0000D0000h,000000D00h,00E00000Dh,0000E0000h + dd 000000E00h,00F00000Eh,0000F0000h,000000F00h,01000000Fh,000100000h,000001000h,011000010h + dd 000110000h,000001100h,012000011h,000120000h,000001200h,013000012h,000130000h,000001300h + dd 014000013h,000140000h,000001400h,015000014h,000150000h,000001500h,016000015h,000160000h + dd 000001600h,017000016h,000170000h,000001700h,018000017h,000180000h,000001800h,019000018h + dd 000190000h,000001900h,01A000019h,0001A0000h,000001A00h,01B00001Ah,0001B0000h,000001B00h + dd 01C00001Bh,0001C0000h,000001C00h,01D00001Ch,0001D0000h,000001D00h,01E00001Dh,0001E0000h + dd 000001E00h,01F00001Eh,0001F0000h,000001F00h,02000001Fh,000200000h,000002000h,021000020h + dd 000210000h,000002100h,022000021h,000220000h,000002200h,023000022h,000230000h,000002300h + dd 024000023h,000240000h,000002400h,025000024h,000250000h,000002500h,026000025h,000260000h + dd 000002600h,027000026h,000270000h,000002700h,028000027h,000280000h,000002800h,029000028h + dd 000290000h,000002900h,02A000029h,0002A0000h,000002A00h,02B00002Ah,0002B0000h,000002B00h + dd 02C00002Bh,0002C0000h,000002C00h,02D00002Ch,0002D0000h,000002D00h,02E00002Dh,0002E0000h + dd 000002E00h,02F00002Eh,0002F0000h,000002F00h,03000002Fh,000300000h,000003000h,031000030h + dd 000310000h,000003100h,032000031h,000320000h,000003200h,033000032h,000330000h,000003300h + dd 034000033h,000340000h,000003400h,035000034h,000350000h,000003500h,036000035h,000360000h + dd 000003600h,037000036h,000370000h,000003700h,038000037h,000380000h,000003800h,039000038h + dd 000390000h,000003900h,03A000039h,0003A0000h,000003A00h,03B00003Ah,0003B0000h,000003B00h + dd 03C00003Bh,0003C0000h,000003C00h,03D00003Ch,0003D0000h,000003D00h,03E00003Dh,0003E0000h + dd 000003E00h,03F00003Eh,0003F0000h,000003F00h,03020103Fh,016322212h,02A1A3626h,03F2F1F3Ah +end; + +procedure _picture_bitmap; assembler; +asm + dd 050434E6Bh,05A606156h,059635761h,05853604Fh,056535052h,063645855h,05E65655Ch,07965505Bh + dd 09A8B7A79h,0918A8D95h,079778387h,09A9D927Bh,08195938Ah,07F727A82h,0967E8388h,0829A9C92h + dd 0AAA49B94h,07AA3A9B1h,0958F8C79h,0908C8588h,080826787h,08E989687h,065748B99h,07875A181h + dd 0978E7679h,07D8B8C7Dh,09C8D887Fh,0AEA08F91h,0C5B7A5AAh,0B0B2B8C7h,0BBC2C4BEh,0CCB7B1BCh + dd 0ABB5AAACh,08F8F9097h,08F9B9B8Fh,095879992h,08B797A93h,09BA3847Bh,09C91999Ch,084868882h + dd 0918A8F8Eh,090989481h,0686F6879h,067676D65h,060555962h,065686B59h,07A676555h,06F768384h + dd 07A686168h,0716E6D72h,07D747A7Eh,07C877D75h,0695F5861h,092907E73h,07D868688h,0A9896E67h + dd 08E7B73B4h,096835C7Eh,08B8A9189h,07C85909Fh,0626A515Dh,079848170h,0676E645Dh,07C78696Eh + dd 0725A6B73h,0876C6C6Fh,08E607AA1h,098999191h,07F9394A0h,06B6D736Eh,06E61656Ch,06E6E726Eh + dd 068716E75h,062625D8Ah,0595D6762h,0706C705Fh,06161686Ch,0838F776Fh,04C878689h,05C635253h + dd 04845506Bh,0575D594Dh,053605A52h,04F49484Dh,057584453h,06C726A59h,074786D53h,07E70556Eh + dd 0907D7D80h,0AE9C989Eh,0708590A2h,090A19767h,08B848F99h,094857E89h,08C97907Fh,0A0A79394h + dd 0B69A9192h,080ACBDC0h,0A79A9378h,08C8F9085h,08C978684h,0AB9F8D74h,0978397B2h,089AEA496h + dd 09E7C7B6Eh,091999795h,0A4A1A590h,0C2B1B1ABh,0DBD6B1C6h,0CCCECED4h,0B0C0C7BDh,0C5AFC3C8h + dd 0C8C0BAC9h,09F8E8BB3h,0AEAB9689h,0B096C0B0h,080778F8Ah,07B9BA98Fh,0938E7986h,09DA59A8Dh + dd 09284859Bh,0979B9A87h,069796E91h,067776A60h,06A6B6B69h,0746D7461h,08A83786Bh,06B768987h + dd 0807B6E6Bh,07E727072h,086858C91h,0858B8389h,0655D5970h,079797970h,0676F707Fh,0B4968F66h + dd 07A7576BAh,0918E838Dh,085798084h,079848489h,070685463h,06C726F76h,072756258h,0797D6A75h + dd 0805A6B7Bh,0696E778Ah,084556B69h,09C8B767Bh,07E937F87h,08C8F7E6Eh,062576F73h,0686A6861h + dd 05B606E79h,06B5A546Fh,07B787F78h,0706D7672h,059636268h,06B806C65h,0537B817Fh,05F56404Bh + dd 058464D68h,048424C5Eh,0515A5649h,04E504652h,051544A53h,05C6A6455h,06377694Dh,087657E71h + dd 0ADA77E64h,0B29F98A7h,06F8FB8A4h,08A968960h,0797F8B8Eh,08C857170h,08CB68C72h,084999480h + dd 0BFB3A091h,0768FB8B9h,0A4AB9C84h,0A3957989h,081638698h,0AF929586h,0947B90B1h,0AA9EA49Bh + dd 0907E769Dh,0A49C9983h,09EB494A3h,0B8B89D90h,0D7D6BFB9h,0C3C7CCD6h,0C6CACDC7h,0BC9DC1B5h + dd 0C9C8BCBDh,0A9A3A6BCh,0B7B6A596h,0B1C0ADBBh,081767E79h,06392927Dh,095818376h,0B499A9B4h + dd 09E82808Fh,0AB8E9F9Eh,06D767CA5h,06F7C6B5Fh,07B736466h,079708176h,076826A64h,06D7D8D88h + dd 07A786D66h,07F787974h,0697E9097h,07CA27B6Ch,068656479h,0737B766Dh,05C566F76h,09E8D8660h + dd 06D7375A5h,0816A6275h,06373676Bh,07775776Ah,07C765F70h,0696C6D79h,0676E655Eh,06260706Ah + dd 07D846275h,062676F6Eh,06E585D63h,07B656C68h,0746C5A5Bh,07B747675h,06F696F72h,066747B6Dh + dd 071737279h,0675B5F6Dh,065525460h,04E4A5255h,041494D4Eh,049554546h,062606771h,04A445A4Ah + dd 05438456Eh,05B5A5961h,053534F45h,05360595Ah,0574D5454h,053606869h,058736957h,08569635Eh + dd 0A1A28C81h,0A19F9594h,07198AC9Dh,0A3826F65h,073868C88h,066716B6Ah,07D8D9276h,09E92A595h + dd 0AA9F9590h,07092C2ABh,094B3A66Ch,0A2988A8Dh,0A596A9A7h,0A0768E79h,09994A3B0h,0A4B2A7ABh + dd 0201D326Eh,0736B8548h,0949F987Bh,0DAB09B8Bh,0CBD8ACA3h,0C8CAC9CDh,0CBB9B0B7h,09E85C3B4h + dd 0B9CFB195h,0B8BCBCAAh,09CAEB6BCh,0A4B8BB9Ah,08E70708Ah,08EB3AB9Ah,0A8925C6Ch,0AFB5B091h + dd 0A58D8896h,0908E9C99h,07D667C8Bh,083857D73h,0867C5F67h,0766A8480h,07E977371h,072838E81h + dd 08682787Bh,08A76747Bh,06C869DA9h,086948076h,06A686983h,07583726Bh,07B677467h,094907B6Fh + dd 0757C8DA1h,0837C6172h,087876264h,0637F9487h,07B7B606Ch,06C737679h,0747B706Bh,066736D81h + dd 05D696579h,067636B74h,0696E6470h,0A1787B72h,0856B7071h,07F7E808Dh,07E7B868Eh,062868E7Eh + dd 06A697E78h,0655E645Fh,0676E565Bh,056555754h,0535F6B65h,05458424Fh,079576079h,0594A5671h + dd 050434646h,05B5A585Ah,04A53565Ch,056485243h,05C4B4B55h,065567367h,05C635963h,07F6F5763h + dd 090958060h,08C898788h,0718E838Fh,09C81786Ch,0707D7480h,082786F71h,0868A8472h,08A828F90h + dd 0A2A99696h,0738DA7B2h,095919E68h,0A5928991h,0A1A99DA1h,09089888Fh,0A9908AB2h,02D6E89A8h + dd 0211C1914h,01A222123h,02A1A1F1Ch,03041271Fh,0654D342Ch,0BCAB907Ch,0AEAEADB2h,0AD84BEC2h + dd 0AFB5BEBFh,0B0A9B2B1h,0A2A9B2B7h,0B1C3ADB0h,0ADA07A8Bh,09CB0AEC8h,0A1885A6Eh,0999D988Dh + dd 0ABA19595h,0957E9B9Eh,077797A8Eh,0878F8D7Ah,078746B77h,0746B6A76h,08E8F8184h,06C708987h + dd 0918E9484h,085767777h,07E929A96h,07D8D8F82h,06F857E77h,08681757Dh,07B7C737Fh,09190817Fh + dd 07569818Dh,0A2A07D84h,089938160h,086798F96h,076725E85h,078787277h,0847E836Ch,07C6A6C84h + dd 05B5A647Fh,0706A676Eh,07B7C8273h,0BFA75F73h,09C8776B9h,088747791h,07C7D768Bh,07881827Eh + dd 065707581h,0636B6561h,068635C59h,06C696161h,058556167h,05A636056h,0755C5C66h,05B615C6Ch + dd 05961545Ch,05F5C5C50h,06B51455Fh,065485A5Fh,075736A63h,06160747Ch,06E6C6C56h,077716A70h + dd 09D988878h,0818E8991h,0706F8282h,06A5D6D75h,07B83786Ch,0807A797Dh,089848180h,090858179h + dd 07077758Ch,080817F7Eh,090878081h,0847D8487h,08A8E8581h,0989D8681h,09B8F879Ah,01F24539Bh + dd 02726322Ch,0282A2C2Ah,029212528h,0403A403Ah,03735393Eh,02E2B343Dh,05D63553Ah,09B90B19Fh + dd 0A5AFA597h,08C8C8993h,08E948887h,0796E868Dh,06661616Ch,072796D76h,083726E6Ch,081767481h + dd 0918B868Ah,09C819084h,0706B788Ch,081847E6Ch,071776E74h,06C7C7263h,0697E8078h,077808F79h + dd 071789383h,061536372h,0676A7175h,07E7D6973h,06A726D78h,06C6D686Eh,06C616869h,07476676Eh + dd 075858C95h,0A6968783h,0A68C8982h,07A6A899Fh,0977F75A2h,07C776F83h,0747F846Eh,0746E7E73h + dd 05167636Fh,06B6A6257h,072787A66h,0B29B8C71h,09D816CACh,07D7E7E92h,079757A84h,0707B877Fh + dd 06E697A7Eh,05C6B575Fh,0615F565Ah,05D696867h,0615A5E60h,065665D5Dh,0706A6765h,05150566Dh + dd 05D5E6F68h,05A5C5C64h,076594B57h,05F635665h,05B615266h,06F5E6773h,07E6F645Ch,076748080h + dd 0A888867Eh,0A1A29EB1h,0A1A8B1A5h,068727E9Ch,0797E807Dh,078797C81h,07F8D9182h,098988F8Fh + dd 0ADAB8486h,091A1A8AEh,07C808A85h,0988C9183h,0A6B5B59Dh,0A2A49E9Fh,07892979Fh,01B282A41h + dd 02F292019h,02A323332h,01D232729h,0291E1B1Bh,0282E3731h,048383630h,030292A38h,0804C311Fh + dd 0ACB6AE9Fh,0ADA79C9Eh,097A7B1ACh,0B293A39Ch,0796D8E9Eh,08778757Dh,08697A49Bh,0958D988Fh + dd 0A79B8D98h,09BACBEA6h,07C79767Ah,0968F8677h,08D8A999Ah,09E9AACAAh,065859F96h,077738A8Dh + dd 0787B6E81h,0807A7570h,071687482h,09A96787Bh,06D67708Ah,05F6C766Eh,06F5C5F5Ch,08F7F7C7Ch + dd 06F89818Ch,07D83837Fh,087866A69h,050727F89h,08C7E6B5Ah,06E707180h,079857960h,07D6F8381h + dd 0647D6D78h,06F6F645Ch,08C896569h,0B0A0A28Ch,0907C7DB1h,095929CA2h,07C79708Bh,06A778B83h + dd 0647C7D78h,053586460h,06559515Ch,062696969h,0666B6B67h,064645A58h,070655560h,060606F7Bh + dd 073676165h,04E565E6Ch,069614A46h,0605E5B63h,0526E5F63h,0665C757Fh,085696268h,0908F8887h + dd 0AA908780h,0AFAB94A2h,0ABBAA7A8h,07A6B8DB8h,07D7C838Eh,083858888h,08A8D8B86h,0959D8E8Ch + dd 09695788Dh,08D979593h,088959384h,09886838Ch,08C999E93h,09CA69C90h,01D388598h,027202D23h + dd 0302E2E28h,026313635h,0302A2C29h,033262A2Eh,02D2D2E31h,032272F35h,02D343535h,0201D2338h + dd 0503E261Bh,0886E645Ah,0B0AD9A98h,0BEAEB7B3h,0936E9CB1h,0826B7A8Dh,07D82929Ah,08889927Eh + dd 097898688h,08D839A92h,07B808981h,07F958A7Ch,098837A7Bh,09CA4A5A0h,0778AA396h,06E768B81h + dd 068816F6Eh,06D6D7476h,067617770h,0797F8F6Bh,06A6F939Bh,0626B735Dh,06B687E6Ch,07D967672h + dd 067636976h,0847A7885h,087887488h,06C6B7883h,06A5F5B53h,0526A7B70h,0686C5C57h,0646F6E66h + dd 05757476Ch,06663605Ch,060706869h,0949D956Fh,080797C96h,079797C82h,076757B82h,0677D7F79h + dd 062697974h,04D555255h,0604F4A5Fh,047544E54h,04F4D4F4Bh,04E57544Ch,05F604B48h,0525A695Fh + dd 0706D6A5Dh,05D5A5F6Ah,0586D546Eh,065555154h,067615F68h,060666F6Fh,089787363h,091909389h + dd 0A8BA7C83h,0A19C9394h,0B4BEB49Eh,0666A84A4h,0887C8074h,088958D89h,09289848Bh,08E898C90h + dd 0838D8DABh,089949990h,09C97978Bh,094B29E9Fh,0A4A4A695h,0E3AEACA2h,0322E39C2h,0253D3232h + dd 02D30323Dh,02A291D2Dh,02535373Eh,02A26232Ah,08F613D40h,0717E9397h,041396676h,0210E1C19h + dd 0211A1F24h,0301E232Fh,09A6B352Fh,0AB8994BBh,0A880B9B4h,080817797h,08E7A9389h,0867A7A88h + dd 082807C79h,0877B7C82h,080717D89h,0858B8C7Dh,086929481h,0979E9687h,08888A58Bh,0807C7996h + dd 07B918563h,06E6F6773h,0676FA187h,09085877Bh,05F839599h,064647264h,0665B6459h,07464666Eh + dd 0A175757Bh,091A0A19Bh,07C8699A1h,0A0968D81h,0707A9579h,0677A7C75h,06E67776Ch,0615E4B70h + dd 06055616Ah,069626567h,0646E8070h,06064606Ch,06D615C69h,075677674h,08485836Ch,07477767Dh + dd 065727779h,071604B5Fh,06C7C6D66h,0776E7B79h,04C77897Ch,06B6A6458h,0475B5559h,0646B5B52h + dd 06B6D5E53h,0535B6666h,05A5D4E5Ch,069646660h,0605D5D5Fh,06A726B67h,07D6B7259h,086857A7Dh + dd 092968A98h,0A498A9A7h,08297A6A6h,07E71757Ah,07E89A699h,09E969F98h,09596928Ch,09D9EA9B0h + dd 0A99F8C9Fh,09EB0B9B8h,097919D9Bh,0AA97AE8Ah,09C958198h,090BABBA5h,03A37352Ch,033323033h + dd 022273035h,027171B19h,03852262Bh,0A87C5240h,0E3CFB6B4h,0C8CBD7DEh,06685BDCDh,0556C8B7Fh + dd 016112035h,0222C2D24h,02118252Ah,0B4748A64h,093947EA2h,0938874BFh,0767D9587h,06A7D788Fh + dd 06A687E7Fh,083767272h,07F817F81h,07B938C7Fh,097878889h,08C89848Dh,06F949F82h,0797F7C85h + dd 073837079h,073655C5Dh,07470888Fh,08187767Bh,0947A827Ch,0696485A1h,0757E6D74h,098976C6Dh + dd 0B08A798Ch,0A39AB7BBh,0B28798A7h,0A28695A6h,07C829687h,07F7A6B6Fh,06C836E6Ah,0636D6382h + dd 069696C6Ch,06368706Fh,060607163h,071845C6Eh,0766D6977h,074687779h,076727971h,073777275h + dd 065787779h,07874555Ah,05F646770h,07D686E6Ah,059848175h,0505D695Dh,05C5F535Eh,05C4F4E63h + dd 06F6A524Fh,05C626965h,0514C5261h,05255734Ch,04E4F535Ch,067635754h,06E72745Fh,06B7C7E73h + dd 083908E7Fh,0A292938Ch,073808C8Fh,05D676864h,0807A8F7Eh,083948C86h,083858B89h,08D878E89h + dd 07578738Eh,084877C74h,070807789h,06A6F8689h,092928376h,00D529D8Bh,037383E25h,02B272E30h + dd 01E1D2820h,03D2C2D0Ch,0A3B56C4Eh,0CFE1D0C2h,0CECCC6CBh,0999AA6BBh,0B29B9799h,0AE9BA497h + dd 0619DA29Fh,01E19212Ah,0212F2B30h,09A705B37h,0A8899DA3h,094858B93h,07F7A897Fh,08F8A7878h + dd 075707479h,08D8C8981h,09273767Fh,079777F83h,07A7F848Ah,0727B7A72h,06F93917Ch,064726E70h + dd 0696A6C60h,07282726Dh,0746D6B6Fh,0767A646Eh,06B6B616Ah,06D6A7567h,06668717Bh,0918D7D66h + dd 0A88C7385h,09CACC4B1h,0A2ABA8A5h,085A1A8A4h,0817F8E80h,0727D7F7Ch,077907876h,064625D71h + dd 064676867h,068686865h,0716C716Ah,084707383h,091999BA4h,07469747Ch,0726E6B71h,073777778h + dd 0676B7779h,066695D6Eh,061676E6Fh,06B686967h,0476A7C6Fh,057636A5Ah,05A595165h,072655352h + dd 0846A4C56h,060758380h,073656461h,07361645Fh,05E5D6684h,060586062h,06C64676Bh,076727A7Eh + dd 0A0958E79h,09DA39194h,079919D9Ch,083939479h,0A38C6D6Fh,07D818798h,08F847873h,0A69EABA2h + dd 07C878BABh,089959082h,09297A483h,09096938Bh,0A890949Eh,0213A91ABh,034362B3Eh,0592B2A2Eh + dd 09C7A4168h,08D9B8A60h,0B3C2C0A1h,0B5B7BDC0h,0BAC9C1B6h,0B49C97A1h,0AFADB1C3h,0A392A6AEh + dd 0CE9F8DB0h,05B696DAEh,01F20362Dh,089421513h,090A0B0AEh,07A718A7Dh,0675A7178h,06463596Ah + dd 0625C575Ah,08B7B756Fh,0736F7B89h,07A827C70h,07A7A8079h,083878279h,08B817B80h,06C777C85h + dd 07973747Eh,06A615972h,074737489h,0906F6C67h,07B817E8Fh,07F887872h,074707272h,0918C7463h + dd 0B2887E8Fh,0A5B4C0B8h,0B6CFBDACh,09594A8B5h,07B799197h,079898B7Bh,0837A9288h,06C5B5F7Dh + dd 0615C6168h,05F686766h,06962695Ch,09680767Ah,09D89789Ah,0867B9AA2h,0736F6F83h,073777275h + dd 0656B7779h,06964576Bh,06F7B776Fh,06F67686Bh,051717D71h,0656A6A5Dh,066675764h,0666B6268h + dd 0735C5270h,064737772h,06B5F5F63h,0606D776Ah,0442B5C76h,062544048h,069515C63h,07D788375h + dd 0A46D8D89h,0A297959Dh,0867A8F9Ah,0ADB2BC7Ch,0967C8C7Eh,0696E8295h,06D766E64h,0B4BBA792h + dd 095959A97h,09C998681h,08D7C7C84h,0A0929467h,0A4B590BEh,0197C9FBEh,036333337h,09C4C1D2Eh + dd 09FA29DA2h,0AFA46C68h,0AFD2C3C1h,0E3E1DFC8h,0C3CCD4C4h,0BFB8A1ABh,0B8C0BBBAh,0AC9AA3BEh + dd 0D1BFB3C9h,080594DB7h,02B398BBEh,01B251016h,0B6D1BB5Ah,07E728AABh,0756F7776h,060636A73h + dd 065604952h,07D74786Fh,0717C6D75h,07A8B7A5Fh,079866F72h,077797D7Ah,09490807Dh,08E9A9692h + dd 0886A6782h,072797388h,082808083h,0906C7980h,07074809Ch,08689827Bh,077889A86h,076866F84h + dd 0996A767Ch,095A48BC6h,08BA6CFB9h,0A9A4A6A8h,07A656680h,08A7B7D8Bh,0686F747Ah,06C586579h + dd 069676972h,08275696Eh,07161706Dh,06F786275h,075747469h,07D7B7C79h,073726D7Ch,06D697877h + dd 06B787978h,071684C77h,076737876h,06F5E6977h,04B687758h,04F606557h,0807B5E4Dh,06B606058h + dd 075654D6Fh,0646D6F63h,06C696F68h,067636064h,04F3C5B8Ah,0504F524Eh,0675A4E4Eh,06A63777Fh + dd 097809781h,0ABB0B7A4h,0958C889Ch,0A59FAB78h,07F7FA691h,06C70767Ah,0815D6969h,078827C7Ch + dd 0B7968E8Dh,0959DA5B0h,0A2A38387h,0A47FB4A0h,0AFC5B6C5h,0177E99AFh,0343A3435h,0B5852C17h + dd 0818DABA9h,08B7A7976h,0B1C3A7A6h,0CBC7B6ACh,0E5E3BAA2h,0A3B7C4CAh,0B69CAE9Dh,0A08DB2E2h + dd 09FC8B3A1h,01F2D4383h,08B76452Dh,018142770h,0BD8F251Ah,05C7BBAC0h,07B6E6866h,0645D6977h + dd 05D605358h,0766E8174h,072736D77h,08F6E6461h,07071697Fh,0757A7A7Ah,093866E6Bh,0808A8883h + dd 08C86746Fh,07664547Dh,07A676473h,0847A938Eh,0706D748Dh,086988F7Ch,07C718E7Ch,0685D717Dh + dd 06C7C6F79h,076835E6Ch,08064777Eh,076757686h,0666A6C69h,06083826Ah,06E706362h,0655F6A72h + dd 062616160h,063616464h,0575D6062h,05655565Dh,065565450h,062575A69h,07B7C7174h,07586787Ah + dd 06C808177h,0566F5B75h,043455057h,04B373D49h,06C675148h,05C656D67h,065536B63h,0605E6564h + dd 071594A7Eh,0696F6F64h,071747C75h,0675C5E5Fh,05D5B6881h,04A535D4Fh,067624D47h,06974677Dh + dd 0758F9A79h,0AA9AA68Bh,0A09993B3h,0ACA7AF7Eh,08E94A8A6h,0797D8085h,09A917975h,08988828Dh + dd 0B89F9286h,097ABABA9h,09BA0928Ah,08F89938Ch,0AEA39CAEh,02081B6AFh,0303A3F3Ah,0AC975717h + dd 08FB5B6A2h,0897F8781h,0B2AFC69Fh,0DDCEA99Eh,0F2D9D3C9h,0B4BDC5DAh,0C4C0AEABh,0C49ECCF1h + dd 0BEBAB9B7h,0596F79ACh,0A4AB8247h,0407EB79Dh,07E390616h,062A5BE9Fh,0695D646Dh,060585E68h + dd 05D655E5Dh,0746D877Ah,0736B7478h,06E736867h,06D7A696Dh,06B68696Dh,0847C7072h,0868C898Ah + dd 08F8C7A73h,0616C677Bh,095806A77h,0807C90A3h,06F70748Bh,0A5967E72h,094746E90h,0858A8087h + dd 0838E8180h,09D7B8C9Ch,089967C89h,0587B7286h,0616B9478h,0816C6C6Dh,074796870h,07A7F8A8Ah + dd 0726C7068h,06C737E7Dh,075786D79h,079717E89h,06A595B6Dh,091798688h,07F847F97h,07C747B7Eh + dd 07E949390h,0716D6072h,05D4D5C6Dh,05C575962h,07D826D54h,05C5D7081h,0675E5B5Bh,06D626561h + dd 0765D4A54h,061636A71h,07676756Bh,05F5A6A64h,061535E66h,050565853h,06162514Dh,06A8A6465h + dd 06B92906Dh,08D818480h,08F969497h,09E97A774h,09B9994A0h,0878B9194h,093957C7Fh,097938788h + dd 0BCA59786h,088ADB4ADh,0708B9678h,08D918067h,0AF7A809Fh,01E78D1B4h,029343C34h,0928C893Dh + dd 0848E9B8Fh,0809A988Ch,0A7BDAC77h,0BAC5B1A7h,0E7DCE3CCh,0BFC1BFCFh,0C7D3BCCBh,0C3A6E4EEh + dd 0CFE7D4A6h,0A4B3B7BDh,03F414084h,07E93614Ch,003033556h,068888336h,069706570h,07068726Dh + dd 0706D6F6Bh,07A7F7771h,080747A75h,07D7E8668h,06C74717Ah,057565B68h,0928B745Eh,08989898Dh + dd 08D897974h,0667D7E81h,072747C86h,07F7B7878h,0827C7986h,0879A9585h,094838788h,06D677C8Ah + dd 091937E6Bh,0BE8D9F9Dh,0A095838Fh,0749590A1h,073659884h,08A7C9395h,0808C7689h,08486939Ah + dd 0806A7875h,087868796h,07A64667Fh,0839BA191h,06D694A59h,0898F9F7Eh,07E7D7482h,0837D7E7Eh + dd 072797E8Dh,07A707A73h,06263707Bh,060535966h,0636D6C5Dh,066607576h,067666B79h,063627176h + dd 05E5E604Fh,061616D63h,0695E596Ch,04A3D4D6Dh,05046524Ah,053535351h,065634956h,05E7E5C5Dh + dd 057677563h,05D605E62h,0836F6E71h,079778A7Fh,0818F7D89h,09188908Dh,0796D7881h,07F80717Ah + dd 083808C74h,07E8E938Eh,0859FA37Eh,07A73868Fh,0AE928B96h,0285CCABBh,026303432h,0ABAEA467h + dd 0A58D8B85h,0D0B8B4B5h,0B8BCBAEAh,0BCC2BEB5h,0BABCB6C0h,0ACACA7A7h,0C2B3B2B9h,0B198A1B6h + dd 0A9AEB7B9h,0A6AF929Eh,08F8893A1h,077857D89h,02E506D76h,057330912h,066736983h,061595E60h + dd 0645E5460h,07D866E61h,08F757E77h,0757C8572h,06B697273h,05F5B667Ah,07979706Ah,06C676E77h + dd 096897D66h,071767288h,05B616C6Eh,07C746E69h,07D77787Bh,07776887Fh,07A786972h,06D826971h + dd 0AB817575h,09E8DAEB7h,0A89D887Dh,0778A8D98h,0807B8873h,0796A6D7Ch,08D908A97h,07C788DAEh + dd 07D5F6F7Eh,09F967E8Ch,07C61737Fh,06F7B7C86h,0747D475Ah,07C9A9A70h,07C7E8471h,0777A837Bh + dd 071778783h,06E606E6Dh,064646B78h,057535B65h,05C695D53h,06D6A6F66h,06756636Fh,0696B6F6Bh + dd 059556154h,0786B6F66h,066656769h,05A616864h,053535E56h,0605A5A57h,06B666C73h,0526D726Fh + dd 0746B5757h,071827C77h,090835F5Dh,08F96A5ABh,09CA78B96h,0C7A5B7BAh,08C6BA0C7h,09D9F9F8Ah + dd 09E7D7995h,0B09E9AA3h,093A1ACC2h,0A396A39Bh,0D6B3BFB5h,03849C0B6h,056323337h,0D4CEB697h + dd 0B9D2C4C2h,0E6FAF0C1h,0C5C8CDEEh,0A2C3C9D2h,0CEC4A9B9h,0E6BEC8D9h,0CDB0BCFAh,0D2D1DBCFh + dd 0D3D9CDCBh,0B7C5A1B9h,0BABBB1BFh,0ADB5A7A4h,08E7F98A9h,002357595h,056433A16h,05B605C63h + dd 057525C5Ah,07B7D7667h,089808880h,08B788489h,06B6D7357h,054717178h,0816A6D6Bh,078707F88h + dd 07869736Dh,0717C7475h,07984788Ch,07F7A6E76h,0B9C29060h,089798583h,06A62928Ch,084807778h + dd 091847886h,096AEA786h,09D8F786Eh,08490999Ch,069787169h,0876A5962h,0A992867Ah,06E788A95h + dd 08098917Dh,08B73797Ch,089847695h,067677D80h,08D735D68h,08B8F7F8Bh,089827C76h,07C828490h + dd 07D8B8986h,074656C73h,0656C6162h,0657A7C75h,07373686Bh,07E5A697Dh,06560677Ah,071717170h + dd 04D4F594Fh,06966755Ah,06F67657Dh,05B726064h,067636959h,070666A6Eh,071879B8Dh,073666462h + dd 062657C86h,06B766F65h,09F908975h,0868B96A2h,08A957E8Ch,0B5A4C0B5h,075769490h,0A89C8C77h + dd 0A389829Dh,0A5A2ABADh,0B6B2A39Dh,0BFA6B1BFh,0CBD8DDD3h,03B3EA5CAh,0762F3432h,0C6BFB893h + dd 0C8B6BDD0h,0D5C1B8C7h,0D6CDC7DFh,0D9CAC4E5h,0EBE9D6F2h,0E5E2DCE4h,09CB6C6DEh,0E0D8D0BCh + dd 0D4DAC9BFh,0CCD6B2C5h,0AFCAB7DBh,0BFB6A8A8h,0A28DA3BEh,0639EAEB7h,0050F0E2Fh,054411609h + dd 05E5E5561h,069766B5Eh,0866F837Bh,09F7C7F8Bh,0687CBCADh,077AB8670h,076587986h,06E6D7E83h + dd 0566F6A56h,06E645854h,07980878Fh,07B708277h,09DAAA193h,08F777F7Eh,0747D878Dh,08779858Ch + dd 07C836662h,0868F8777h,088747B70h,07C796F7Ah,067645E62h,07964545Ch,08E84867Fh,0757C807Bh + dd 0837A7473h,07D908A82h,060837A6Fh,0484E645Ah,07E655A5Ch,07C7D6D7Bh,07B7E7F76h,07F848493h + dd 063728B8Ah,05F5F6865h,05B56756Bh,06D616762h,06A6A6868h,06A616973h,06C636268h,0645A585Ch + dd 04B4A554Bh,061617157h,06C6C8081h,069715560h,0756F756Ch,07C736D75h,089949588h,0A29B8C83h + dd 06E727A9Ah,08483756Bh,09B87896Ch,08D8B8E8Fh,074918E9Ch,098A2AB8Eh,06F99A8A6h,092827878h + dd 097969478h,0B1AAA4A7h,0B9C5AD9Ch,0B59DAFA4h,0BBC6B3B3h,03E2FA4BCh,09552302Fh,0D3B2B28Ah + dd 0BEE1DEE5h,0EADEAC95h,0EFFAE7F9h,0F9F4E5F1h,0E9FAF7F9h,0DCFADECAh,0A3AEA2C1h,0F6D5B2ACh + dd 0D8D8DDEBh,0C9D2B5CFh,0ACC4C5DBh,0C4BCB9B3h,09989A8BBh,0A8A6AAAEh,03A6881A0h,00717251Fh + dd 05556300Ch,06F756551h,08A7A8278h,06E82847Eh,07F80879Fh,0778E7D80h,086677383h,06E758787h + dd 05B525578h,0806F6078h,080819087h,09681737Dh,0B5A09991h,09F7C6F8Fh,0646E8095h,096AF9D83h + dd 082818F81h,0727F92A1h,07373876Fh,06963879Ah,058636769h,073766452h,07B777B74h,06A666B72h + dd 0817D6A5Bh,074858A7Dh,06E807C8Ch,05A646082h,06B735D60h,069717D69h,06D717A6Fh,07A7D807Dh + dd 0707C8784h,06760666Ah,07E70645Ch,07E706C73h,06C757C6Ah,05B75776Bh,0675F5957h,066646465h + dd 05853574Dh,08D796C65h,07869766Eh,085857878h,087878880h,07D7A727Fh,08D8D7F7Bh,094AA908Eh + dd 07882757Ah,08C867B70h,08191A489h,089879987h,070828E9Eh,08F9C856Fh,0C3AFB2A3h,06588C9BCh + dd 0B89A8D92h,0B6ABB5C8h,0A2AC9FACh,0C6ADA2A0h,0C39FB9A7h,03C296419h,0C5722D27h,0D9B2AA9Fh + dd 091CCCCC7h,0EBEFFABDh,0F9EEE9D8h,0FAFAFAFAh,0D2E5E7F4h,0F6FAEFE0h,092D4E0D5h,0F6D2CA8Fh + dd 0D1E1EAFAh,0BCC3B3C5h,0C9D4CDCDh,0BBB5BBC0h,0868AB2AAh,0B09E7788h,094B37A83h,03B2E6173h + dd 02218313Dh,0584B4433h,0837D7760h,078819B80h,0789BA6BBh,0947E7E8Eh,0796D728Fh,068718686h + dd 0586E6664h,072756461h,096917E8Eh,08E7A7A80h,089A6A99Bh,09D716E6Ch,06B7C8C99h,07367A172h + dd 07579B2AAh,07CA7A79Eh,0887C7C66h,07C8B7C8Ah,068666978h,067675E5Ah,0706D736Bh,069737977h + dd 07D736E75h,0788A8173h,06E76708Ah,06E7C686Ch,06B675D5Dh,068666666h,07D686369h,07477787Ah + dd 065707F7Dh,06F68696Dh,0655B6075h,0737D645Bh,06F737A7Fh,05F556472h,064696B6Ch,0656F736Eh + dd 062746B69h,07B7D7159h,0767D7F8Bh,072716D72h,0747A7A76h,06C796B6Fh,07E7B796Fh,06E768883h + dd 078856974h,07D868678h,07E8A7C80h,0747A7977h,06B6D6C75h,07781787Fh,09E8F8489h,086A2A2AEh + dd 0B18E8B84h,0B4BCAFACh,0B4B4A6A1h,0CBBFBCABh,093CDCDD3h,02F395327h,0B6903B23h,0A1AEACA1h + dd 0BE91D5C9h,0FAF6F7F6h,0FAFAFAFAh,0FAFAFAFAh,0D1E0ECF9h,0EDF1DCD1h,09CB6C9D5h,0AC98A196h + dd 0B0A9AAB7h,0908994A5h,0B5BBC09Ch,0B7B6AAB0h,0958F9BA0h,096AA929Ah,0829D736Eh,087908377h + dd 05E65727Dh,010062836h,020240C10h,04D56482Bh,0859C6255h,07B757C84h,0807C767Ah,072708497h + dd 08B878679h,07C777071h,07B80707Ch,0977C6272h,07E877F8Dh,07E696577h,0736D737Fh,05D799672h + dd 07076A473h,06870837Fh,0886D6B77h,07C918A87h,071686C78h,08A6C706Eh,0937B798Ch,07E7D8776h + dd 06A7C759Bh,081857161h,06E727C7Bh,066818C7Ch,06F717158h,0675C6268h,079735F6Ch,0787D7D76h + dd 061718484h,071775875h,06D56656Bh,0786F6167h,0767F8075h,077757A79h,073777773h,077788480h + dd 0825E4C6Bh,06A6B667Fh,0474D5452h,05A5A5A65h,060626B5Ah,0646C6664h,07C846D6Eh,0746F9C87h + dd 084878380h,0918B8684h,07F8F7880h,07A767E7Ch,080878A8Ah,07C6D7486h,077707478h,07B8F7F83h + dd 09286A497h,09396878Eh,09D999178h,0A69EBD9Ah,072A88C9Eh,0433D6247h,0A6A08229h,0B7D3BBC1h + dd 0F5B28ED4h,0FAFAF5FAh,0FAFAFAFAh,0FAFAFAFAh,0D3D9E1F0h,0E5E0D4D0h,0C2CACFD9h,09D9FA7CCh + dd 0AFB8C19Fh,0C2BCB7B7h,0B0ADABB4h,09AA3AAB7h,0A497A2A7h,07FA5A8ACh,07B929387h,08A7B7570h + dd 07C79828Eh,03E54808Eh,029221A1Bh,03B3C262Dh,0A5865F76h,0899C9792h,070727576h,06D71647Eh + dd 0958F8588h,0787F7E78h,070847C70h,094887878h,07F86737Fh,084758284h,0929D7F9Bh,091968080h + dd 07987AD8Ah,084788A84h,081858084h,080858A8Ah,06A676D7Dh,075657061h,076837971h,07A7F7B64h + dd 06272626Eh,06E786E5Ch,0626E7F78h,06B778F74h,094959388h,0858A8D91h,081856F80h,079829080h + dd 071647378h,07F7E5D7Ah,0535C827Fh,07E6F5B57h,071747D7Ah,070766664h,06E5B5668h,079696864h + dd 0746C6260h,06A7C807Fh,05C5C5F49h,08A807D62h,07A6D7D90h,05D5B8091h,06F796255h,088668C77h + dd 08E7F7672h,08C84848Dh,0888C9B8Eh,0646D7175h,07F787571h,06A555967h,06A646F63h,065595B97h + dd 09D86948Ch,0877D86A0h,086AAB375h,0957D8A99h,04D9F89ACh,0273D272Fh,097A37E0Eh,0D6BED3C2h + dd 0FAF89789h,0FAFAFAFAh,0FAFAFAFAh,0FAFAFAFAh,0D7D7DFFAh,0FAF6E5D8h,0C7DCF1FAh,0B6A8C4B3h + dd 0B7BEB78Ah,0D4C5AEB8h,0CAD3CBBDh,099A7BCB7h,0B9C0CCC6h,0A49F9FB3h,07B8198AAh,09791857Eh + dd 072899F9Bh,033948880h,01A1B280Bh,0462B1E1Eh,0748F7A52h,079768E85h,07A757C91h,07285736Dh + dd 083648A7Bh,084A2CBBFh,088B1A279h,09A898093h,099B6A897h,0858E908Ch,099999A82h,093838C94h + dd 08377988Fh,08D7B7279h,07573716Fh,0656A7577h,0665E5D65h,06E758266h,08F65627Dh,085897A6Dh + dd 06577727Dh,06A666367h,063726E6Bh,06E635C5Dh,0847F7C87h,0727E8B8Ah,08688847Dh,086949187h + dd 072627983h,06A666C7Eh,07161776Fh,07E74666Dh,058636F72h,0484D4B50h,0554C4448h,0686D7D86h + dd 0625F8178h,06F708689h,07B68867Bh,084858A7Bh,054587781h,072685A5Ch,06E757752h,0B1797B71h + dd 081716D6Dh,08A797282h,07C719D76h,07A816D66h,089616376h,045404353h,05A749467h,089916352h + dd 0997D7783h,0835D799Ch,0A0B0B18Bh,08885807Ah,01E7D96A4h,02B37152Fh,0B4BFCA35h,098DFE6CEh + dd 0FAFAE266h,0FAFAFAFAh,0FAFAFAFAh,0F7FAFAFAh,0E7E0DEF6h,0FAFAF1E9h,0DBF9FAFAh,0CDB3C3E2h + dd 09AABAA9Ah,0D7B3989Ah,0B6B8C3BEh,0A9C4B9B8h,0A7A3ABB6h,0C0C5A6B1h,07A827D9Bh,09A877E79h + dd 0867E9CA3h,093A37A98h,026221D4Dh,01A253123h,06E4F2632h,08B807B6Bh,070808D8Ah,06E6E6D68h + dd 0B37C8878h,0ACB2ACBDh,078718EA4h,0857C8673h,081AA9A8Dh,08C91826Fh,09D98888Bh,0787F8C9Bh + dd 06C7A947Fh,0897E937Ch,076708A88h,084857F74h,07D6E7483h,081787469h,089779A8Eh,067727381h + dd 06A6E6971h,07B63617Bh,070797A68h,06D696471h,07C7A7883h,077787978h,08074717Ah,0757A7F7Dh + dd 0667A837Fh,076667663h,066716871h,06B7E6A67h,07174756Ah,052526C79h,072736954h,088837C64h + dd 0695C6764h,084707987h,074877F86h,055636A59h,04B4A4A54h,04B554B48h,0707C734Eh,0876B646Eh + dd 07779797Ch,08072787Bh,077868B87h,06376746Ch,0567D6571h,05E4A7577h,04A616F68h,0615D7559h + dd 0905D6879h,094768F9Ah,0AF9D947Eh,0768085A2h,01E83A68Fh,0142D2B42h,0AEA4BE63h,084D5E9CCh + dd 0FAF9F8C5h,0F3F0FAFAh,0EFF9FAFAh,0FAFAF4F8h,0E4D0D5FAh,0FAFAF8EBh,0F8FAF2F0h,0E7DBE4E8h + dd 0A4B093C3h,0CCD8C3B3h,0B5ACC0E9h,0BFBBBCB3h,09E9097AFh,0B8A1B09Bh,08D9399A0h,07F8D6982h + dd 0727E9996h,08A9C7881h,022359DB1h,02D272826h,031302728h,0818B5A5Ah,07F7D8573h,090938D7Bh + dd 0A0997C6Dh,08F808BADh,0838278A0h,084738C83h,0827C7990h,0767E8A8Ah,0838E8F80h,0A7ACAB90h + dd 0A5BFA6A4h,0BA9C84ABh,08FA194A4h,0A5A59E9Fh,0798A919Dh,0818C8077h,07E848F83h,06A807177h + dd 08D66746Ch,0565C5F85h,0717C755Fh,06E697875h,08697877Dh,08789878Ch,08E927E82h,078749081h + dd 06E697786h,07774686Ch,05C59635Ah,062766666h,05C6B6972h,03D525B59h,05E664A4Fh,0826E777Ah + dd 07A5E5461h,06D756D75h,07579776Ah,04B616F73h,04A43414Dh,05A504F4Eh,0524E535Eh,076594C55h + dd 0767C777Dh,070778384h,0717B8B73h,089717672h,03B475670h,056617F79h,070706950h,08E838D56h + dd 08C6C92A7h,08C88989Fh,0B68C7978h,0799CA8A5h,0165BC991h,0402F3946h,0CFB9D8A7h,095A3E6EAh + dd 0FAFAF3FAh,0F9DAF6FAh,0F9FAFAFAh,0FAFAFAFAh,0DBD7D2F0h,0FAFAF6E2h,0EDFAFAF3h,0C9CCE7F3h + dd 0BECCC1BCh,0B9BBB9CBh,0CAC4B2AEh,0C7D9D2B8h,09BABB7C8h,095A5BF92h,0A293ACA2h,0AA9B7F91h + dd 07B8E939Fh,0899C998Dh,07E9EBEA7h,0272A1D25h,0282F2A27h,05239132Ah,08E99928Ah,0B6BEABA7h + dd 0A78C619Ch,08D8D9194h,08F9E9795h,07B6D8880h,097948B8Bh,082848289h,07F878F86h,093A59D89h + dd 0809A9E8Fh,0B391999Fh,08CA58CA4h,0A5959A9Bh,084958988h,08F817F78h,093999D92h,06171708Dh + dd 087746E5Ch,05D6B6B87h,06C746B59h,06760816Ch,0818D7C83h,088878289h,08B848275h,075777F83h + dd 073817684h,05C56555Eh,050685252h,0646E5456h,06E675262h,043585358h,06D68524Ah,078878192h + dd 07268656Ah,0827C7372h,0666C6B8Bh,0777F7D90h,06F65657Bh,07B777473h,069777D81h,0746E7970h + dd 059636F81h,06661766Ch,06D6F5F65h,06C706F73h,068625D6Eh,0808A7681h,093A09F88h,08F8F858Bh + dd 072777F87h,08F878B82h,070666F78h,08D8C937Ch,04C4DC3AAh,05B243C55h,0BCB5BCB5h,0D37F9ECAh + dd 0FAFAD0D4h,0FAF7F1F6h,0F3DBF8FAh,0FAE8F6F3h,0D5D1D7E6h,0FAEBD1D3h,0F6FAFAFAh,0E3DEE8EDh + dd 0D9D2DFC2h,0949EB4C5h,094999798h,0BCB8959Ah,0A7AAB1B2h,09FA8A697h,08785A797h,091797283h + dd 094838086h,097918984h,0AB9E9B85h,025162689h,02C35362Fh,01F293636h,087958A44h,0767C889Eh + dd 08D6D6783h,07F85857Ch,089897D91h,08372808Eh,08B867A89h,094716679h,07A7C758Fh,08D9A9786h + dd 0A0A2958Bh,0BBAFB3B1h,076797D9Fh,08CAEB094h,080828598h,08F707F72h,0809D9B8Bh,055608B83h + dd 08D907258h,05C565C88h,07A81696Dh,06E546B6Dh,07F8C7B83h,08E8C8487h,08E898B89h,07876838Fh + dd 0616F7787h,07B6A655Dh,0646B5260h,08278597Ah,05F68607Ah,04E534C50h,067595647h,0818C7885h + dd 0616D7157h,0837A686Bh,09A746E6Dh,0878A807Ah,0857E7A81h,080898587h,06C6A7064h,072887677h + dd 05B687D84h,05D6B8474h,072616957h,08973656Eh,0636B5D5Bh,08CB08784h,08C78727Dh,0717E8D7Dh + dd 0968C667Dh,08B768097h,05B6D5B62h,0946E7C77h,04E2C9CA2h,07E26383Fh,0BDD0D6C7h,0F0967CB7h + dd 0FAF9F8B4h,0FAFAF4F4h,0F4E9D2ECh,0FAFAFAF9h,0BFD9F4F3h,0FAF3D6C2h,0FAFAFAFAh,0EDEDF9FAh + dd 0EFD4EAE2h,0BF9BB9D3h,096AFA99Ah,0A08F9892h,0C0A3A99Bh,090A08EA5h,07B9393A8h,080888499h + dd 098937E7Dh,0978BB092h,09C859F9Ah,018338BA2h,02B2E322Ah,037262827h,08C702A25h,07A8FB09Bh + dd 092686564h,0848A9387h,07B92AA9Ch,08E76727Fh,087867B82h,0AE866F78h,08F989CB1h,09092938Ch + dd 0A9919792h,0A6AA9194h,06C6E8C90h,066829384h,07D8D977Dh,098709679h,0828B8697h,0615C798Bh + dd 0698E715Ah,075664E64h,06F6F7087h,0977A8279h,081958486h,0837F8586h,080857D95h,072737E87h + dd 0797F7180h,07370817Eh,075666869h,06C6E7A74h,05577777Fh,05A4E575Bh,07B5F6143h,093928A90h + dd 06163AD71h,07C59695Ah,0687B716Ah,0887E5D77h,073807D77h,077707274h,070668B8Bh,075586172h + dd 063777E99h,069608079h,070705A5Dh,05E81667Bh,081807465h,082768375h,06E7A7F71h,08777857Fh + dd 096777D8Ch,0978387AAh,08482747Fh,08A8D7981h,06126959Fh,0A8242E5Ah,0B7C3EBD8h,0B0EA759Eh + dd 0F6FAF8D7h,0E2E3F6FAh,0FAF4E5C7h,0F7FAF8F6h,0B9BADBF8h,0FAFAFAD5h,0FAFAFAFAh,0FAFAFAFAh + dd 0D1E1EAFAh,0CED8C9BFh,0B4A0A3BDh,095919AB0h,0DEA89296h,08D809098h,0AB9D7577h,08D7C928Ah + dd 085847183h,07F78787Eh,08E809095h,02E7580A3h,02D2F291Eh,0222B3131h,06B212B2Ch,08085B3ADh + dd 0966E7269h,08A8A929Bh,0AEA493CAh,074786F77h,076738E80h,0A2776876h,08B91BC98h,0988D8D9Dh + dd 083807576h,09F957979h,08D91879Ah,07374877Ch,07E878F83h,080827F7Eh,07B7F827Fh,0626F607Ah + dd 0504D4E55h,073525451h,073576169h,07C746470h,0897E746Dh,07E7F8689h,08B887E82h,0747A8487h + dd 07A888080h,07B837B81h,0727C7C7Dh,0626B7874h,069757C74h,054464A5Bh,074665E61h,07F7E7881h + dd 065527181h,079817E48h,0947F798Dh,075787772h,0A07A7F7Bh,0666E7D79h,072718281h,0757D817Bh + dd 080767478h,0636D727Fh,06C755C7Dh,077867881h,09495746Eh,0816A6D72h,075717173h,087818278h + dd 088836184h,0757E8374h,0857E7569h,09896808Dh,047277A93h,0C04B2346h,0BFD0E2D2h,0C6CDAC7Fh + dd 0ECF1FAFAh,0C6E1ECEDh,0FAEEFAE7h,0EAEEF5F5h,0E8CAA9B3h,0FAFAFAF6h,0FAFAFAFAh,0F0FAF7F9h + dd 0E9F6F6F6h,0E5C7B2D0h,0B7AAAFC7h,0ACA7ABBDh,0DEAB8C9Bh,08594A1A6h,09B9F837Bh,089817B79h + dd 07A7E7C85h,08A847E74h,0939BA7A5h,0807F6FA9h,01E1E1F44h,023242421h,0313C2A2Ah,08C82BF64h + dd 076667F91h,081837980h,091A2978Fh,07D696A74h,086A56E89h,09B716D5Bh,08C95AD9Dh,08A8A8B94h + dd 088717183h,0A4AD9790h,0A1A29FAAh,08FA3A194h,0596F909Ah,09281695Bh,071757C80h,071836C72h + dd 058677985h,07E5E6B5Dh,086657482h,09D919490h,08D8682A0h,0858C8B8Ah,08D907882h,08A918388h + dd 0838C9292h,0856F6680h,07F74747Bh,0757B7E7Ah,068786B6Bh,0726E726Ah,09188796Dh,07D848591h + dd 06A646A54h,08F919476h,073706798h,0898F8681h,0AE8A9F81h,05280AA94h,0A6939582h,0756F6D6Eh + dd 07E837472h,073768B8Bh,0787B648Bh,0767A7780h,08E937074h,07468726Eh,0786D686Ch,07C6F6E82h + dd 07472747Bh,070868476h,07569716Dh,097948E80h,03B436589h,0BF6B2149h,0A9D7CCD2h,0E09DB077h + dd 0FAEAF3FAh,0D2C4DFFAh,0ECFAFAFAh,097CCF1EFh,0F9FADDA7h,0FAFAFAFAh,0FAFAF9FAh,0F1FAF9FAh + dd 0EBEFEAE0h,0C8C4DEECh,0B0B2B6D9h,0B6B3B9B5h,0D1A988A3h,095AABDBBh,0A3A88E8Fh,08B8A838Bh + dd 06C6C6C79h,0A18A786Ch,0848D9097h,08B776A7Eh,01A0C3486h,01E20211Fh,03B28201Fh,082764231h + dd 0796C687Bh,0858B6174h,05F6D807Fh,088727A6Dh,07D907E8Fh,09C7C7E75h,099A2B6B3h,0A2A79D9Ch + dd 082738DA8h,0A4917F81h,09CAC87ADh,09B928F92h,0616E8F9Dh,075695E61h,07C746C6Ah,0737F6C77h + dd 05B636464h,076555952h,08E6F808Ah,09480949Bh,09796939Eh,0898C8D8Fh,07F7C858Ch,0858E8E85h + dd 0938D8A8Dh,078706B91h,078777578h,0807A7A74h,06E818D81h,0757D897Eh,082817E79h,07E848490h + dd 04F606758h,06D7A6555h,06B7A5C6Fh,080807465h,06F6B6F7Eh,04F848278h,0A3A98581h,066646E80h + dd 06F5D5C52h,07C737579h,06B685B6Bh,06D6E6366h,07F595B75h,069596570h,0746C6059h,059767588h + dd 05162756Fh,0645F5756h,07968845Ch,07C6D8085h,03D6E7690h,0BC993245h,07AC5ABDCh,0FAC5A8ADh + dd 0FAFAEEECh,0F4B9B4DFh,0EBEFF5F9h,0C4A5E2E7h,0E7E4F1E3h,0F2F3F1EBh,0F3F1EEF1h,0E6F4EFF5h + dd 0D9D2DBD1h,0F2F0E9EBh,0C7CCBDD9h,0ADA9B6C6h,0A9A18EA7h,08A88A0A3h,09D8E6685h,076778294h + dd 08073626Bh,091828487h,081909C9Dh,08592798Dh,020296386h,01C212729h,030292A2Ah,06D183A2Eh + dd 086866E74h,06F847E8Ch,0796A7587h,07E87847Fh,0777C8381h,0848C8280h,08286919Bh,0ABAD9183h + dd 0958C90A5h,096A78F8Dh,0B19D8C8Eh,09BA18791h,05D6E8494h,0605C5A58h,0736E7280h,0779B7F67h + dd 06652586Dh,06B5D6664h,092696777h,09C86A19Eh,09B938E9Fh,090969899h,07879858Ch,07F888D7Eh + dd 093828086h,0746C6794h,06F62727Bh,082737A72h,0587A8C7Dh,0817F7E69h,08177767Fh,0817D7577h + dd 0625F605Eh,07273696Bh,06C7287ABh,0655D7375h,05C585762h,0586C5E56h,0A4A59983h,06088BE96h + dd 0936D8366h,069849073h,0716F827Ch,066775A65h,0777B6E55h,06D68647Eh,062796C75h,06D746D80h + dd 072777D79h,07B646272h,0BAA3747Bh,08C8193ADh,03A995185h,0ADCC4B4Fh,084C9C2E2h,0F8FAA3CBh + dd 0FAFAFADBh,0FAFACEE0h,0D3F8EAFAh,0FAFAD08Ch,0F3F2E7FAh,0FAFAFAF7h,0FAFAFAF9h,0D7F1F3FAh + dd 0E5E8E9E9h,0FAF3F4EAh,0EBDFF1FAh,0D4D5D9DDh,0A5BDC1CFh,0B0A59B98h,0A999B49Dh,083ABA0A4h + dd 0988A9895h,0748D8078h,09487A380h,09097958Ah,061B1BDAFh,0170E3970h,030252524h,0240E1620h + dd 07B557B61h,0AA8A8CA4h,099919785h,08BA797A7h,08F867778h,089939196h,08C877EA9h,0B0B89886h + dd 09A8699A2h,0736E9795h,09BCBAA81h,0899C9898h,06C707777h,087777B7Bh,05F736074h,08B8F626Ah + dd 0555C5B55h,058786B65h,08A6A5F59h,09AA58DA8h,0979A8A97h,07F96B2A1h,07F79868Bh,07F8E7E7Eh + dd 09C807E83h,07482759Eh,07E7D817Dh,082788781h,058758F85h,07D7B8270h,06979787Bh,07B757161h + dd 072566665h,08E877B94h,07E7E8F8Bh,078725D6Dh,068747E75h,072887D70h,098918F80h,0867D9B9Ch + dd 093918D75h,062778D75h,0817C8C78h,09C916A8Dh,0929CA594h,064616188h,0928A8268h,05F756D84h + dd 0716E7379h,09F9B766Fh,0ACAF8D81h,090AC9BADh,01E5D2180h,0DFD0583Dh,06094DAF3h,0EFFAB3A5h + dd 0E5FAFAFAh,0FAFAFAD7h,0A4B4E4FAh,0FAFAFAA2h,0F5EAF0FAh,0FAFAF9F6h,0EDF5FAFAh,0E9F4ECEAh + dd 0EBF1F1EEh,0FAFAFAF0h,0E7F4FAFAh,0DFDCDDE6h,0B0B4C9DDh,0BDBAAAACh,0B9A0BBB1h,081868BA4h + dd 0948A8881h,080868D86h,086ADA9A2h,0A5AD9D88h,0BDCA8F9Eh,011386BAAh,028241C13h,01B151F1Dh + dd 08D775C2Eh,09A9F8582h,0ACB8997Dh,08FAAA2A3h,07E8B7E80h,0A8AC978Eh,095878F8Eh,0A09F9990h + dd 093818EA8h,081719397h,0AEAFA5A2h,0789C9DA5h,061626F71h,090837A71h,06A69879Ah,071716854h + dd 0544B6384h,071797571h,0955E6D80h,0909C9384h,09286948Ah,07E818695h,07E7D848Ch,088768280h + dd 07B7C807Ah,0757B7084h,078937C6Ch,071716F6Bh,05E717E75h,07D767267h,070787F7Ch,075706761h + dd 05E566E5Ah,0868B9A8Ah,081848690h,058605965h,08E8C7D6Ch,06D78707Eh,0948B6B6Fh,0868C8DA6h + dd 064707C7Eh,060616F5Bh,08565816Ah,0A1887684h,09FACB7A0h,07171678Dh,0998D9D85h,0747E6972h + dd 08982878Fh,0A6B08781h,065879571h,0C1A1D072h,01E4D1FA1h,0CFAE7131h,0A46AD1CFh,0FAFAD79Bh + dd 0F4F9FAFAh,0FAFAFAFAh,0B6BABFEAh,0FAFAFAF1h,0EFD2FAFAh,0FAFAF6F8h,0FAFAFAFAh,0E2EEF7F0h + dd 0EDF2F1E8h,0EEF7F4EDh,0E8FAF9E3h,0D5DEE5EDh,0C0AFBECFh,0D0CFCCD3h,0AFA6D3CDh,090AFA3A6h + dd 0AEA0B2B4h,080879299h,0B1BDB88Ch,09EAEA7A0h,0A9A19BAFh,0378DAEB0h,0201E0E0Dh,0161B261Ah + dd 084411913h,09397A9A8h,0A68AA4B5h,093A5ADA6h,08886A384h,0929C9FA5h,09D9E9388h,0809B8394h + dd 086898581h,08C9EA497h,093957B8Bh,08B908F8Fh,0737D8E92h,07C7C7772h,073848A8Ch,075857570h + dd 06F584F51h,0867F7675h,065767A7Fh,0817B717Fh,090867089h,08B8A8F8Eh,083837D8Bh,076828383h + dd 076838D8Bh,0918F7B7Fh,08B8C9194h,0858F988Fh,0998F8E8Ah,08D8D8C93h,072576F88h,09591838Ch + dd 05E656F69h,06D6D765Eh,071807360h,065565D70h,07D848A7Bh,0646C8183h,07C797486h,08C86898Ah + dd 07976827Fh,06A696B77h,050628365h,0AD95776Bh,0A0ACBAA4h,05B6E6B8Ch,0887F8073h,0707389A1h + dd 07B777677h,09286757Ah,077AF7C7Eh,0B0A0462Ah,017351AA3h,0D29F8C1Bh,0B75BA1C1h,0FAFAF6A6h + dd 0FADEFAFAh,0DBFAFAFAh,0DFC29BA9h,0FAFAF9F2h,0EAA0D0FAh,0FAFAFAF6h,0F9FAFAFAh,0D8E5F9F4h + dd 0F0F2EDE1h,0E4E5E9EEh,0FAFAFAE7h,0E7E8E8F1h,0CED2D6E4h,0D6D2D6CFh,0C0B3E9E0h,096B1CDC4h + dd 0B09CC3C3h,080897684h,0425A9BA1h,0A1B28552h,0A49F9E9Fh,097AD8493h,0080F1C4Eh,01C191F1Ah + dd 04B1E192Bh,0A8B6A287h,09897ADA9h,08F9CA8AEh,09E978E81h,0AEADBBB5h,091978D99h,092778F94h + dd 072787D88h,0817B8392h,098888F8Fh,085918F91h,08987898Eh,0777F7D7Eh,077889893h,0707F735Eh + dd 064495776h,06B616568h,08B64885Dh,0988A8C99h,09C836DA0h,09CA19B9Ah,0878B9293h,07C8E8286h + dd 0767D9292h,095966D6Eh,0838398A4h,09B9F9E8Dh,0B0A1919Bh,096A4A4A6h,091637C85h,09B978698h + dd 073757270h,0755D6872h,066625E7Ch,06C6F4A64h,0887B6E72h,052647583h,082756C79h,08B8CAC9Ah + dd 06E707E7Fh,05E6A6065h,0688E7F5Fh,07D897169h,0A49AA1ABh,07C727A9Dh,076716968h,0706E6B68h + dd 07D7E7574h,09D956D79h,08BB39C8Dh,090272A6Eh,01E2E2AA0h,0C8B99623h,08A946EC7h,0FAFAF9E5h + dd 0FAF3FAFAh,096EFFAFAh,0E3DBCB99h,0F6F8FAEBh,0F4E782FAh,0F3F1FAF5h,0E0FAFAF3h,0CFE5E0EFh + dd 0E6EFF9E7h,0E6EFEAE6h,0FAFAFAF1h,0F3F1F1F8h,0DCECE7F3h,0D9DCECEDh,0C1B5DAD8h,0B8D3D4CEh + dd 0C49BAEC8h,08DA98BA5h,025A892A5h,08F6B4122h,0A09AB2A6h,0ACA48F9Ch,0042C70A4h,01D1A2119h + dd 013272225h,08F965D25h,0979A9895h,07E8A9CA2h,0809A7E7Fh,0A195847Dh,092908282h,08F999583h + dd 0687B9173h,094BD957Eh,0979B8386h,08D849096h,08D918E8Fh,081928A96h,07381A1AAh,069787880h + dd 0606E5970h,0767C665Dh,0546C816Fh,0766E6578h,09F847296h,08C9BA19Ah,08280887Bh,08C919082h + dd 0737E8A96h,0968D7669h,087958F99h,09E9F706Fh,096837E96h,09EB6A79Fh,085588F99h,084786F7Fh + dd 06F78736Ch,05D5A5558h,07B6E666Eh,07E796D73h,081787882h,070817778h,06B727E80h,087888179h + dd 06B88978Dh,0656E6C60h,077737263h,08B837C82h,093928192h,06F7A7B86h,062606166h,07264636Dh + dd 080898075h,0888C7D7Fh,096AA9899h,04330539Ah,025475B61h,0D4CDB577h,0A1BC69C8h,0FAFAF7F3h + dd 0FAFAE0FAh,0A5AEECFAh,0F7DAE0D0h,0DDF6F7FAh,0F4F9CEE0h,0F0E6F4F9h,0FAF7EEFAh,0C1E4F6D5h + dd 0E7E3E3E8h,0E5F5F5E8h,0FAFAFAE8h,0EBF1F9F7h,0C8DBD3E6h,0D8D7DADAh,0E4DED4D8h,0C0B5D2DEh + dd 099B9D0B9h,0987794A1h,0889E93A6h,0333E3030h,07E6F5D41h,096909790h,04E8A9696h,02A2E192Dh + dd 02933261Eh,098642524h,06A7E8AA4h,08D8B7F7Ah,081978E82h,08F76888Bh,0928EA096h,0799B8A8Eh + dd 0618D7A76h,0A6A3BA96h,0878D849Ch,07B888587h,08F919287h,08A918795h,0797F969Dh,071707066h + dd 066645A81h,06670747Ch,073708078h,07267595Fh,0AA95688Eh,08D919C8Dh,084878E8Dh,0858E877Eh + dd 06974848Fh,091857463h,071889A9Eh,0A3A29268h,085707F9Bh,095A69395h,07E6EA491h,077717081h + dd 06D7F7C73h,08C765F65h,08A7B7475h,098787E87h,097999CAEh,08895868Ch,07C90747Fh,09EA29A8Ah + dd 083979499h,0737B928Bh,093949885h,0A2899E94h,07DA4999Ah,073917C63h,0736F6C6Eh,0775F637Ch + dd 08683928Ch,0697B7577h,06C7C7D81h,069446B6Bh,01E754E1Fh,0D2DDBC88h,0B79B4FA1h,0FAF8FAFAh + dd 0FAFAF5E4h,0EFBBB3E8h,0F8F5EEFAh,0D6F9F7FAh,0E8F7F0B4h,0E3E3F0FAh,0F1F8FAFAh,0D8D4EDECh + dd 0EEFAFAF1h,0EEF5F4F0h,0FAFAFAF7h,0EEF2F7F7h,0D9EFE3ECh,0E9E7E0E3h,0F5E7EFEBh,0D0CDE1F4h + dd 09BCBC0C1h,0BDC9D3A9h,0A6C1D4DBh,0283570ACh,010181E25h,05122151Ah,0A482665Bh,015164284h + dd 0211C2014h,0833A091Ch,0899D847Dh,0A5A4A297h,07F899AA0h,08E7F978Eh,09882928Fh,0605D8FA6h + dd 062816989h,0C3A3B385h,08E8892B7h,081878184h,0858C968Fh,0848E968Ch,07E7D8A8Bh,061687D73h + dd 07170717Fh,0736D636Eh,0A2A39A8Bh,099937F8Ch,0BA8172A9h,08E8F9AAEh,085878897h,0818C9A91h + dd 0797E818Bh,089938777h,09A98A38Eh,0949E9792h,0767A7482h,0ABA78781h,077628DA6h,07C7D7D8Eh + dd 058636970h,0836B5555h,07B6B7673h,07E757F84h,097989283h,08EA09694h,06B98778Fh,08B7F7E6Ch + dd 09DA4A39Ah,0A3A1A39Dh,07393A1A0h,0D6A09E89h,07E9B8CACh,07C856A5Dh,0877F7A7Ah,07A727582h + dd 0A6939C82h,07D887484h,06A7A7F82h,0564D7B58h,074872B65h,0DBF0D5A6h,0DC857197h,0E3F9FAFAh + dd 0DCE8F7D3h,0FAEFA09Bh,0FAFAFAFAh,07AF0FAFAh,0EBEEEC98h,0E8C0B1F8h,0F9F7F6FAh,0E1FAFAF4h + dd 0E3FAFAE7h,0EFEFEDE4h,0FAF9FAFAh,0F5F8F9FAh,0EDFAF4F2h,0EBECE8EFh,0F4F7EBEAh,0D0D7CEE6h + dd 0C6AEC9E0h,0C3B3BFD8h,0BACAE3D2h,02047C2B3h,02535382Eh,0252C3C30h,0541E1B27h,01F577460h + dd 021122113h,04003081Bh,0978E6C86h,097A1B5A0h,08982A2A1h,0A49B9A8Dh,0A978827Eh,06B8793AEh + dd 076637166h,08D887A69h,0908D8593h,0878B8C8Fh,083848B8Ch,08B899784h,078778180h,0676D7373h + dd 06E687972h,061755E5Fh,0827E785Fh,0727D6D7Ch,0936C716Bh,088847F88h,07C888185h,076878385h + dd 07375797Ch,05D77756Eh,0716C625Ah,07F776A6Bh,05666656Ch,063645E63h,058627766h,06C6B6369h + dd 054606A75h,07773604Eh,065566C8Bh,08C7E7F78h,09D988F8Eh,0899CA19Fh,065827690h,09B858170h + dd 0B5B1B1A6h,0B6C0B4A9h,0A49DB0B3h,0A6BBACC0h,096A1B0C8h,085757381h,0777C7A7Ah,07B847E80h + dd 0A89AC27Ah,0847E7D7Ch,082867C85h,0327B6572h,0B381373Bh,0C5DDCEBBh,0E3707E7Ch,0A1E2F5F2h + dd 0A1F1E4F3h,0F8F2DEA3h,0FAFAFAFAh,078CDF6F7h,0F8F4E6CBh,0DC845FC2h,0F2F8F7F4h,0E4E6F7F1h + dd 0F5F2E5F9h,0ECEFF4ECh,0FAF9FAF9h,0EEF8F9F7h,0E6FAF6E0h,0E9E7E5E5h,0DBDFEAEDh,0CFBFCFD5h + dd 0D8DAC9D0h,0DDD3CFDCh,0B6CECEC8h,0319597BEh,033292C14h,02A222225h,02228271Ch,03F310E07h + dd 020377E6Ah,0191A1A0Eh,08A89833Ah,0A5ADB790h,08F90ACACh,0A9939289h,0A081807Eh,08D717A95h + dd 09E738784h,0827A7884h,0888B768Ah,08B848C8Eh,08F949189h,094828F81h,07C899392h,06B778D94h + dd 075698082h,06F7F6F6Eh,07F736C6Fh,0A5907477h,098B3AA9Ch,09F9E8F90h,09195A493h,07E909397h + dd 0667B8388h,09182636Ah,08F7C688Ah,07B8D9684h,07089887Eh,08B8C877Dh,094818292h,096918B82h + dd 05E616B73h,0726E6054h,069606887h,08D787671h,09490898Dh,08F9C9595h,08C98A186h,08D999D8Fh + dd 0AB96A3A0h,096939EA3h,0A599ACA5h,0B6B2ABACh,0A1AC8AAAh,0646A7473h,080858282h,09B907887h + dd 0A686C19Dh,07684A196h,075777B6Bh,0557B6B76h,0A952231Ah,098C8AAAEh,0E5A89050h,0DBBFF1E8h + dd 089A8EBFAh,0F6E4E2CAh,0FAFAFAFAh,0C092E3F9h,0F3EBE7FAh,075557573h,0FAF9F4EBh,0E6F2FAFAh + dd 0FAF9F4F3h,0E8EBF9FAh,0F8F2F9ECh,0FAFAF6F5h,0D3F9E9F7h,0DFDDDDD7h,0DADAE6EEh,0D6CED7DBh + dd 0C0D3D7CAh,0B0CBD2DBh,0AEA09DA2h,0849B859Fh,022160C40h,01E172219h,030251C1Ch,0190D1827h + dd 0589B9647h,01C1F2B30h,09F9E4D22h,0969C9399h,08E758598h,0B193A0A0h,0A29B8D97h,08078767Fh + dd 096818A70h,07A828182h,09EA89894h,09FA5A8A7h,0ABA0A2A7h,0A38A959Ah,05C5D6E8Fh,06365887Eh + dd 063625F59h,07676695Eh,07D835E82h,09195A28Fh,0A6B47A6Dh,08F9396AEh,097877E92h,089949693h + dd 0687E8D95h,09E8D6065h,08C7A747Dh,089858586h,0788A7C84h,08787896Fh,09990817Dh,093908E81h + dd 04C555D5Ah,05A5E624Fh,069686478h,0747D6F64h,08F8A8779h,085918F8Dh,080857F7Ah,07C91937Dh + dd 0A0919693h,08E829094h,0808E9991h,092917D80h,07D929391h,075859277h,07D727980h,0958B777Ch + dd 0958F8BABh,077738893h,079777379h,08B64607Bh,098521E4Dh,086D0A2A1h,0E4CAD666h,0F5C0CBE9h + dd 0D38BD9F9h,0FAFAF1FAh,0F3FAFAFAh,0E784DDF6h,0D1E8E1FAh,06456BB62h,0F9F5F1DFh,0E5EAF5F9h + dd 0F9FAFAF0h,0F0F2F6F8h,0E4DEECF1h,0EEEAE2F0h,0CDEFE8E5h,0C3C2C2C7h,0D8CAC2CDh,0BEBED3DCh + dd 09BB1C5B6h,09BB0B0B5h,08C97A091h,08B8E8497h,01E173583h,0713A291Eh,0574A3A4Bh,0404A5259h + dd 07A7E241Ch,0336C8080h,078400D07h,0878A7778h,088787280h,093707B83h,08E8D857Ch,06D7D6077h + dd 09B9C8361h,093A4B297h,0B6B1A89Fh,0B3B2B5B8h,09A9EA7C3h,074839A8Ah,0896E748Eh,064707981h + dd 06E6E6A60h,06E6B6568h,074726172h,06D729585h,09E9D7461h,0707C7794h,073617580h,070747974h + dd 07166777Ah,0A1665F55h,087678076h,0837B7A8Fh,077848483h,076767C65h,08980817Bh,09A94808Bh + dd 051585E50h,054535457h,06562675Ch,075827E72h,074737079h,077697072h,058547790h,081626366h + dd 08E8A807Bh,088808F87h,07D797F7Dh,0948C6C70h,0879A9492h,09D92A48Eh,09D8D9C9Ah,08F959892h + dd 092AC9BA7h,07F8EB6A5h,08A897A7Ch,098687D79h,09885476Dh,076CBAE8Fh,0F0D29A83h,0F7F9BCEEh + dd 0FAC2B9E2h,0FAFAFAFAh,0FAFAFAFAh,0FA8B9EF9h,097DCEFFAh,03C45AF5Ch,0F6F5E6B6h,0E5F0F9FAh + dd 0F1F5F9FAh,0F2EEEAEFh,0EDF3EFEEh,0E5F0FAF5h,0D3F1EEE4h,0A5A8B4C9h,0CBB79FA9h,0B1A5B7CAh + dd 094A8AFB9h,0B7AD9E9Eh,0888CA1B0h,098A0AA95h,0292F98A0h,072292832h,0AFA5AEB2h,083938D95h + dd 04C4C3C72h,0B88D4833h,06D0734B7h,096AFBAB7h,0A7B8A48Fh,0A287A194h,08A8F9685h,070796F93h + dd 08F88756Bh,09DA0B195h,099928394h,0AFA8A49Dh,0A9A0A6B8h,08A898B8Ah,06E6F8587h,072708196h + dd 06A6C767Ah,06660676Dh,083746360h,082778F8Ah,09D8FA383h,0769490A5h,08C89987Fh,07F7C757Ch + dd 0746E7B7Eh,0926C6172h,08F6D7079h,078888F95h,06F78827Bh,0726F745Bh,07B6A797Fh,09C887E8Ah + dd 073505552h,0AA9D9299h,06F677B94h,08E858894h,099979697h,09B989396h,08E8AAEA1h,08D7197B3h + dd 08E8E8189h,086788982h,08688857Ch,09B966F75h,08D98C6CBh,0737F807Bh,0857B8C7Ch,08479828Eh + dd 090918B72h,0998C9A91h,074787DACh,0495E487Bh,0B0704347h,077CCB4B6h,0DCCB50A0h,0F9F6CDD1h + dd 0FAF59DB7h,0FAFAFAFAh,0F9FAFAFAh,0F9B168E0h,095FAF9F1h,03697C161h,0FAF3D18Dh,0F1F9FAFAh + dd 0FAEBE9F9h,0F4F9F8F9h,0E0EEDEE8h,0B4C0E0DCh,0E4F2E6C2h,0B0B8C5E5h,0B698A5B0h,0A5AAA9BCh + dd 07A7D8CA1h,0B09D989Ah,09C67658Bh,09C9C9C75h,02D828EA1h,01B2D2C19h,0B28A7430h,0AAAF9CA4h + dd 0B1536DA5h,07B5A85B3h,0131A7C9Ch,06E5C665Ch,092A3BE99h,0A28F9691h,09284937Fh,07B797485h + dd 0856D6B7Ch,0A5989989h,0A392A494h,09694979Eh,08D979691h,07288917Ah,09389948Bh,07965849Bh + dd 0766C7884h,0967D737Dh,08296A09Ah,0706B7E61h,078787A5Eh,062787E6Eh,08477617Bh,0807D787Bh + dd 0606E7379h,073775381h,070626A69h,06D717E72h,0696D7C74h,073717156h,075708270h,09D7D8283h + dd 0864E5F58h,093959490h,081929096h,093908683h,09C989C96h,088848493h,0AF8B9C92h,08583919Dh + dd 0A28F786Ah,0817E879Eh,0847C8581h,091847476h,095A3B7B9h,08088858Fh,09C857764h,089A7A595h + dd 09B98897Dh,07A847B91h,035385D64h,063482137h,054433D74h,07A8A7B71h,0C7BD5B85h,0CCEDF3ADh + dd 0FAF8C983h,0FAFAFAFAh,0F4FAFAFAh,0F9DB70A0h,044E3D6F9h,0399BA79Bh,0F9DEBF61h,0FAFAFAFAh + dd 0F2F3EFE4h,0F4F1EBEBh,0E5DEDDECh,0CBE5EFECh,0E1D0CDBEh,0CEB788D1h,0A68CA0D4h,09E9B968Dh + dd 0A798908Fh,0AC9B96A5h,0B7856C8Ch,0A9B79BA8h,07090A1A3h,0262A3136h,09E893E1Dh,0907C7A95h + dd 07D6AB6B9h,08979767Ch,053767888h,0635B695Bh,09C9EB193h,08480847Eh,07F898286h,086907B85h + dd 0828C8289h,087746F73h,0A481897Eh,0A79AA2A4h,08499A29Fh,09195828Ah,07B7B7676h,06C6A877Fh + dd 07B72767Eh,0726E767Ch,0767F8B80h,080877E76h,07F71848Fh,08E897270h,08B828F88h,064777880h + dd 08B8E847Eh,07C767780h,0717B8581h,071707677h,079757C72h,07E817B7Ch,0656E7F7Eh,0605C666Ah + dd 07D45585Eh,095908689h,090808393h,0858D8793h,09193838Eh,0949C9B8Eh,0AD82898Ch,092AAABADh + dd 09A888888h,07F8F96A0h,07C6E7F7Eh,08E866770h,09F829979h,0888A8A92h,07F7D6E94h,0808577A1h + dd 09B9A8277h,0A78B6E87h,019133EB8h,032222E2Dh,02E1B372Bh,02755987Bh,099AD2061h,06DD8D1ACh + dd 0F9EEDA81h,0FAFAFAFAh,0CDF4F9FAh,0FAF9B27Ch,03AA0E2FAh,04DA8BFA1h,0F6E4A036h,0ECFAFAF6h + dd 0EBEEEEE7h,0F0F0EBE7h,0E7E3E8E7h,0DFE3F6F5h,0B999AFCEh,0C5BC9896h,0AC82A5D3h,0AB97AAA9h + dd 0AA97AFAEh,0A18EA2BAh,07C815E8Ah,0BB9EA3ABh,0AFA0A8BEh,0381F1A64h,0954D1842h,0726E6267h + dd 08668847Eh,089777688h,06A669194h,07B8E8196h,0949BADA1h,0999B9891h,09A978D93h,07F8D9A95h + dd 07F8D7A7Fh,08A7B706Dh,09F9E866Ah,088A9948Fh,07A8D928Dh,082877B81h,05B74676Ah,063637270h + dd 06065666Dh,0716C6861h,0695D6B6Dh,05C858B82h,096827C51h,07A727D82h,081818089h,0798C857Bh + dd 09B8B8F8Eh,07D7F7992h,06F627B82h,0796B7476h,096868D7Fh,08990838Bh,05F83837Eh,08A818382h + dd 0775A6A80h,09E9F8683h,0948F9792h,0A194A89Ah,09597939Dh,092939892h,08C8A9B97h,0889BB0B2h + dd 0887C8C89h,08488868Bh,09E96A194h,0B98F7E97h,09686A289h,094A4A699h,083958391h,0899A8B99h + dd 0A2A4929Fh,0947E7C95h,0758389A9h,03E3F5067h,0D581613Dh,098BE99CCh,05F336456h,0456FC698h + dd 0FAF9F1ACh,0FAFAF7F5h,094E3F6FAh,0FAF9D778h,05F79E4F7h,080E2D098h,0F8DD7E41h,0F3E8F3FAh + dd 0E6EAE7DDh,0EFF0EDE8h,0E2E6EBE7h,0CBD1EFDDh,08D9F9DCFh,0ADCEBD7Eh,0B1849EB8h,09A878EABh + dd 0969D9F9Bh,093939A98h,0B480738Dh,0A4AFB7AEh,0949499A5h,0371D5EABh,0661D352Ch,097745E76h + dd 099817E7Bh,0908B8F9Eh,06F738390h,072877A65h,088959389h,0A3A19190h,08F8FA0A2h,08A969290h + dd 0878C7D8Ah,07D7B7B7Ch,09DA88B69h,0ACAE9383h,05A52628Fh,077705963h,07C81809Ah,05C758071h + dd 0655D4F64h,069615B5Eh,08B636259h,0606A8F7Dh,08F7A6260h,085655861h,07F817688h,07A7C8679h + dd 084757F95h,0717E7882h,06B8B7F6Ch,08D80817Ah,070859892h,094928473h,053717D7Fh,0888F825Ah + dd 07158596Ah,07A7B888Dh,07D898B84h,0889B8B98h,082798783h,08D949091h,089798288h,09692888Fh + dd 0928E9D94h,08289848Eh,0736C8388h,08C6C6480h,079778576h,071797679h,0747A797Ch,07E7A787Fh + dd 082796989h,08B856573h,07189847Eh,049434652h,0A0C3C790h,09ABED49Fh,08793ABB2h,0724E5367h + dd 0EBD7DAE0h,0F4F7F5F7h,07ED9F2F2h,0FAF3E898h,09C6CE0E8h,0759091B5h,0F6CE4646h,0F2F4F7FAh + dd 0F7F7F3E7h,0E9EBEDF2h,0F1F0DEDFh,0DFDDC0E4h,0A5B8B3ECh,0639094B6h,0A0929D8Fh,08F8E949Fh + dd 08A9B8E86h,08790998Dh,0B48A8C88h,0A5B595AFh,0808C9F9Ah,034777D89h,057274043h,0A79E8EAEh + dd 094958F9Fh,0A29B9198h,07E909998h,08E8E8B7Bh,0889A879Dh,0A096858Fh,0959DA5A4h,099979BA7h + dd 08281819Fh,08F767F84h,08295907Eh,08B9AB08Eh,08668718Ah,059545483h,08F858476h,068706F69h + dd 06E6A8B74h,0776E738Eh,0A5586A65h,0477EA383h,075726451h,07D69615Bh,07C79857Ah,0768C7875h + dd 0727E7C89h,07D6B6B6Eh,07E757A74h,080818886h,04E5D7E80h,085839B84h,079738887h,084888369h + dd 0555F6773h,08F706969h,079928179h,0837D768Ah,08A80917Fh,099918B78h,07E749E88h,07A898F86h + dd 09E96988Ah,082819F9Ch,086787B85h,0A3AD837Eh,0816D8480h,0857C8E70h,0797C728Ah,09499B199h + dd 07B8B909Fh,07B798588h,0264A819Bh,0C8694435h,0B687ADE8h,0CEBDBBE2h,07199CCC3h,07DA87782h + dd 0C69A594Fh,0F1EBEBE4h,08AA1E6D9h,0F8FAEFDFh,0905DBCE6h,0A8B19D9Dh,0DE69392Eh,0F9F8F8F2h + dd 0FAFAFAFAh,0D8DBE1F3h,0E4E5E7DDh,0DAD8E3E4h,0A3C9DEFAh,09EA9CDC9h,0D5C5BCAAh,0BBCCD0D6h + dd 0AE96ACBBh,0B2ABB8AFh,09D7EA3A3h,0DAB9AAB8h,098A7BBD7h,05C97A99Ah,03B2D261Fh,08EA59452h + dd 0859AA389h,0949CA684h,092A0958Fh,09A94A192h,0A8A7A099h,0929AA09Fh,07C76838Ah,0A5AFB197h + dd 093888D9Ah,071938E8Fh,08D878572h,070827B8Bh,05F78726Ah,0454B5B62h,07A6E656Bh,0635F6A7Bh + dd 075637C68h,08D8E8D9Eh,0877A8399h,0716D7E7Eh,06E6A7C8Ch,08C857E7Ch,07F7D8A8Ch,076788383h + dd 0767C8483h,0636C8B6Eh,07A7A6C66h,072777575h,079777F7Ch,08989827Dh,0727B8082h,07269716Eh + dd 05D675F60h,08171685Bh,06F7B6E80h,073617167h,087858272h,0A6A18F7Fh,08C8AAB92h,0917E8C8Fh + dd 097908A88h,08C8F867Dh,06564727Fh,06A7D8683h,0A87C8970h,086689178h,08079847Eh,0A1B2B3A3h + dd 090888BACh,092939FABh,02C2E298Fh,0C8C7733Dh,0B2BA7B92h,0EDDDB996h,07A3675CBh,0C8C5CEBAh + dd 07885DAAFh,0E7B78D76h,0B545CBDBh,0E2FAF5EDh,07A739AD7h,08D9B6495h,0A5601A8Eh,0F9F4F7E3h + dd 0F9F8F3ECh,0E2EBECF2h,0EAF1F7DDh,0C4EDF6E5h,09EC4C1D8h,0ACAEB3A5h,0E0C6BAA5h,0BEC6CFD4h + dd 0A48FB1BCh,0B38FA5A9h,0897C8C98h,0D0B1BFB1h,0A49FA9DCh,0959FAFA9h,02B26153Dh,07A933F13h + dd 07A878B7Dh,08A888E7Ch,09486928Eh,08B9C978Eh,08E898E89h,08486999Ah,0786C6D79h,099A9A88Ah + dd 0A9A4A7A2h,07C887A89h,07C8B847Ah,0786A6775h,07F8A8790h,0556D6C71h,067615A54h,05D585E6Dh + dd 068706E74h,07A807974h,0707E869Ch,06B747070h,06E686D7Eh,08B8D8078h,06D778084h,07573736Bh + dd 0716F7E7Dh,070517178h,0796F6B84h,077696B72h,068747A7Bh,0646E766Fh,086847C71h,075757E84h + dd 05962637Fh,07264665Ch,092756570h,086827C8Ah,07177656Bh,0968F8E7Fh,09989A27Ch,088668BA1h + dd 091837E7Eh,0856E7178h,075727066h,07D6D757Fh,04450837Dh,0659D8272h,093899A86h,0AFA7ABAFh + dd 08C857999h,051AAB394h,0343D3F28h,064B0BD75h,0889ECD8Ah,0BADEF0CAh,0BBB76277h,0B2DCE2BDh + dd 0CAC6E4D8h,0725987B7h,0A3475B73h,0D5FAF5E5h,08D746CC1h,0AA796965h,06637157Eh,0EDE9E9BCh + dd 0F7F4EFE9h,0E1EEF6F7h,0E7ECF1D6h,0F2E9E9E1h,0C6B0BDE5h,0A1ACC3C7h,0A8A58CA4h,0B8BCC9B0h + dd 09591ACBDh,0A78DA59Ch,08C8693ABh,0A9B9B99Eh,0B3BFC3C2h,09C8F96A3h,0210E22A6h,0803B1821h + dd 07B807D75h,07A7F7779h,098848780h,0858C7E7Fh,0947F7D83h,085868593h,077686B79h,0A6A9AD87h + dd 08F94AABDh,090958A85h,08A7D7A83h,07C7E9392h,065767893h,07F5B5462h,06A76807Eh,0705E5A5Fh + dd 070795661h,06E7E6C72h,083817F81h,0A4899A8Ah,08884739Ah,083877778h,07E87727Ah,07C71847Bh + dd 0727D7F7Dh,08E877E7Dh,09188918Ch,08D96918Eh,07C898B8Dh,08D949383h,09494938Ch,08788868Fh + dd 062786C81h,096717369h,08D666B89h,0849C867Fh,083A2887Bh,0A3A6A499h,08AAC9C76h,0816E6281h + dd 089919587h,08A6C8276h,07073877Ah,07D778F90h,0164E8C74h,0828D6224h,09D989B8Eh,0B6ADC0AAh + dd 0907E76AEh,020346D97h,08F2E3C2Ah,0906295BBh,0C97E70C0h,065A8C8E0h,0B9C8E590h,0AF96D7DEh + dd 02810AAF9h,0D8E39052h,08C4B6FA4h,0E3FAF7E2h,05C7A5EB4h,062935A5Bh,050213917h,0E6D8D291h + dd 0F6F6F5F1h,0E9E7EBF2h,0EDEDEEF1h,0FAFAE3ECh,0AAB6E0FAh,0B3CAD1A5h,08580B4ACh,0C2C0BCB5h + dd 09DA9B5C8h,0A5BBC99Ch,07D887B9Eh,0C6BFB5A7h,0A8C3C097h,09485737Fh,021196FADh,07C1C141Ch + dd 08795A3B0h,07F917980h,0847A877Ch,0948A8C87h,08F879886h,088848191h,07A6E6B80h,083909375h + dd 07E9A9BA3h,0917D9789h,08F867988h,08190988Dh,07B7F6F80h,07E817A77h,05B717E75h,073666975h + dd 06D847282h,0A1A3737Fh,08D706E90h,0A198948Eh,06F796D8Dh,0706E766Fh,076736B6Ch,086767879h + dd 066758481h,081806C78h,07D847A84h,081827F7Ch,0767E7D7Dh,08F8B827Ah,094969591h,076818294h + dd 073747375h,09B937171h,07E70907Dh,09797888Bh,0A99EA496h,074A9A496h,084807D7Eh,07E727F81h + dd 090B3A491h,0BB8C7C7Dh,0A6BBE0C5h,0ACBFA098h,02029A3ADh,0571D1330h,0809A7E7Dh,0939B99A4h + dd 0A67194BAh,02B1F2EA9h,0B9894149h,0C29979B6h,0D1CABB8Fh,0A67996B1h,0D0BDC2DBh,0BE8EC0D9h + dd 0A83A3D8Dh,0A4631377h,099ADB0B4h,0CFFAE5D0h,056867B9Bh,01C3E4856h,03E5CBC64h,0C1C79C54h + dd 0E5E6E6E4h,0F4D5F6E0h,0E7F3F1DCh,0F6EFE9F5h,0B7F0F5FAh,0A6B0B191h,09C8689A3h,0A8D0A4AEh + dd 08CA5908Eh,0C9AE98A1h,0A9A3A5C2h,0D5AFCD80h,0A2CCA1C1h,09C8E9093h,01C40A5A3h,04E18201Eh + dd 07B7C7C92h,0616C808Dh,05D626D62h,05774725Fh,0786F6444h,0707C6E72h,06D596656h,06B797A67h + dd 076558781h,0928C9788h,087959189h,0918F9D95h,07572898Eh,0746B6F75h,078727879h,0776D6A82h + dd 0758F7C6Fh,09D8D887Fh,08D6C7E9Dh,09480A589h,081647B8Bh,065646D6Fh,082797171h,07A7E8185h + dd 0657B7D7Ah,078707E82h,07A7C7879h,087858171h,087757383h,0848F8E6Ch,08F969988h,0806C6F71h + dd 06572755Eh,0848E7861h,071657B7Dh,07065696Ch,076637C76h,076887E78h,08F918780h,08792888Dh + dd 0747A757Dh,06056676Fh,057495B4Ch,06B707168h,0292C937Eh,0242E3234h,0A08C8C45h,0918A8798h + dd 09588A286h,02C2F1A68h,08DBB8242h,08ACBB081h,0DEC6ADCCh,0F0EBC3C5h,0F9FAF4DDh,0FAFAD2E7h + dd 080AA656Eh,091629CD9h,0D8CFC6B7h,0F1D7DBCBh,078A9925Bh,0994D5286h,050A6A6B2h,0CCB16250h + dd 0EEECE7E3h,0F9E9FAF2h,0F1F6F5ECh,0F8F0F1F5h,0E5E7E4FAh,0B0AEBFC8h,0899FCAC4h,0989A9BABh + dd 08282818Fh,0978B8F98h,0A9A68B8Eh,0BF9EA88Eh,0E1B4B5CDh,091A3ABBDh,01A7F9B89h,0221D2227h + dd 0897EB577h,0867F7486h,06E727B71h,043687773h,07F7F7A7Ch,0876D7577h,06D8584AAh,06E707669h + dd 07A51727Ah,0ADB69778h,08377839Ah,099908991h,08174828Ch,070768589h,0837E8178h,07E7A6D6Eh + dd 0788A8260h,0ACA1908Eh,083888FA4h,07F7A8F8Dh,08E70686Ch,074787D83h,084877477h,086868C85h + dd 079867C81h,08167768Dh,07E808A94h,086788195h,08989898Eh,07B828065h,0868A8982h,087767979h + dd 068689381h,04A566A67h,09A8B885Eh,088757481h,08D88A0A0h,090918F85h,0969D908Bh,08C879695h + dd 0AD979796h,09E93B6AFh,096A7B3A5h,087628BA5h,0402C9CB8h,01A2F3037h,08A89441Ah,097A1948Ah + dd 0A38FA0B0h,04342304Ch,07AA0BB73h,0AC83D1C3h,091D6F2E4h,0EDD7CB88h,0DFE2CBCDh,08BBDCDBBh + dd 094867A4Ch,05AAE7EB3h,0977C5C22h,08CD2AEAFh,05253492Bh,06D643321h,0409DAFB5h,0CA764520h + dd 0EEEAE4D7h,0F9EBF0ECh,0FAF6F6F9h,0F3F7FAFAh,0DED0E2FAh,0B8CCD6DAh,0D2CBB6B9h,08695B5CDh + dd 08788807Fh,09B939583h,0DFBA8F8Ch,0C88CB6D0h,0BDB0E6CDh,0B2A4C1D4h,044460442h,028312316h + dd 0A389AC3Ch,0797E92A7h,074777D6Dh,072917B7Ch,082878B5Dh,07B817D7Bh,07B877580h,058625068h + dd 051616A59h,08E7B7C4Ch,07BA8999Bh,06F817284h,06E697B77h,06F747F79h,07D7A7F70h,06A726B6Bh + dd 067858F75h,094928984h,081719089h,0909BA68Fh,069777F84h,083828B7Eh,07D838E8Fh,07F7E827Ch + dd 06569757Ch,097716B7Ch,0949B9699h,0707D8482h,0627A7B7Bh,053676A3Eh,0615C5C5Fh,0524F595Bh + dd 06B699C78h,05D5A6068h,0A29D8060h,05E63565Fh,0AAADA483h,09B8FA493h,08F97B69Ch,0918A9590h + dd 0AE97858Fh,08A84A798h,07F939189h,082686F88h,03C318F95h,02D393B43h,081522224h,09FABA4A2h + dd 093B1C0A7h,0704C3829h,0B98DABA1h,0EBB189CCh,0ACAAF7D9h,0C8D7DBD8h,0F7E2F278h,059B07F9Eh + dd 0919A964Dh,0869B946Ch,0560B0D58h,09BEBC998h,041AE6D25h,04725463Ah,0120A2C45h,09F603C1Ch + dd 0F1E9DED5h,0F7F7F6F7h,0FAFAFAFAh,0F3F9FAFAh,0D4D1DCFAh,0CDD6D1C5h,0ECDFCFCFh,08EAFCFF4h + dd 0897E7E7Ah,0988B9782h,0E3BF938Dh,0C19DB8C6h,0B1D6DFCFh,0D3C9DAD0h,02A274FD5h,02B262F27h + dd 09C996724h,07492A69Fh,06B69717Dh,087838173h,080878C8Ah,08476787Dh,09C919B91h,081786179h + dd 0606B7C7Fh,075637156h,07878606Dh,072666D72h,06B555B63h,069666B72h,071798173h,06D72717Ch + dd 07B85756Ah,092898588h,08C97A792h,0798B8D93h,08D937084h,089898D96h,082818E91h,086817A80h + dd 07983838Ah,07D746C7Eh,078868186h,07A767A78h,0807B737Bh,06975775Eh,070676672h,0837E8480h + dd 06F6A6A8Eh,068625A5Eh,0856D746Ch,06D776277h,0837B6B68h,08FA1AB97h,06C7E8E7Eh,08684818Dh + dd 09A9D888Fh,080809FA3h,08A838D78h,0807A839Bh,02B4B9FA0h,02D323837h,0281C4731h,0BEAAB879h + dd 052A8A8BAh,0C4673531h,0D1C78E82h,0D0F1C28Fh,0F7B27EE3h,0B4DED9F7h,0DBEEF8A4h,0AFEFCB88h + dd 05B5EE0AEh,0494B525Eh,013263A5Ch,03EC4691Bh,0427E7955h,0463D282Bh,037338E61h,0512D2815h + dd 0E4D7BD96h,0FAFAF7F2h,0F6FAFAFAh,0FAFAFAF9h,0D8DFF0FAh,0BBCEDDD6h,0CBC7B794h,0A1BEDCC5h + dd 0907D9AA2h,08D6D969Ch,0C39DA68Bh,0B5B6C7D4h,0D8D7CFC4h,0A3DCD8C4h,037385BC0h,030372D2Bh + dd 0AB8C2B21h,0829DA4A1h,07A767867h,06A848176h,08E919683h,07678848Eh,0786B7A79h,059667772h + dd 072744D71h,08A728978h,06C7F5180h,07883996Ch,06B6D678Ah,084466E59h,05F666966h,060565C57h + dd 089796B5Fh,0979A908Bh,0A7B9B19Bh,0A9ADC9B8h,0BBA8A7ABh,0847F829Bh,0887D7B99h,07E8E807Eh + dd 05F697B8Fh,08C788275h,08D867E91h,080877A7Eh,081838583h,064737E7Fh,0886E6D79h,08482817Eh + dd 06C695F6Bh,059546566h,07968786Ch,0777B939Ah,09CA5A183h,07594ACA0h,077647773h,08C7D7F89h + dd 09F94A0A3h,0A0A6A9ABh,093899FB4h,0A3948594h,02E39879Fh,02D343C3Fh,011558342h,0A19A551Dh + dd 04FABB4A9h,094836F81h,092DAA67Bh,0DDF6F0B5h,0FAE1C5B5h,094B5E7FAh,0C1F8E7EDh,09A4ADCACh + dd 07582EDD1h,05863626Dh,025343F5Dh,03227111Ch,02F5F6D5Eh,0E4A1835Fh,0207BD1BFh,0573B2E45h + dd 0D9D0A44Fh,0FAFAF8EDh,0F0F7FAFAh,0FAFAFAF1h,0EBEBF8FAh,0A6C5DEDDh,0D5B39D9Eh,0D2C4B8CEh + dd 09EA3A0B6h,0AA9C927Eh,0C8D2ACA5h,09BC7E7D1h,0F1DDECCFh,0B7F1C6C5h,00B8AB2A8h,0352C1C26h + dd 0964F133Eh,0819798A5h,06B697469h,07998666Ch,092829283h,06E6E7490h,0657F6E6Fh,0F0BACF8Dh + dd 0827776B0h,091707374h,0AE7F5F8Ah,0AE9370A7h,06C7887ADh,08853755Eh,05A5E666Eh,053525E60h + dd 08C89736Eh,0A59B9286h,0ADB2AFB6h,095ABA7B2h,08794A09Dh,09EA48F74h,098998BA5h,09385A797h + dd 075798096h,0948B8579h,0818E928Eh,07B86908Eh,0887E7D7Ch,0696D7A86h,07B796467h,06A626972h + dd 063726A61h,06C66625Ah,079766D74h,082798E98h,07F7C7F85h,076718C8Ch,078717A88h,08D817F77h + dd 08C7B96A0h,07D938B92h,08E767594h,0817C6D7Dh,0173C979Bh,025292824h,0468B9142h,074561E10h + dd 02788958Dh,092994737h,08294CA9Fh,0CBE9E2D5h,0ECEEF7CAh,0D691E0EAh,09AE4F6D7h,099498FE6h + dd 08E8CB091h,0A17E7C89h,0221B61ACh,050474347h,08C96A794h,0B9B9C3ABh,0519DACB0h,0463C4032h + dd 0C9975546h,0FAFAF2D8h,0F2FAFAFAh,0FAFAFAF3h,0FAF5F8FAh,0BACFCEE9h,0CFB18998h,0BBBCCBDAh + dd 0E0C3C8BCh,0BDA1AEC7h,0B0AAC0C1h,07EA2B4C9h,0E4BEB9A2h,0B8B4A1C7h,05E8E7896h,034272234h + dd 04F1D2F3Dh,084857388h,07C7D7E7Fh,09386626Fh,0906E7786h,068646B94h,07D767972h,0B59E9E8Eh + dd 086658788h,0807E7475h,09A716885h,0A985678Ah,0766A6E87h,076527674h,070666266h,0555B7279h + dd 07A624D58h,0A7979082h,0A9A398C0h,0A99BA6ABh,0909B91A5h,092988A73h,095A28D98h,09377B6A0h + dd 07D778291h,09B9C988Ah,09E92988Eh,0A18C949Bh,07B808795h,0897A787Ch,05A767289h,06C5D5D6Ah + dd 07C898676h,080726A6Dh,086897C8Bh,08C837B83h,09E9DAB96h,0A0A4A1A4h,08381798Ch,091948E8Ah + dd 08F919698h,0947B8591h,07F889395h,0968C9C99h,02E3D8394h,036393D3Dh,09A9B956Bh,03C262F69h + dd 04B58AF9Fh,0B7B67338h,0CD8EB3C0h,0D8E8E5E4h,0FAFAFAF1h,0F385C7F9h,0DAD0FAE4h,0B36D8EFAh + dd 0637E7783h,041584743h,03F352D3Ah,0A75A3A2Eh,0DAD6E7CAh,0CDC3AAB8h,0C2BEBAB2h,06A664C59h + dd 0A15F4B5Bh,0FAFAE6D3h,0F5FAFAFAh,0FAFAF2F6h,0F7F2F9F7h,0D5E7D8F3h,0A88CBFCBh,0D0E1DCCCh + dd 0D2D1BCB8h,0B09EB6B7h,0AEA8C8C1h,0D1A9A1C0h,0CAACA7BFh,0A29B9FBEh,04E9C9F8Ch,030292537h + dd 04017241Ah,0AAB0AD9Dh,08F9AC1A4h,0B1A09A95h,09F91909Ch,07B76809Ah,08877827Eh,08380858Dh + dd 08E757F8Eh,088727179h,0855A708Ah,08484927Ch,0918E957Ah,060517E93h,085847D76h,05159717Ah + dd 06E6F7970h,09692897Dh,09EB8ABA3h,0B199A6A7h,0A7998C9Fh,091957074h,088969A97h,08E8E9D94h + dd 0739A959Ch,0909D9B75h,09487878Dh,0888B8A8Dh,0958C8183h,077708B9Eh,06C69687Ch,06E6A6F77h + dd 0836F675Fh,088718485h,08F868C91h,07D777577h,0A198938Ch,0A4A5969Fh,08A797A7Dh,095939097h + dd 0978D8C8Ch,09E91A1AAh,0AAA0A6ABh,0A49A9789h,02654BFBAh,034293B3Dh,08F7F786Bh,00B13529Ah + dd 04341551Eh,0B2AB853Ch,0EDB376ADh,0DED7EBD3h,0ECDBD8D1h,0E4A67BDCh,0D8A6EEFAh,068AB88E3h + dd 071745715h,03A475969h,031162236h,0C0B15B03h,0C4CFD2B9h,0E4D4EEDCh,0D1C1D0C0h,04B525BC2h + dd 04B252A2Fh,0FAEBCA99h,0FAFAFAECh,0F6F5F7F7h,0F5F7FAF3h,0B6DEEDF4h,0959098ABh,0FAACAD94h + dd 0C1C0C9D8h,0CAB2EBE0h,09F9CA4C1h,0B7ADB0ABh,0AC91A19Fh,0B9B6AFAEh,08E9895A6h,02C2E241Fh + dd 03B373049h,0AFA99E8Ch,0C8CABAB8h,0AEB5B3AEh,0AB9FACA4h,0708AA1A1h,0696D7E7Bh,066748970h + dd 059575F62h,066534A4Ch,074787067h,051748C7Ch,057556F6Bh,06A566B5Bh,080878076h,06D746E75h + dd 07383906Dh,07E7E7F7Eh,075959186h,0928B7B71h,08B7B7587h,085919080h,08F889583h,0848F969Ah + dd 0738F8E8Ah,08181937Ch,07F7B7B84h,07F8E8580h,06B7F817Dh,0817E7D81h,0716E7681h,0515B656Ah + dd 092807A6Eh,08281909Ch,074958498h,059565A5Fh,0989E6F5Ch,0A5948981h,08884768Fh,08D867382h + dd 093848586h,09FA89592h,097B9AEAFh,0D0BB817Bh,02D58ACBEh,047323735h,06975887Eh,04D91A37Dh + dd 03A3C2221h,0B5A68865h,0C8C36E9Fh,0C4C2CDCFh,0EED8CCC1h,0D8C18CB1h,0E2A2E2F1h,03A9681C6h + dd 053602F34h,033473230h,03E293B4Dh,0ADB2B66Fh,0CAD2C2A2h,0C7B1CBCAh,0D5D9D0C1h,03B1F8FFAh + dd 03B282A36h,0D2E8A548h,0FAF8F6F6h,0F8F9FAFAh,0FAFAFAF7h,0C9DFF4F9h,0A59CA9BEh,0DEAFA39Eh + dd 0DAE0C6C7h,0CFDCCAC2h,099BAB2BFh,0BDA7B49Fh,0B699C4B3h,0C9ADC6D9h,0B1A0B4CEh,02E332951h + dd 02F2B252Eh,0AEB4B379h,0BCC2C9B3h,0B6C0A9C1h,098A3A7ADh,08BA1A5AFh,06D6C726Eh,07D797B6Ah + dd 07873797Eh,06D696472h,07D807E77h,08D7B8980h,091736B86h,078749490h,088857F7Ah,077876B6Fh + dd 061686A5Fh,067737B6Ah,07E8E857Ch,069696673h,060585464h,0565E6A57h,085826F59h,0878A8285h + dd 0648E8F87h,0929A865Ch,0968F8D90h,08E999494h,0758F8F8Eh,08F8B7B86h,08A647188h,07776818Ch + dd 0A0A49C8Ah,0808D83A2h,0697F72ACh,051565A68h,067675E4Fh,0A1867E70h,07E797DA6h,0978D8884h + dd 0A18C8F8Fh,0ADB18E92h,0A2AFAAAAh,0938585BDh,0216DC6BCh,06D2A3640h,03F33567Ch,0BCC18B62h + dd 031411B72h,0BDA79474h,0B8C99B9Eh,0BBC3C5BAh,0E3C8B1CBh,0D6D5B48Dh,0DFB1B7F6h,0ACB06993h + dd 0816D6C7Dh,04E4E4569h,0782D324Eh,0C1C8D6B3h,0CEBE5432h,0B8AFA1B4h,0B8CDA999h,021319FC9h + dd 034323940h,0C98B523Fh,0F8F5EBD2h,0FAFAFAFAh,0FAFAFAFAh,0EAE8F2F9h,093ACC4E1h,0B9A1848Eh + dd 0E2CB9EC9h,0C5AFAFCDh,0A5B5B9C4h,0D0ABA182h,0C2C9D9CCh,0ADC0D7CCh,0A49ACCC6h,03336319Ah + dd 05824273Ah,0BCC5BF82h,0A3A7B0BFh,0A598A9A2h,076A193AAh,07D9599A9h,066686A6Dh,07066675Eh + dd 070687275h,06E626272h,07E7D7973h,05D797779h,0746F7672h,0918D8E86h,0887E7F7Ch,0547A6A7Bh + dd 0756E5C66h,05B6F7466h,079897875h,061626863h,07064626Ah,07A78715Eh,084858A84h,087868E88h + dd 0718F8F8Ch,079887B60h,0818C837Ah,082807F83h,071847D81h,08996918Dh,088809585h,078676D7Fh + dd 0949D9885h,08D86848Bh,0778396A0h,065646866h,07065796Ah,09D848588h,088978EA6h,09D8F8482h + dd 0968D9F99h,08E867C8Bh,09280817Bh,094A38AA0h,02875919Dh,0752B3C46h,03C2B6599h,0A19A7240h + dd 0344A53B0h,0A1998352h,0AEAAB48Eh,0BBAEB4A2h,0AFD0F8C0h,0E2EBE3B6h,0C5D580E5h,0A3896E8Eh + dd 052344755h,02725335Ah,0A272382Bh,053CDFAD9h,0BABE6E25h,0C4C3ACB9h,0A6BCABA3h,01D8FB9A5h + dd 0393D4745h,052494E32h,0ECE9C9B4h,0FAFAFAFAh,0FAFAF8FAh,0DEE2F4FAh,093A7BBD7h,0AF959C8Bh + dd 0A8B399BCh,0A2C6C0AAh,0A6B8B0AEh,0B99C8C82h,0B3C5BFBAh,0AAD8C8A0h,08EA1C9A2h,02C30359Eh + dd 05557322Fh,08E918462h,08F91878Eh,08781A083h,067817F89h,06E929881h,073787D7Bh,0776F595Ch + dd 0726B7376h,06E6D686Fh,07F79726Eh,08075717Fh,08A8D817Dh,07F8B8D98h,0817E8C7Eh,082857173h + dd 06A5F525Eh,071726D67h,078816770h,0615F615Ah,070616F6Ch,08D827769h,082798C95h,08D8A8D89h + dd 0868A878Eh,078767679h,0867F8281h,0838B8D8Ch,079897684h,082939693h,09388878Eh,08374707Ch + dd 07F867F71h,0877C8978h,06B7C8079h,06F656964h,0848A807Dh,0958F837Eh,0818F9A9Bh,089787F7Ah + dd 08D9AA697h,086828485h,094908977h,0929B9691h,043829295h,05349453Eh,047689685h,0988F8F7Fh + dd 03E55748Fh,09D7E4427h,06F7989B0h,08B757B7Dh,0AAA0998Dh,0D1CAB3C5h,0BAEAA7DCh,098A77493h + dd 0677E80A9h,0513B3E4Ch,0C3C69262h,03658C2BBh,09C966C53h,0A0A397ADh,09EB6B7B3h,07ECFD0ADh + dd 03E444939h,04239363Bh,0D7BA8238h,0FAF8F9E4h,0FAFAF9FAh,0E4EEF7FAh,0D6E1CADCh,0B4AEACB4h + dd 0A9A1A5B0h,0DBC1A3A9h,0BBD3B2C1h,0A89DA6B7h,0B9C4BDB9h,0D4D0B6B3h,0A9C0D0A8h,0384047A6h + dd 063C66836h,0AAB1AD63h,0B3AEACA5h,095B8A3B5h,08A8F9E8Ah,07DA6A389h,0878B9382h,07D786070h + dd 07778717Ah,07779716Fh,08C758387h,082858D92h,08D91A99Ch,0768E96AFh,08386957Bh,08B80757Fh + dd 0675E565Ch,07C746870h,087855776h,0656E6E77h,068697763h,08F888273h,09083848Dh,09B8F8892h + dd 07D7F808Eh,093867D72h,069687C91h,07C78796Dh,08A887E86h,080898892h,07C9C9381h,0847F777Fh + dd 06C6E645Ch,0867C716Bh,07B6E8A8Ah,07E797B83h,08F8D9990h,08BA38884h,0809EA996h,07C7F8D8Ah + dd 08195B19Ah,0836C767Dh,0A09B8D79h,0C2B59C9Dh,06BC0D4BEh,0332B2D38h,051869351h,0A5AB9075h + dd 081BC6F96h,097332E27h,0AEA9B176h,0B9D9D7AEh,0E8EEDEB9h,0DCD3EEF8h,0D3E6A4A7h,092A55C93h + dd 0496D8A7Bh,03A3E2735h,0BCC7B46Bh,03F2A76CEh,08D6A5F3Fh,0B6B6B1C8h,0A5BFA6A9h,0CDC4B7ABh + dd 0482936A2h,032363124h,0763C3627h,0EAE2C2C9h,0FAFAFAF3h,0F2EBF2F9h,0E4ECF4F6h,0A39FBAD3h + dd 08F7775A5h,0C6ABA188h,0B9CEB7D1h,09CA999B6h,09BD6B1AFh,0CFE3CEADh,0B6E6C99Ch,02A353AB1h + dd 09BBD562Ch,0BCA9AC6Dh,0B5ACABB7h,098AEB2B1h,0959FB68Ah,07D809199h,0998D937Fh,06D706992h + dd 07A7A726Dh,0867B7A79h,06C757889h,090888179h,08194A6A1h,0608C8183h,0B4A48765h,08B827181h + dd 06F6D686Eh,05A675E6Ch,08EA5847Bh,0828C8296h,089948374h,0807B8897h,09A8D8476h,0784B689Ch + dd 0837C8788h,05E5C8482h,016443A42h,01F22161Ah,0927C4A2Eh,07F767E8Dh,093958165h,06F6F696Dh + dd 070625C5Dh,08F756F74h,091838FA3h,07D867077h,093849B8Bh,098BC9E88h,07DA28990h,08FA6A388h + dd 08597AB99h,085747A7Dh,08E988C7Ch,0959D9284h,06F85928Bh,04A312F2Bh,0A3AE842Ch,09BC4C5B9h + dd 0B7984D85h,01048267Fh,0C2AFAEA4h,0D8CCB6C3h,0FAF9E7D4h,0DCE5FAFAh,0D4E0CF90h,095A6448Ch + dd 0485A72AAh,03F6A5952h,0D2BFB2A0h,0433D2D89h,04D505749h,0BAC8C199h,0B6C29BB5h,0BFD2A57Fh + dd 02C41BCF8h,03D3D3031h,04449432Bh,0D2D1B86Eh,0FAFAFAF0h,0F6F3F7FAh,0E3E7FAFAh,09AACC1D5h + dd 0725D759Bh,0C297958Bh,0C3ABCAD3h,08D9D95B4h,0ACCCA4A1h,0BDBFA9AFh,0CDE0BB9Fh,03F1F64B0h + dd 0BAC15231h,0A4ABB9A9h,0B0A19F95h,094AFAFADh,09DA2A275h,0A5B59E99h,08A7B795Eh,06D756CA2h + dd 08D8C8470h,09C919090h,09F988D93h,08D908A91h,07D779096h,088958983h,07B7E8193h,0838C8586h + dd 05C5D685Fh,062696464h,07A6D7C71h,08B84777Dh,08E8F8483h,0948E8B8Dh,0999EA99Fh,02B18246Dh + dd 0979E8D6Ah,0243D5E7Bh,0252D2415h,01A181825h,02F111D25h,07D909C6Dh,07E7B7D78h,078717583h + dd 062555355h,07A717772h,097958487h,083877E6Ah,09780A593h,0A5B8AB84h,096AD8FBBh,08D958D70h + dd 07D99BCA4h,07D6E7173h,09377786Bh,09CA4A483h,0727D818Bh,0253E283Bh,0A78C4B28h,08FA4C3BDh + dd 0A68A5A6Eh,0303698C3h,0B69C7113h,0ECCABDB8h,0E7E0CEE6h,0C2F5FAFAh,0D4E4E08Bh,0A4B14C92h + dd 0514742A2h,0924A5266h,09B8CA5B6h,043402C45h,02D524E49h,0B4C49746h,0BEC7B1BFh,0CAA69F9Fh + dd 0428AB9BFh,0413A2C17h,03A2C2B36h,0DA913B37h,0F8FAF6DEh,0F7F6EFF0h,0E4FAF6F8h,097B2D5D7h + dd 06377739Bh,0AEAA91C7h,0B5ACCEA6h,0A4BBBABCh,090BA9EADh,0B0BBA6A0h,0B6B7B7ABh,0341590A7h + dd 096BE4631h,09AA5A594h,0B2A6A38Bh,096B2ABAEh,0979B936Eh,093C0A195h,090756985h,069719AB4h + dd 073766D66h,08C847A72h,099AB8F87h,091879B8Dh,086869193h,0B097AC9Fh,08F8F8195h,079868C86h + dd 0786F726Eh,093979C86h,06F3D5989h,091797484h,08C8C9A99h,08B8B8B81h,085BAA9B0h,023252E35h + dd 0547D7D61h,035412B31h,04A252F3Eh,0364C5542h,0180C102Bh,085855223h,0906A6F87h,0756C8297h + dd 06461605Dh,08477726Bh,08A988C8Eh,0897F8E83h,0B187999Eh,07CA9957Eh,09CA58F88h,08D8CA49Fh + dd 0839BB9AAh,081757677h,0878C8573h,0D4A89097h,098949CB5h,024302DA0h,0A26D2036h,07EA3A3A7h + dd 0B37C5095h,062959FC9h,0D9721E35h,0C9F1C9D3h,0DDDAC4C0h,0A2F8EEEFh,0CDDCE095h,075694ECFh + dd 04B533923h,0B67B6661h,063AAAFC6h,06021422Ah,03E544E55h,0A09F3C0Eh,0BEBDB99Dh,0C094A787h + dd 0A1ABADA5h,03F302555h,03E3A3543h,0773C5F42h,0E3EEEABBh,0FAF2DED9h,0FAFAFAFAh,0B2D1DDF0h + dd 0839486B9h,0CEBEAC8Ah,0AB82C5AAh,0A5D1DAC9h,09CC2A4AFh,0AAAE9FA3h,0B0D4B9B8h,02822B6AEh + dd 08FBC5E27h,0A1ADA1AAh,099919497h,08CA59692h,07A837A5Fh,09F6E967Eh,0866B5B7Dh,0706E9597h + dd 06F646A6Eh,08D75787Eh,09AAD948Eh,08E8F8794h,087808C90h,09397AA89h,08B8D7379h,085868479h + dd 07E787A8Ch,08C96A380h,003111C79h,0AD876E3Ch,099837FA4h,0838A837Dh,050A8A5B1h,05A502E25h + dd 0252D3F68h,060492D34h,064564167h,0908F8081h,034214277h,079442637h,07F5F6B79h,076667A93h + dd 05C5C5650h,07668645Eh,07A797F7Ch,092717885h,097859995h,085888480h,08B7C7B80h,0999EA59Fh + dd 0828F9F9Fh,0716D7D80h,0707C7877h,0B49F8381h,0B1ADBABAh,03753A1BEh,069263353h,0807B7B7Ch + dd 09F7C408Bh,0827F9086h,06D25497Dh,0B7BB90C7h,0D1C8B8B2h,0A6D1CAC8h,0BDBAB7ADh,0592783B8h + dd 06C7E755Ah,0A5AB637Eh,02F7EBB9Dh,044332A1Bh,044573E47h,07A5F4B49h,093BFB2B7h,0B09D8C86h + dd 07C988AB8h,0395C979Eh,04B585250h,0605E6B5Bh,0C4B19A60h,0E5D9E1D0h,0FAFAFAFAh,0D8D5E7F2h + dd 0B2AABBD5h,0B1ABA3B1h,0997A9D91h,0B1949FC5h,0B6C2B5BDh,0ADC4B1AEh,0B0B9C3AFh,03C73B3BBh + dd 095C3673Ch,0948D969Bh,0AEA69FA0h,0A8ABB09Bh,0979294A0h,0A87C858Dh,09E95A5A6h,0769D8593h + dd 08D887D82h,08C888489h,0AAA38F8Bh,082778D9Eh,06B7EA18Ch,082A19C7Dh,09C948F76h,089777E8Ch + dd 0777B8B8Ch,09483A082h,0130D2B83h,0908B5F22h,0907F8595h,0869D9384h,025529D90h,060744A2Bh + dd 02D1F1E41h,0A77B5536h,083858FA3h,097AA998Fh,031567B87h,0272E422Bh,0736A7062h,071696A8Ah + dd 076736151h,099857977h,092A1A8A9h,09A808E8Bh,0A69BA09Bh,08E878697h,0AAB6898Fh,0B8AEA3A0h + dd 0C7BFC8BDh,0BEB5C9D7h,0A8C0C0C1h,078A08F9Dh,0B79B9496h,07193A1A4h,0403D421Eh,09E99A689h + dd 0AF70638Eh,09B9C95B5h,01F6BB2ADh,0A2A29934h,0ABA29AB2h,09899969Fh,0BEC2BAB0h,04994C6CDh + dd 0D6CCDAC0h,0D1E59A91h,0445AADC8h,0413D5C4Eh,07EB85B3Bh,048514A53h,0E0D89964h,0E7CCABB8h + dd 0BDE4D0EBh,05A9EBFBAh,0292E1517h,03C3C1919h,054363937h,0E2AF7763h,0FAFAFAECh,0D7E5F9F9h + dd 0B7B6CACDh,0C8A2A3B3h,099C8B4C1h,0BBB6BADEh,0B2B6BDC0h,09CC7AD9Fh,0B2BCD4C0h,01B69B3B3h + dd 0B7D68A32h,0A7B2AEABh,0BCAFA19Bh,0B5B5BAB1h,0BAB7BAB6h,0A9859CABh,09A97999Dh,0777A7D95h + dd 08A866E70h,0896D6677h,08D988A82h,0A9918A93h,07E89B8B0h,08C9DA195h,0828E9272h,07F969890h + dd 087899E92h,0887A8A8Ah,021184781h,093884C3Bh,083767595h,083869086h,02A285287h,02955604Bh + dd 03B2E2522h,0A3909F76h,0A7949EADh,0A1918C9Bh,06E77869Ch,02C352B33h,05F6D651Ch,074716566h + dd 070736555h,0998C796Bh,07E8DB49Dh,082748D90h,09A9F9C80h,09A938B9Ah,0D0A38993h,09FB3B7CAh + dd 0B19CB5B6h,0CBC6C9C9h,0AFC2C9D1h,0A7B29F96h,0CBC0B1B3h,0A3A7A8ABh,02211125Ah,0B5B4B046h + dd 0A27B54B2h,09191A9E6h,088A0A8B1h,088571C37h,09BA2AC8Ch,0909CAA9Dh,0C0C1C5A4h,0A7AEC9C3h + dd 0D6CFB754h,0D0DBAA4Fh,0484A57E6h,0302E234Bh,0907D8D22h,045454769h,0DF975A4Fh,0E3C4C2E2h + dd 0B6CFDFD5h,090AAA3AEh,035192B60h,03849463Bh,03B2E3135h,0CC583034h,0F8EFEFE0h,0E0F8FAF7h + dd 0BED8D6D0h,0B0AAABABh,098C191ACh,0B6B8B9D0h,0A6AAC0B7h,0A4CFB19Bh,0C3D4D5D5h,02866B1C5h + dd 0A9BDA02Bh,0BFBFB09Dh,0B6AEA3B7h,0A79E9FAAh,0C1BEC0B6h,09E7DA1B4h,08B909495h,081746A87h + dd 0776D7A79h,0998B807Dh,08D989F97h,0857D8175h,095653D74h,096847F8Bh,07F7A8486h,0788A8181h + dd 081777772h,082818687h,033335885h,07A805F39h,077898C79h,09B94908Ah,042232566h,02A455B73h + dd 07F4D332Fh,0828494A1h,07FA49590h,07E8C8387h,07A847E7Dh,0331C4263h,0604F4139h,07F756A4Fh + dd 06E72604Bh,091917A66h,0777EA781h,0987F9B8Ah,08FA4A79Dh,09B8F8CA2h,0E0B08C98h,08A888CB9h + dd 092818987h,0B8B59D95h,0B6A0AFC1h,0A3AAC5AFh,0C8C6A899h,0A0CAA287h,0202371B8h,0A7B4681Dh + dd 0A96966A5h,096859595h,048789A9Ch,02C224844h,0A9AFAE66h,076789A9Eh,0CDB7A48Bh,0CDE0CDD0h + dd 0AF81429Ch,0DFB4D132h,06B1C3A70h,033352940h,05FA0E09Eh,045425A63h,06549494Dh,0D3909BB4h + dd 0CDF3FAFAh,08D8C929Bh,02D73858Ah,04E342A26h,032301C4Bh,0A7322E21h,0EEE2E7D3h,0E5FAFAF7h + dd 0A8C5D4D1h,09A8A98A1h,097BAA5C0h,0C0C3C2B6h,09490B9B3h,09CB7AEA0h,0C2DFB9D9h,02564ABAEh + dd 0AAA9B12Fh,0B4ADADA1h,0C0C1C0BDh,09F9DA9AAh,0C3BEC1ABh,08972A5BBh,07577777Dh,0807B6986h + dd 0645E8D89h,07D7F786Eh,07B698A85h,08BA6877Fh,0B48B6782h,0A97F79A1h,091878D87h,0879A7D70h + dd 0575C5E85h,02B373A41h,02D242A31h,09088501Fh,094907482h,089AAA0A9h,082452923h,037453962h + dd 087624D32h,09A7B8FA8h,08C8D7F88h,074728595h,067747765h,02D347273h,086410D2Dh,089848B81h + dd 0716F6B6Ah,0708F7974h,081899479h,0888E898Fh,0829AA298h,0A8969885h,08D8A9290h,07B749AAAh + dd 063787C89h,07D799E8Ah,0AA8F9C61h,0B294A6AFh,0ADB2BAB8h,097AB5E74h,01161C5A7h,0A6A04629h + dd 073529290h,0AD7D7D9Dh,02C78B79Eh,0544B392Eh,09A54473Ch,08598AEBDh,0A7988779h,0DCD9C2B9h + dd 03C63B7E0h,0A5ADBE7Dh,05C393341h,0965D303Fh,0A0C9D9AAh,0395090A6h,04B4F5E5Eh,0A99B8250h + dd 0DACAE5E4h,0878D90CEh,08FB9978Bh,03436233Ah,038363B31h,09E371D2Ah,0E0D6EEE0h,0D8E6F0EAh + dd 093C0D0D6h,0776E7882h,0A4CF9EA0h,096D3A0A1h,0B99CC4D2h,0C1C6BDD2h,0CBCDD1C2h,0397CBBCFh + dd 0A9B9AA3Ah,0C9C0C0A7h,0B2BDBBB7h,0B8AC93A5h,0B9B2A9B3h,0A0877EA1h,09CB2B69Dh,08B837D7Bh + dd 0825E858Eh,062638B75h,070716D7Bh,092926465h,08C87667Fh,0624E2F86h,04447545Ch,02439374Fh + dd 02E2D201Ch,03637332Bh,026222235h,088975E20h,0AE977B7Fh,03D84AAA5h,0978A5722h,038424751h + dd 0A49D6842h,0AE8D8A89h,08D7C6786h,07F8E8586h,07482857Fh,018627D7Eh,0560E2213h,0788B929Bh + dd 07A7C6B5Eh,0787F827Dh,08D5D748Eh,096928F96h,07F89A8A4h,0B7989E99h,087899CA3h,088A9BAA6h + dd 0A9AEA196h,0999D9EA1h,09D9B949Ch,0B8A6A5A1h,09AB8B5A8h,0D7AD7281h,061ADC5BAh,09752483Bh + dd 04973B1B8h,04B529186h,05095B6AFh,059525A35h,05E325350h,0B6979E9Fh,0C8BEAEB3h,0E5DEE7EFh + dd 03AADE2DFh,06DB3CF6Fh,051443538h,0A3AA604Dh,094ACB2AAh,0679C997Dh,04A4F4652h,0B48F4B40h + dd 0D9C9C2AEh,087959EC0h,092ADA174h,04B49758Ch,0665F6464h,0C2714E5Ch,0CBCFE9D8h,0C7E0E3D6h + dd 0B6D0C6BEh,09497A3ABh,0D3CA9376h,0CCDEAB9Dh,0B7A4C0CEh,0B19EB1CCh,0B2B6C4C9h,04B87BFBFh + dd 08FA4A239h,0A4979F94h,09AA19EA2h,0A0968F8Eh,0928F92A2h,082827985h,0737A8190h,08F91837Fh + dd 079768E91h,08269816Fh,06C725D74h,08A776462h,0957F7083h,02C30227Bh,024161E21h,0565D5B4Dh + dd 0706C6E80h,07B888275h,01B1E4A6Ch,08275582Ah,0998B9086h,01E337296h,073947444h,04C3A2E2Fh + dd 09687834Bh,09D9B9488h,07A64746Dh,0706F8187h,075888372h,04479837Fh,01E151A12h,0735F8077h + dd 0687A7C77h,06F6B7060h,07D91987Ch,084818478h,089849384h,0A4989292h,0AAA4A99Ah,0A69792A5h + dd 094A49492h,07D779A9Eh,088917C8Ah,08C839495h,099ABA491h,07F938B7Dh,0B79B7877h,0571F306Ch + dd 0498692ACh,0706D615Dh,09E9D5D39h,04447746Bh,03D4A4D48h,08E6F7E5Eh,0CAB0AF9Dh,0E8E1D4D1h + dd 04F8ED9DDh,0486D8F8Ch,04D523A54h,0B3A9A469h,0B0AB9EB1h,0989FA8A7h,0554C5491h,065454C4Ch + dd 0B5A8C4B2h,0A6B4C7C8h,08D807997h,046477FAEh,05B545B66h,0D39D5C5Dh,0E4EAF6E6h,0EEFAF6EAh + dd 0B3DBE8D8h,0A6AD9C9Fh,0D9BE8291h,0D0BEB8A7h,09C9DA9B7h,0B890BFC5h,0BFB6B8BEh,043A0ABCFh + dd 0A9B8AC3Dh,0B7A4A3B1h,0BCC1D2C5h,0B5B1BEC5h,0A2A2AAAAh,0B9C09A9Eh,0C4A3B5BCh,07E7D9CCAh + dd 0808F8589h,0677FA790h,07165687Bh,0836E6D5Fh,087979598h,04124377Bh,0702C1B2Ch,08084978Bh + dd 0796C6E80h,079827775h,0262F6070h,0806D4D25h,071584E69h,02F253563h,05A8C876Ch,05234352Ch + dd 07D6F885Fh,085888374h,073606C82h,074777472h,06F7D7D73h,069837F7Bh,01F201A3Dh,06D737F2Ah + dd 082807B7Ah,0785B7978h,08BA2A690h,0868A9A98h,082858175h,0B9A6A792h,093A6B9ACh,0AEACAD8Ch + dd 0838AA39Eh,0B1898480h,0A3859086h,0B5A1AAA9h,0B4B2C6D2h,07693B7A1h,087856B7Eh,03E282769h + dd 0618BAA83h,04C4C5640h,09F744F82h,0494E89ABh,034394A45h,07A759E70h,0BFC7A486h,0F4EBE9D8h + dd 06E78C0F8h,0424790CAh,046415337h,0A6958E7Fh,0AF9582A9h,0C2BAAEA9h,0432F59A0h,04D603B43h + dd 0C9D58844h,08C8AAD94h,0717A8D83h,051483248h,03C31374Ah,0D2BF6247h,0F2ECF1EDh,0F3F8F6F6h + dd 0C6E7E4DAh,09DBBA7A8h,0C3CB4AA2h,0E1C2BDB1h,0959EC8E2h,0C370A8B8h,0C3AEA8B0h,0309BAFD3h + dd 0B0B4A02Ah,0CFB4A1BCh,0C5CED5DFh,0B4A7ACBAh,0A09E9CA0h,073837088h,0F8D094A5h,072609CDDh + dd 06985828Eh,0766B948Dh,00A22467Fh,07F886214h,07C6E6E82h,03B395174h,075342C2Eh,070707E90h + dd 07D797A8Ch,07880827Eh,02A296473h,08C866433h,0637B7581h,05F441B35h,04D789186h,0574A2A31h + dd 0867A7C83h,07A858478h,082817F88h,0787D7A7Eh,0717D7E75h,07079737Ch,0282B2F5Fh,057625223h + dd 063848E8Eh,05065756Ch,087818A75h,0707E8478h,068657163h,098796B72h,07FA49199h,0B3B68379h + dd 07F829993h,095996D68h,0959F9993h,09C96928Fh,0A5A3BBD3h,083A4B7AAh,04A947C86h,027303531h + dd 09F668669h,04A295E5Fh,053435054h,046849DA2h,0404A4650h,092987741h,0D0CDC8ADh,0F2F8EBE5h + dd 07C5A9ED7h,03A4265E1h,097564637h,0958B9CB0h,0B58E7DA7h,09BB5A59Fh,03A87AFA3h,051484E37h + dd 09F4C4C5Ch,096C392B0h,02B67858Dh,039453633h,0442F3341h,0E3C4933Ch,0EEE6FAD6h,0EFF9F8FAh + dd 0E8FAEBD6h,09FC499C2h,0BE964ACAh,0DFB5C4DDh,0B4B5C9E4h,0CB74BDB7h,0B3CB9EC9h,020A4B2DCh + dd 09BA6A540h,0C4B7A897h,0A9D1CDC8h,07524557Ch,0B3A16068h,07192898Bh,0CBDFD1BBh,0B6A6AFC5h + dd 05D6B8784h,0664B8C8Ah,0401F5B65h,09E9F651Bh,07D737389h,04E47589Dh,07D33363Ch,073779AA6h + dd 0686A5C64h,04A55615Eh,027366D55h,078735C38h,04B989B77h,0926A2437h,05B90998Eh,056463A38h + dd 07D8B827Ah,07F85978Fh,0829198ADh,08789888Bh,07E897D72h,097847673h,0361B4B95h,07E923B29h + dd 05A86908Bh,0586D6E59h,08E909968h,0777C8385h,06B7E7E77h,0927C7F6Dh,09EA5859Ch,0AD958387h + dd 085839DA3h,088977C77h,08C909090h,0809D9D79h,0B3C0CD9Bh,0A1B3BFBAh,02C538094h,02D2F363Ah + dd 0A3AC833Fh,060546A80h,0353D555Ah,06094A745h,04D435445h,0AD955A48h,0D7C9C7ADh,0E0F4F8EEh + dd 0595162D1h,03432418Dh,0A6903622h,07471A3C2h,0AB8E5F62h,09E9E848Dh,0A1C3C29Eh,04F5A4754h + dd 03F263F63h,0B2C87A57h,0293F6E95h,03F493836h,02B633A4Ch,0E3D8BE5Ah,0ECEBF2DDh,0E7E9F4EFh + dd 0BDF0E2D8h,098949BB4h,0851E59B4h,0EFABC9D6h,0C6CED4C2h,0C087BABEh,0C2C479BEh,0349FA3C0h + dd 0096B9B2Eh,02D150902h,031364241h,0160A002Dh,0A05B0642h,095888B96h,0BDD8BBB7h,0B3A7B97Eh + dd 01C268DA1h,0859B9251h,01F21717Eh,0A9A45A23h,0717DA9B6h,0312C357Eh,068292426h,076798E98h + dd 06D626F87h,0675D5E6Eh,015327863h,0878B4E2Dh,0345EA780h,0A1824149h,04C859BADh,07551342Eh + dd 099A88C93h,05A688493h,08F868885h,07777817Dh,05170836Ah,08A786257h,01C427894h,08B863325h + dd 04E7599B3h,0494D5555h,093897C60h,097928B9Eh,08B9D8F79h,09991A891h,0B1A491A8h,0A49D9596h + dd 0877B7692h,0957A6C78h,0B4AFACAEh,0998FB1C6h,09E978383h,0ADB3A89Dh,0402B347Dh,03C32332Eh + dd 0ABBE524Eh,0907F6082h,05173608Bh,098654656h,050574649h,0BF94553Ah,0E5DCC8B7h,0CBEEEFEFh + dd 0615035B7h,01A172A5Dh,08D916C2Fh,08473A2AFh,08C8C5D59h,0967C6A78h,0A29D919Ah,0464A84B7h + dd 04B444661h,09A6E3B45h,02E315DB4h,0363E313Fh,033452E41h,0E1DDD499h,0E7E1E7EBh,0E6EEEDE3h + dd 0B2C5CED8h,0AF8D88ACh,06E2675BFh,0EFBAC0F2h,0B7B4CAE0h,0C1929FA9h,0CEC87DD3h,0379DACDDh + dd 080B28D4Dh,019243856h,03127141Ah,0AA984517h,08A6D2287h,0A380788Fh,07FA7B794h,09F778753h + dd 01A1969AEh,079935F26h,01C28757Eh,09E865C16h,07D86A4A6h,02F2C2070h,05C2A1F21h,07A7F8E9Bh + dd 0758C876Fh,080605163h,0163E807Bh,088956431h,0293F7C8Fh,0A28D6A50h,0468D8180h,084433C31h + dd 08787999Dh,07E848E8Eh,06D768185h,0796D5B83h,06888866Ah,06C615857h,0276F9E8Eh,0B9712430h + dd 04F6C92ACh,060646F67h,07B92986Bh,0978A9279h,086858381h,08F8E8A85h,0A8A59593h,0ADC0BDB0h + dd 0978D8A99h,0977B7C8Eh,0939794A1h,073928E95h,0A99EA391h,0758FA2ACh,03E433133h,055485351h + dd 0A6B54B2Fh,097AE717Ah,057595A75h,05C354B68h,0474B4971h,0AF895737h,0E6D9C7BFh,0D1C8E0DFh + dd 0664139A4h,034313D45h,05E678062h,06D7B7C70h,079796263h,088778182h,0857F768Ah,06EA6BAA4h + dd 04E5C5167h,0604C5357h,041687F5Eh,043504642h,08D50474Ch,0E4E5D1B6h,0E9CDBCEBh,0DCEFE9E2h + dd 0ADD2D3D6h,0A2979DAFh,02F3E94CBh,0B397C4B2h,0BAA5BAC9h,0DAA1A3BEh,0C7BE92C1h,04C9CA4CFh + dd 0A9CF915Dh,098A4B1A9h,049538894h,0B38C3A3Fh,08B953072h,080919596h,04B768997h,09C707456h + dd 0180C4C98h,06C84622Bh,020376680h,0816C571Ah,077768486h,02D2B0856h,04E2B1F24h,0767D777Dh + dd 075738C92h,07E7E8286h,028629886h,08D8D6A36h,04C31428Ah,06C6A8C6Dh,0449C9365h,09F5C3930h + dd 08E899096h,07C848890h,07D707B76h,07A65866Dh,05F656971h,0806E5F5Ah,036759AA0h,0A3774134h + dd 04F5D6F70h,04B3B3E4Ah,083605C57h,07385887Fh,0AD828070h,0A9B5ADADh,09C9C8E8Dh,0A8AA99A2h + dd 0A2928A9Dh,0C5B6A3A1h,092A4C0C0h,0A494A59Dh,0BFC4BEA9h,051C09FBBh,059554E4Fh,0484D5454h + dd 093714140h,0AB8974C3h,06D858D88h,081465857h,063584F7Dh,0AA805F5Bh,0E0D8CCCBh,0E9CDDEE6h + dd 05857505Ch,06D413936h,063617575h,06572696Dh,0715F6D66h,07C6B919Dh,074888E74h,0B3D188A5h + dd 0517655A8h,0514A4F57h,050544245h,044424C43h,0AA856451h,085B1B1B0h,0F3D56493h,0ECF8F4F9h + dd 0B2D7EAD4h,0C39BC49Bh,02D31A2C1h,08CB4FA9Ah,0F0B1D3BFh,0C5BCA8E8h,0CACCD08Bh,056A1B6DAh + dd 0B4E0A85Ah,0C6ACAFADh,0363F74B5h,0AEBAA260h,097AF3733h,06C998664h,0262978DAh,0C1B9843Ch + dd 02E174297h,0506F6F25h,014215D66h,08A6A4E12h,07E716F81h,033382760h,0542B1924h,0818B9376h + dd 094878189h,0897C707Ah,02859937Ch,08B80653Eh,05C294159h,083819182h,046A39789h,08C634C3Bh + dd 086958D90h,06F888695h,05E68746Ah,08980737Ah,06769877Bh,081876365h,0567E968Fh,09F412526h + dd 06A78888Dh,060514F60h,0926F7569h,091988F9Bh,0B098A391h,0B6C0C4B9h,09E947C95h,0B1BAB2B3h + dd 0C2CAB5AFh,0E1C5B6B3h,0C8DFD8CCh,0AEBDABB0h,0B3B5AFA9h,04C449AB0h,04842424Ah,04D4F3F4Eh + dd 09C475354h,09F916890h,044776C60h,083645647h,053595D91h,095715449h,0E6DED2BEh,0B7D8E9F3h + dd 040693953h,066584828h,069517458h,0706D7278h,09066767Ch,07574637Ah,073719279h,0A3B68597h + dd 05975A1DCh,0544B3D4Ah,049465144h,040424856h,0605D5548h,067676566h,0F6E4624Fh,0F1FAFAFAh + dd 0E5D7E5D3h,0C4BCBFBCh,06554BCC1h,08CD5FA74h,0FAEAFAE3h,0F8D7AEFAh,0E4BEBA93h,05CA4C0D7h + dd 0B6D69A45h,07EA39593h,0A87E4C35h,05CA3C0D5h,041C84912h,096A9781Bh,02A2C3A89h,08D7A703Dh + dd 05E4D4271h,06A6B6E45h,03A51716Ch,08E915A3Dh,080757C8Fh,0614B5C88h,06A4D384Dh,0817F9A93h + dd 0837E8E8Ah,0847E7D78h,02E6D8F8Eh,06C9B5C3Ah,0A1562536h,0938E99A1h,0438E738Eh,085774754h + dd 084948A82h,08286838Dh,0776B7A79h,07C837E6Ah,085746B69h,08A8D838Dh,05073908Bh,051202A33h + dd 07E83969Ah,08D847A7Dh,0928DAC94h,090898496h,0AB938D8Fh,0B6B0B4A8h,07A8A85ADh,0B1B4AF91h + dd 0BBC8ACADh,0EFC9B4ACh,0A4C8C7D4h,0D3A99398h,0A0B5B6BFh,04B334FA9h,055423B46h,0474B3A5Eh + dd 0C3394D3Fh,060546F98h,065406960h,04C453F42h,0555B6784h,07F716A5Dh,0DFD4C5A8h,093BCE4EDh + dd 027775753h,04B5F5A31h,083927157h,080697D8Bh,086727E8Ah,05173908Bh,068758078h,0B8B9917Eh + dd 08FBAE3B7h,042313F61h,04D4A4E44h,0484D4F52h,0604F4A4Bh,06653575Eh,0F3E3B75Ah,0F2FAFAFAh + dd 0D4D7E3D6h,0BFB0AEBAh,05F94D5C4h,06CDDD541h,0FAF2F7C7h,0F1DAAEF5h,0F1C3AD73h,05BA1C2CFh + dd 0CBC69B4Bh,0293B99C1h,0ABA9B693h,01670D3C3h,01265BD22h,068B6C447h,02A183D70h,07E7A6D52h + dd 03729274Bh,07273794Bh,02F1E6F84h,0936D2B33h,0B495868Eh,0713D377Dh,043382C4Fh,082899B85h + dd 096899484h,094AAA893h,034777D94h,031584333h,07C6E442Fh,089868B86h,033717F6Eh,08E914F38h + dd 0999E8C7Fh,088889395h,07065667Eh,0708A887Dh,086625E68h,08C8C93A3h,076859089h,04D0E1029h + dd 07C738185h,0A0A0978Bh,094A4C6A5h,094817D90h,0C0A89994h,0B7B2C8B7h,0718993C4h,0BFBDB188h + dd 0D9D8C9C2h,0ECD9ADB1h,0A196C0C9h,0AD8F8EA3h,0B6B4B0A8h,036483093h,083543A43h,04248434Ah + dd 069394040h,062719A7Ch,0817E7465h,040375894h,054677752h,07B726252h,0D1C2BDA2h,07DC6D9DFh + dd 01E49955Bh,04B505A5Fh,081754C56h,077717480h,077727667h,056465E7Ah,07375594Ch,0A6C7AF97h + dd 0A4BEB6ADh,0495880ADh,049493D38h,047464144h,06245474Ah,05B555263h,0F1D9CB9Fh,0F2FAF8F7h + dd 0C6EBE4D5h,0A8B4C0C2h,051BFC3B9h,095D3B64Bh,0BDCBBF9Dh,0CDC6A9CCh,0E5D0C77Ch,0529BBEC1h + dd 0C3C8A848h,0C063409Eh,0DDB3A3C4h,04C2575C3h,024345B9Dh,090C5B87Ah,03E1F4293h,0796F7A78h + dd 02F292240h,068727D5Ch,03837696Eh,0AC68333Dh,0867F8AA5h,06336364Eh,03D3F335Fh,08D8E9677h + dd 08F838484h,09CA29C8Dh,034799195h,016263E29h,0766E4538h,0A48C7880h,039A26784h,093884838h + dd 09F957D85h,0867E948Fh,08262587Ch,0608C8883h,083656154h,089918591h,072757E7Bh,04C070F48h + dd 090707D84h,0A7ABAEA3h,0ACB6C9A8h,0968B89A2h,0BAB8AB9Fh,0C1C5D8BEh,08B8A99C5h,0B6C4B39Eh + dd 0D3CCB8ABh,0DFE4BBB5h,0B09EC5C0h,0A4818CB2h,0AF9EAAA1h,049423E53h,0865B463Eh,046464235h + dd 05349413Bh,05F84A58Ch,0BCBA9D8Fh,05C4D79A7h,0495C6035h,054515149h,0D8C29572h,053B2D5E4h + dd 0635CB365h,062627598h,06C71656Ch,088757668h,056526962h,0473F5964h,0433E4038h,0C7E8A05Ah + dd 0B0DBBA9Ch,05F90C2B9h,04646413Eh,04F4D4944h,05C4B4A4Ah,0614A4D5Ah,0DCCAB5ABh,0EAF2F2E9h + dd 0CFF0DFD5h,0B0BBBCCDh,043ACA8B1h,0B8C87A5Ch,0CDE5CF8Bh,0C9D6A4DBh,0DAD2C76Fh,04993C1C2h + dd 05598A22Fh,0CBDCB659h,0ABC8C9BDh,0695A485Ah,031AF7551h,0D3B0B69Dh,0704F368Dh,0897F7A8Bh + dd 02D261A3Dh,0756B7C61h,02E1F669Dh,0A04F3931h,0896F899Ah,07125264Fh,02F31325Ah,08E869073h + dd 0A5918294h,093818796h,03175ABA2h,0291D1B1Fh,0536F6963h,06F6A7769h,02D8E8F77h,0AA844341h + dd 0A9978895h,0827F8989h,09B5E5C80h,083848B77h,071685E5Eh,082958A7Fh,05F5E6665h,04914194Ch + dd 08976878Ah,09B929588h,0A2A9B39Dh,0897B9697h,0A6A08685h,0B8C7D5BAh,0868A96B4h,0A9A29396h + dd 0B4BFA4A3h,0C7C9AD9Fh,0959EBFB0h,083727B75h,07B978D85h,040424237h,05A716C42h,03F3F3B33h + dd 04E3E4543h,04A7E9E6Eh,08BA1B498h,0523F6793h,063915C3Ah,054594F5Ch,0BCA4795Bh,05778B6C1h + dd 083919072h,063716E84h,08670725Ch,05A59645Fh,03B454951h,053424140h,0424C5250h,0CB7E4947h + dd 0C1B3AEA6h,099D9E5D3h,03B386270h,05A4F3E4Eh,0544E4D55h,0494A5354h,0D9C66E4Ch,0EAF3F8EEh + dd 0D4E2E1DDh,0C0DDC0D4h,055BBBABAh,0CBE74B71h,0E8F1BFA8h,0CBF3AFF0h,0E4EBE078h,06695C7CEh + dd 07B4D4767h,0C7D2C4C1h,04989C0AEh,0753C3239h,02F63D494h,0AEBAD9C1h,09C7B898Dh,0A4A88C9Dh + dd 0413E2D42h,0687E7355h,03E2A6E93h,0B44C3D32h,09675B38Eh,07D363A47h,0302E357Ch,087848E62h + dd 0A1B7A385h,08B929C95h,03F82998Bh,050191D2Ah,05C6B5472h,0827A806Fh,03F8BAB7Bh,09E654032h + dd 0A190878Bh,083808889h,0846C6076h,05F919982h,081645550h,06A73808Ah,05B617168h,0451E2762h + dd 0847F7C6Ch,096868471h,0B3ADA993h,08F9AACB0h,0A8B4A584h,0ACBDC7ACh,09987A7B0h,0B08E9C8Ch + dd 0C7BDB6BAh,0DEDECDC7h,0C0BFDAC7h,0B281A8ADh,0439BADBFh,03839493Bh,02C87853Ch,04A474139h + dd 0463C3E4Ah,0629DB94Ch,0A9ABAE86h,059496587h,062A9485Ch,0544C3F5Eh,094844F51h,06956B1ABh + dd 0869A8CA9h,0686A6278h,0838B745Eh,07767877Dh,0515A3C6Bh,038402F36h,03B404543h,05F3F4537h + dd 0D3DBCD97h,0C4C5B5E1h,04DA0E9E1h,046403A3Ch,04E4A474Ch,0494A4548h,0E4C17638h,0F5FAF6F2h + dd 0E2DDE7E5h,0D1D1D2F5h,099A1AEBEh,0CBC12A5Dh,0FAE89CDDh,0F1FAC1EBh,0CCFADF95h,05FA5DCCCh + dd 0B09F6652h,0BED2D3BBh,032537FC6h,0AD9C622Fh,0771087BCh,0B49EB9CDh,0A89BA0A2h,0B4AF8498h + dd 063724758h,06D5D6A67h,04B42607Fh,0AA4B4E42h,09BCC83C3h,0A33C2D45h,03A39276Dh,07C7F8757h + dd 07B86A69Eh,077767982h,0367E947Eh,05B2B272Ch,0757C657Bh,093978F85h,05C95A892h,096664640h + dd 093888388h,088748C8Ah,0917A727Fh,0787A8B92h,0837A736Fh,05C626E80h,077675C4Ch,054221A58h + dd 08269554Ch,09D8F9279h,0BCA98F92h,084B6BFCBh,0A7B2A27Dh,0B5BECAB3h,09681C1BDh,0CCC6B187h + dd 0CFBCACBBh,0D3C0BED1h,0AAB6C2CDh,097BAB5C3h,03760A4B3h,03F41444Bh,0197F9C55h,04C484034h + dd 052574651h,07EB69631h,06A9BAB49h,0514B515Ah,0769A4C54h,056454159h,06352515Eh,05B507B76h + dd 0768CB299h,05E575876h,075836A6Ah,06A6B5246h,0685E505Fh,0404D3E47h,0555B5751h,05A4B584Dh + dd 0CDB05349h,0B6BCB2B4h,0A4BFA9A7h,06E899B9Dh,0453D3660h,056503E3Eh,0DFBB7144h,0F8FAF4E8h + dd 0AFE4DFE7h,0D6E3CBB6h,0ABB2BDC4h,0D9814650h,0F9CEA0FAh,0E9FACADCh,0CBF5CF99h,0777ABAE1h + dd 0907E9994h,0D0C7E7D3h,074494F5Bh,0E9B1B0A0h,08E182CA6h,0A6A0CDC1h,0BAB9BEA2h,095A297A4h + dd 061575D62h,07A83A394h,0684D507Ch,087576255h,091858D83h,08A66634Ah,030425394h,07B7B7E43h + dd 07B818467h,08E8A908Fh,030558799h,070493437h,0818A8598h,0A2A69794h,0779D95A4h,08D644749h + dd 095848589h,095858987h,0A07D868Fh,07D7D718Fh,06E62616Ah,06C809386h,095878676h,061322771h + dd 075625D68h,088888B73h,0B69F797Eh,08CA6CCCAh,0A5AFA186h,0BBBBC3B4h,08895C1BCh,0D7E2B59Fh + dd 0E0E4B9BAh,0BDB0AABFh,0ACA7AAC9h,0B3A8BEC3h,0323490AFh,033444345h,01868A87Ah,049423E38h + dd 06A82544Dh,09BBF6C36h,068B88344h,0383B3942h,098784133h,04B35324Ah,05E56515Eh,067754F5Eh + dd 077929E37h,063685E70h,05251726Eh,0414A6257h,041537347h,0353A271Fh,03D474B50h,048313341h + dd 0863A473Fh,0A29DCCD6h,0B9848395h,092B5AFBEh,04C4D5153h,052465759h,0D9B35241h,0F4F8F2DDh + dd 0DAD8E4E3h,0B6C6B4D8h,0D9B7B7B0h,0EB475C8Dh,0F4AA9AE6h,0ADF7D1DFh,0DECCF0C5h,0B9C6E9DBh + dd 0BBA37779h,07AE9D6C1h,0B8A47E5Dh,0C8DAB1A8h,0A5480B60h,09B90A5B6h,0B7ADAC99h,07CC3B3B3h + dd 09257675Dh,093AD9CA0h,06A5E7D88h,05D54473Eh,0A9AE8A94h,0946D5248h,02F2C53A0h,082807637h + dd 088817E77h,04A6F898Eh,026182D30h,091452E2Dh,07F8586A3h,0A595999Fh,07C9490B0h,07C4D4345h + dd 093778A8Fh,07EA59684h,0626B5F61h,0968E5358h,0707E707Bh,06D829079h,0808E9772h,0642D1558h + dd 06A6C7380h,06E878C74h,0A3957964h,08CA3A9A9h,09CA7978Ch,0A8ABA7B3h,08E92C4AFh,0C7CFA79Ch + dd 0BCDBCDB9h,0D3B09BA2h,0A6A0B7CBh,0A8A6B7C1h,0493D62B2h,03C2D3B44h,0A2969883h,078616A8Ch + dd 08EDDC9A3h,0BBC3573Ch,0646F4C84h,041404456h,0C361444Bh,04B484D5Ah,07749565Ch,0A1807CABh + dd 0899D6150h,077777B79h,05759535Eh,05E4C4F5Eh,061586C54h,0302C4B3Fh,03E54473Eh,07B5A3934h + dd 0324C5271h,09EAA8B62h,0BFAEA196h,061B6C0A6h,05C553A2Eh,02C425055h,0C0804639h,0EFE9E0D1h + dd 0DCD1EDF0h,0A39DA6CDh,0E5DDC2AAh,0F65F89D5h,0E99EE1D6h,0A3D7B2DDh,0DBDFE4F3h,0AC8E99B5h + dd 0C0BFBEBEh,0C5CBCBBFh,0B9B5B6C7h,094D9C9AAh,090731553h,091A59591h,0AA8F9F90h,047B6B6AEh + dd 0955E6D50h,0C88D9295h,03E3C69ACh,047495F4Dh,092A18E78h,07E615244h,0201F509Ah,04252553Ch + dd 01F1C3543h,03825322Ch,01E10233Ah,0662F2D1Fh,0839CB5A6h,0B89C948Ch,0949B8BB0h,06849425Ah + dd 0937D8B91h,083939589h,07272787Eh,090625D7Dh,096B68C8Ah,0586B887Bh,06E817460h,06A232046h + dd 07D8C90AFh,0828F886Fh,0A7887672h,0A3A6AAA5h,0ACB3A5A3h,0BDA8A8BFh,0B4BAD0C9h,0AEC3BBBDh + dd 0ADC0BEACh,0C8AE9AA1h,0AD8F99BAh,0BE9895C1h,04C573EA0h,068344150h,094B0B0B6h,0B79EA9AFh + dd 0BABEB6BCh,0A1933F53h,0634B517Eh,04349526Bh,0A85A4946h,04A4B4666h,0B091634Ch,08BB6628Fh + dd 06B644F44h,058527986h,05946565Fh,05A585B51h,08E745245h,0B8536454h,0ACD2CFB4h,06F56393Eh + dd 07491CDABh,0C085453Ah,09F839BB9h,0356190C8h,05864524Ch,05A58564Fh,0B9724755h,0E9F0E5D8h + dd 0DFD8E8E6h,0AFD2EDF5h,0B7A99AB3h,09D5298D0h,093A9ECD3h,034DEADEAh,08379B0E4h,0CED0BFA3h + dd 0D0CAD2DEh,0DBDFE1D8h,0D2EBF0DFh,04A71CFE6h,0AEB09032h,0ABA89B9Ch,0C0C7BFB4h,05D9BCABBh + dd 0A17D6B37h,0A99DC5AFh,03F545DA4h,0283F756Eh,0879F7C59h,07D563E44h,02F2D7B9Eh,019203237h + dd 087693F1Ch,08F7C9597h,02C387194h,036393A32h,07F5D231Ah,09E9E9582h,08E87899Ah,046334075h + dd 0857B985Dh,0848EAC96h,07E73A39Ch,0626F7C95h,09E9F8875h,076767D8Fh,04F8F885Ah,0814A2525h + dd 07E9296A0h,08E7C6767h,08D78698Fh,0ABA2A197h,0AEB6A4AAh,0B7AAA3B9h,0CBCFBCC1h,0AEA8B6CAh + dd 0848CA5ACh,0C2CEAF93h,09FB0B9D9h,0A5A4A9ABh,04A5B4752h,0823D3D4Eh,0AC9A84A6h,0A2ACB5A7h + dd 0B4B3B9AEh,0AF893568h,04C466B9Dh,04A484C56h,072404C53h,05851547Ah,08AA89A6Dh,06975A76Dh + dd 072745D59h,0554F4252h,0444B4345h,02D2A3944h,086735C35h,0CB52375Bh,0C3D1CDD0h,0393C3564h + dd 0DBC8DF6Eh,0811A349Fh,04F5B5892h,0482E3437h,051395830h,05D5A8D8Eh,0CC988B79h,0F3F9F9EBh + dd 0ECF4E8ECh,0C6E6EEE9h,0D2C8C2C4h,0429EC2CCh,093AAC9C4h,0215AC09Ch,0CEBE678Ch,0C0B7BBD0h + dd 0E6E7D9C7h,0F7FAF5E5h,0ECCFD5ECh,03F28449Ah,0B09BAAA1h,08BA1B2B1h,0514D4B69h,0A4BBDD89h + dd 0937B6B66h,0D68FA994h,05B5259AFh,049416071h,076B59C5Fh,08E5E404Dh,02C4BB3ACh,0643B2F33h + dd 081788794h,09A7D8A8Ah,0447896A9h,0634F4449h,01A40586Fh,0A7754F24h,09B919BB3h,041397296h + dd 09B8D7336h,09D98AEA1h,0646796A3h,0727A7058h,08580857Eh,0606A7C94h,02C769672h,068823829h + dd 092AFC4AFh,0B8846B82h,08D9C9FCFh,0BAA8A499h,0B7C3ABB7h,0AFA0A1BBh,0DAE0C8C4h,0C6C5B5D6h + dd 08CA6B0ADh,0C8C39D85h,0A5A2A3D5h,05F8B9FB4h,04B3F5B2Ah,09F593A3Eh,0B2A59FACh,0B3B9AFB8h + dd 099CEE2ACh,0CF4E1B9Ah,03E4F75BFh,039414944h,07B4B4C3Dh,03F3D589Ch,0605D8F67h,05E556081h + dd 02D4F575Ah,06762643Fh,0313C5366h,0AE3B2335h,0423C2F4Dh,0C27F274Ch,0C6CCB9B6h,045493873h + dd 0BAAAB631h,0543990DAh,02D3A487Dh,037452028h,0976E474Ah,0D3C5CAB4h,0F1E3D1DFh,0FAFAF8F6h + dd 0FAF7EBF7h,0E0D9D7E6h,0E0D3E5C3h,08F9CC0B9h,0DABCCFD2h,03C273073h,0D8B9D6BAh,0C1C0CAE6h + dd 0EFEBE2D4h,0E2E6EEEDh,06ACEDFE9h,0C26C3042h,045386488h,02E3E3D34h,03E413D30h,0949E8153h + dd 09A724D6Bh,0D4C3CFA8h,0605076C0h,0595D6575h,04DABA953h,0A77A4C48h,04556A5A5h,0793F3749h + dd 08E93918Bh,084707A80h,0768F8C85h,0724B434Eh,07C90A49Eh,03A304C67h,09A947C63h,0266E9793h + dd 085682C2Bh,095979284h,0898D8990h,07C897581h,0656B7B7Eh,0626C6A7Fh,021255461h,0725D643Ch + dd 095B8B9ADh,0BF7B6A6Ch,08AAA9BD0h,0B79C8F84h,0CCB3C6B9h,0A99EAEB9h,0DDD4C9CAh,0B0B8B4AFh + dd 0C3B6ADB4h,0C1BCA2B1h,0B394B3D6h,0383D3C82h,047454540h,0A6883B3Dh,0B2A6A79Fh,0ACABC0B4h + dd 0ABB2B6A4h,0A14646C0h,0446D98D2h,039343C4Eh,07E345B45h,0343C5A9Bh,0595D6047h,07569524Bh + dd 06B4A6354h,04960675Dh,011344B5Ch,0D9C29C50h,029445149h,0BD9C3D44h,0C1B1ADA7h,04F36325Dh + dd 0CBAD8C4Eh,03E8EC1C5h,05D71391Dh,026322517h,09F865747h,0DCCBCAADh,0E2E2E2E3h,0F9FAFAF0h + dd 0FAF8ECF2h,0CDDEF5FAh,0D4ECD8C7h,0A899BBBBh,0B69CBBCEh,0E3593732h,0D2DDC1D3h,0CBF5EED5h + dd 0EFEBD6C8h,0E1E6E9E8h,04665C8DAh,03C4B4E5Fh,0282D3026h,03A352D2Ah,04F4A393Ah,09F465054h + dd 0ACA0AAB4h,0F1D9BCB4h,04F4D5BD2h,04B426970h,045AF8651h,0926A404Ch,02F6CAE8Fh,07A4F4C3Fh + dd 072839D80h,06A74636Ah,069AC8D76h,063322F3Dh,094948FA4h,06D90A398h,06D4D3E53h,05E9BB48Eh + dd 0662F363Fh,0A8ABB0A8h,07C988689h,0665A616Fh,0706A5D61h,05860637Eh,00904143Ch,04A455C37h + dd 0AFC1AE96h,0C27F7586h,093C2B8D8h,0A1885D77h,0CAC8D5B6h,09A9EADBEh,0BAC4C1AAh,0AFBDC4B5h + dd 0B1B3A8AFh,0CDBC8289h,0BBA9CEF0h,06377576Ch,052506B7Dh,097996150h,0BC9C9AA5h,0ADA3C5BBh + dd 0BAC1B89Dh,0940F9ACAh,0498ADFD4h,03F483440h,064454342h,024324499h,039433D2Bh,06952544Ch + dd 048587457h,0464D6854h,085453346h,0B6BEC8B1h,033464379h,0979F3448h,0B8AEA8A3h,042485A89h + dd 0C9AD816Dh,074CBAAD6h,083351F20h,03C1A207Bh,05B4B353Ah,0CBC0C18Fh,0E6D9D5D4h,0F5F8EBEAh + dd 0FAF7EAF1h,0DFF7FAFAh,0DEC2CCD3h,062AEEFF1h,09AB8B7D3h,0633D2EA1h,0D5EFD4A4h,0FAD9CCE6h + dd 0D8CCD6F2h,0ECE9E8DEh,0443E8EE9h,022242F40h,03433332Dh,03D3C3C38h,044423A3Dh,04F2B4444h + dd 0ABB2B6C7h,0D6E8E9C9h,0624D61D1h,05A547E8Ch,048966D41h,09B734655h,02A90BB94h,0834C5537h + dd 07D6B828Bh,06C746D9Ah,07AA89173h,048253746h,0938F8B91h,0A79FA59Ah,05388A8B0h,099835149h + dd 0252B4581h,0A0A29055h,08D928485h,06774808Ch,07A665A5Ch,02D4B5770h,036160515h,03E454F55h + dd 0D3C89366h,0B7889AB6h,096C8C5CEh,093876A7Bh,0DEE2D39Dh,0908497CAh,0BDB1D6B4h,0B1C0D1CAh + dd 0AAC4B4B2h,0D5C6B19Eh,0C5B4D8F7h,0A5BDAEA4h,0B4A8A1ACh,0B5968EBBh,0C1B0ACA5h,0BCC2B3BEh + dd 0BCC1C7BFh,08511A9BCh,091E4DCC2h,057464B31h,0513F3A4Ch,022435687h,038393622h,06B4C574Eh + dd 044536457h,0545E5753h,0A86A4C4Eh,0ABBFB6ADh,044573499h,0A8B95E38h,0C5BBB7B1h,03B4D7F92h + dd 0C2CE857Eh,0DBC1CBCCh,0582D31A6h,01C3D7E85h,057584A2Eh,07C727365h,0A9979B8Eh,0F6F7CFB4h + dd 0FAF9F5F8h,0F6FAFAFAh,0C9CBD4E6h,07BC1DBD8h,07F5FBCC7h,07978C0BFh,06F604758h,0D9BDA07Eh + dd 0B0D1F3E9h,0E1DED9C0h,05CA0CFDDh,055504843h,0524C4A50h,0474C5352h,03B3F4243h,0373C3A3Ah + dd 0A5A3B057h,0ECCADFD1h,0574350C2h,05F559990h,040865F47h,09679454Ch,03985AAA9h,086464537h + dd 0D776A397h,0827A5D8Eh,06A9A8E80h,04E263D51h,086878CA5h,0A3A29787h,0AAA8A8ACh,04C38769Dh + dd 04A6E7B5Fh,058422620h,092978A70h,0666F6E7Bh,078727E6Ah,019192C57h,04B401706h,03E484351h + dd 0DBC58858h,0AF8BA4C3h,097C2C5C5h,09780788Eh,0C7E0D097h,0958097C6h,0B7B2BEC4h,093A0B0A9h + dd 0ACB2A99Eh,0DEDCB3A1h,0EBBCD8F6h,092B8C7DBh,0878D8584h,094907F88h,095848994h,07F8E9589h + dd 0BA988A7Fh,06033B3E3h,0BDBEB3A8h,0565E566Fh,0956A6757h,05A566288h,07A64685Eh,0766F7374h + dd 082728159h,0738C5272h,07E755F57h,0BFB1B195h,06F501CE1h,0A8A38027h,0C1BAB4ADh,054398CACh + dd 0B9D7869Ah,0AAD4BFCDh,04C4F78C7h,095C5B888h,0545E5544h,04E545853h,08B62544Fh,0F2EED6A5h + dd 0F7EDF2F3h,0FAFAFAFAh,0E8EAE1EAh,0BFCCBAC5h,06D3943B6h,0AFD2EFC9h,06984DFF5h,05D384A63h + dd 0C3B48B7Ch,0D4D3D3C6h,04278A9D0h,0483C2D43h,04D494549h,03F4A4646h,02F363E3Bh,0444D282Ch + dd 0A7974C1Fh,0CBCDD4C7h,056552C82h,04E5F9D71h,0456D5353h,07A725058h,051779FA1h,069534230h + dd 0BD8FA38Fh,08B7270A9h,06AAF849Bh,04320364Dh,07F7B7E8Eh,097888F86h,0B6B1A6A8h,07F9D9CA2h + dd 055595C76h,01835646Ch,0613B2513h,0575D5D5Fh,02A2C4444h,02D091922h,04A573C34h,036444B43h + dd 09E8E676Eh,097959CA5h,0B2C1C7AFh,08A7F7C94h,0D3CFC89Ah,0BBC5C5D5h,0A9B6E4BAh,096909392h + dd 09E98A697h,0F3F4DFBAh,0F7F7FAFAh,0DFDBECF2h,086A8A7B6h,0C9CDC0AAh,0C4C8CBD9h,0A5AAAFB5h + dd 0BFB7B4ACh,06253DACFh,098ADB9BFh,043351D91h,0B5852944h,04945394Fh,0485F4257h,04C735B4Ch + dd 0669BA372h,0BC85317Ah,06E504341h,0C0B6AC8Dh,0473F45D6h,0BCC5B53Bh,0B1B5C1C9h,02B2E82A7h + dd 0C7E579A2h,0D2CECEDCh,02643B9C8h,0D8E08226h,0583C4B9Dh,04A3F533Ah,0CE8C4A42h,0FAFAF5E7h + dd 0FAFAF9FAh,0E5EFF8FAh,0E3E2D9EAh,095ACC4E5h,04A7C512Fh,0C0C6B882h,0C0ACD6CDh,0BEC6DAD8h + dd 0757E7B92h,077725D5Ah,085A08E86h,045446B7Eh,031465658h,03B261A21h,04D434847h,03B3B3D3Fh + dd 07E71313Ch,0A59C9893h,061554984h,058848C5Dh,0586B725Ah,09F925854h,068A4A3B1h,0724A4741h + dd 09B8B9082h,097818DA1h,074B9898Bh,046465558h,081918C85h,09C9F8F8Ch,0A193ADA6h,0808F9FAAh + dd 04B77848Eh,053656936h,02B333852h,01923282Ch,019141A12h,04D442D25h,056504E4Ah,0564E505Ah + dd 0A499787Fh,0AFC4BDB2h,0B9C8D7A5h,09B93919Fh,0E1CFC5A6h,0A9C8E5F1h,0CDD0E2BCh,0B7ACAEBBh + dd 09B9AA299h,0F4E6CCADh,0FAFAFAFAh,0CCE9F6FAh,09AB7D0CDh,0F8F2B794h,0CFEAD8E3h,0A2A2BDB3h + dd 0A8AAB7B7h,06274CDC1h,09198C283h,039236B96h,077A82E2Dh,050433C33h,09481765Eh,074C8C7AFh + dd 07E85A590h,075227D62h,038284096h,0C9A59C6Dh,02C207FCAh,0C8AEE240h,0ACB0BDC1h,02D9C88ACh + dd 0CBEB9791h,0D6C3BBCAh,02194D9E9h,0C89E342Bh,09BAEC4B4h,04E453D4Bh,0C9B6854Ch,0FAF9F3D4h + dd 0F9F8F3F8h,0E8EDF3F9h,0DED0EDE2h,06C628AC8h,06DB0C6B5h,0C0C9BD35h,0AFC8C0C9h,0EBD1DED2h + dd 0CEFAEDF9h,096C8E0E5h,07A657D8Ah,0B7B5B3A5h,0A7BFD2CDh,06E7A909Dh,02F46555Fh,03D3A192Fh + dd 076163B3Fh,0AF9EB0DDh,04B495399h,0486E5E47h,054635440h,0B9A15347h,074A3A5B5h,0734D403Ah + dd 08D8EA3A0h,093969084h,04A717090h,045303B2Dh,0A2A09687h,0A28190ABh,0ADA5A5C1h,06B7592ABh + dd 0929F9B89h,0454F7D85h,064697363h,03A304C5Dh,04837323Bh,0575D5C51h,092926A4Fh,051475C89h + dd 0B3B09496h,0C2B8AFB7h,0B5BECDC3h,08D8785A0h,0CFBBB095h,09DA9CDE3h,0A7BFC8B2h,0C7BBACA2h + dd 0AEA9AEA5h,0FAECD5BEh,0FAFAFAFAh,0D9F4FAFAh,0ADC4D2D0h,0E1D0C8B0h,0F2F2FAF5h,0D4DCC7D6h + dd 0B8AFAEA8h,03276C7CCh,09AAFC382h,02B3AB090h,065B16B28h,04D30262Eh,0CAAC6650h,058A8CBCCh + dd 0476B707Ch,02B5D694Ah,047476D5Bh,094897456h,03626C1ADh,0B9BFBDA5h,0ACB0B9BFh,04090A5B6h + dd 0D3DB8068h,0D4C5BDBAh,06FB5CEF0h,0B23E1724h,091E4BA9Eh,08C545538h,0C3C7DABAh,0FAFAD274h + dd 0F9F9F7FAh,0F7F4F8F9h,0929AB0F2h,0CBC9B27Eh,0A3C1BEB0h,0D2BC9A33h,0BABFC6CFh,0D7C3CCC8h + dd 0C7DEC1D4h,0D2F7F6F2h,0B6DAF0CCh,09A9A8C86h,0D6CBC2ABh,0D0D3D3D8h,07E9996B5h,0362A0A36h + dd 016353937h,0BEC0B994h,03D3F5CB1h,054554840h,0534A2F2Fh,09AB0815Ch,0629FB6B5h,05D3B2428h + dd 077696555h,0627A7669h,0457D5D5Fh,04A2B3238h,0AAA67C89h,07D5E6F93h,0A4A3AAB3h,0616D7496h + dd 0A8A28C70h,05B8DB0AAh,05839323Ch,0585D6C69h,06A645861h,060564E59h,089855B58h,04C5C6E8Ah + dd 0A8B6A8B1h,0AEA7A2ACh,0B0BCD2A8h,09A8A839Eh,0D1B5AEA9h,09BB7D3E8h,08CA3A288h,0B8BF9A94h + dd 0D5CDB7ABh,0FAEFE0D9h,0FAFAFAFAh,0F6FAFAFAh,0C4D6DBE0h,0DFD6CCA5h,0FAFAFAFAh,0BBC6BFCFh + dd 0AAA1A4A3h,0449CBDC2h,091BFBB79h,01E6599A4h,07A9F7B52h,066313D28h,0BF7B4964h,05E7CD6CFh + dd 0465C648Ch,05E4A7465h,033584329h,0986A553Dh,07237BBA0h,0B9AFB9DEh,0ACAFB4B8h,08A6CBEB8h + dd 0CAC19E46h,09CAFB8B9h,0DCB9A0A6h,0A8314E58h,0265CB3C2h,0D4825749h,08CCAD9DEh,0FAFAE48Bh + dd 0F3F6F1F7h,0E6F3F5F1h,0CE9475BFh,0A1BCE9EDh,0C3B3BEF9h,0F8C07968h,0C9CCCEDEh,0B9C6C6D8h + dd 0C8BEBABDh,07DB7D0CFh,0BFB6C086h,0B4C0D8D5h,0AB9FA2B3h,0C7C3D3C8h,0A9ABD3CEh,03E310E67h + dd 04C364242h,0C9B59C1Bh,0354565BDh,07F6F7952h,04544283Eh,099C89456h,06D8C9BA2h,03C2D2335h + dd 0726D6F5Eh,070777C74h,05A8E8672h,044273535h,0769A6379h,082746658h,0A5B4A29Eh,052427F95h + dd 0A9A29A72h,08198B0AAh,0383D3F76h,04E4A2620h,05567604Eh,0635B524Dh,08A817562h,04E687185h + dd 0B5B1B2B6h,0D0AFB6B8h,0BABCD0B1h,09B928FAEh,0D0C0ABA0h,0A7C9DBDCh,0A6AFAE96h,0D0D4C9B2h + dd 0E8DAC5C9h,0FAFAF5EDh,0FAFAFAFAh,0F4FAFAFAh,0C4E5F4F6h,0D9D2C2B1h,0FAF9F8F4h,0D2CFD9DBh + dd 0A5B3C1CCh,03196B2A1h,088B3AC7Dh,06F8BA38Bh,07184A4AFh,05B2D3345h,04F476993h,0654EAB8Ah + dd 064627794h,04F556F76h,06C3C4854h,07E6D3642h,06D99AB9Bh,0A0A6A881h,09C9EA5ADh,08494B8A3h + dd 085A08B3Bh,08A9EB5ABh,0D3A177A1h,05C402CC6h,0522F53ACh,0DFC89B47h,06AAFD8E8h,0FAFAECBAh + dd 0ECEEF3FAh,0DAE3E9ECh,0F2DAAB9Ch,08AE1E9EEh,0C1B7DAEAh,0F1E226DFh,0D2CED2E6h,0CBD4DCD0h + dd 0CBD3CACEh,0A3ABC2E1h,0B2C1B27Ch,0BBBAA0B6h,0CAE2E6DCh,0BAB6ACB6h,0ADB1BDBAh,0433D3B9Eh + dd 0404C3C48h,0D5B3433Fh,02E4670A2h,0A89BB071h,04A4B2665h,0B9EDB76Ah,05B757A86h,04134263Ch + dd 09A876B3Eh,0808D826Dh,0506E666Dh,04B32403Dh,07B8A6B7Ah,080665956h,0AB9DADB3h,0757B8AB1h + dd 07C6F7478h,05D7F9191h,05E96534Ah,01A082643h,064566936h,08C896353h,09C808F9Fh,061595E78h + dd 0AEA2919Ch,0A3A1AFB2h,092979F7Eh,08A8A9786h,0CFBCA083h,090A9CFD8h,0AEAE8388h,0D4CCC1B4h + dd 0FAF5E4DAh,0F7F8F9FAh,0FAFAFAFAh,0FAFAFAFAh,0D6F5FAFAh,0D7B7C5D2h,0F7EDE0D6h,0C7DEF7F7h + dd 0A8B1ACBDh,050A5A89Bh,0A3A4A15Fh,0A5B3AF9Ch,07F86A1A1h,063587476h,054678B85h,07A686061h + dd 046505475h,042454E4Bh,06865473Ch,04D5C5763h,0979D956Ch,0B8B0ADA2h,0A4A6ADB6h,07FCECAAFh + dd 0BED0B837h,0B4B3A9A8h,0A4A7958Ah,02F31B1CBh,03C3B41D9h,0E3CB9258h,06B78CCE6h,0F8FAF1CAh + dd 0F9F8F7F9h,0F6EDF5F9h,0F6E5D782h,09AEFF4F5h,0B3BCEACBh,0E9815ABFh,0C2D9E9FAh,0D7E8E5C7h + dd 0BDE3DAD0h,0789DB0ADh,0D5DEB67Dh,0C1D2CCC0h,0E4D7CCCDh,0CBD8D2E1h,0A5B3B2BDh,03D4992AEh + dd 0464E4444h,0D364364Fh,0524B68A6h,0BDAE9F6Ch,0533F3D97h,0BAF0CC76h,09F998B98h,044342F58h + dd 098737662h,0595E6F87h,05E728060h,02C353330h,0AC947069h,07A7B8297h,0B28E8A92h,091A3BECCh + dd 052587080h,05E5E635Dh,0AD8A554Bh,05E585C76h,047231233h,083757460h,08384887Dh,04D585D62h + dd 0A09EAB97h,0908496B5h,07888989Ah,0898C9669h,0D3CFB184h,0A8ABC2CBh,0ACBFAEB6h,0E4DACFB1h + dd 0FAFAEEEAh,0EAEFF9FAh,0FAFAFAF9h,0FAFAFAFAh,0E6F6FAFAh,0CFCAC5D0h,0FAF8EBE2h,0C2E5FAFAh + dd 09BBCCCAEh,080B7B3A5h,0A8858A5Ah,08099B6C6h,06258667Fh,0575B5152h,04A504C47h,0AA6C5D56h + dd 05D586A8Fh,030344A5Fh,057585249h,05D645F5Eh,097946D5Bh,0BEBCB5A1h,0A1A1ABB1h,040C0C0ABh + dd 0ADAAD379h,0C19D8F9Dh,0A39387A1h,03240C1B4h,0344346B7h,0E1CB9362h,050529AD5h,0F7FAE9B4h + dd 0F8F7F9FAh,0E8EBF4F8h,0F2DEEF7Ch,0C4F0F2F4h,0AAC8E699h,0DC1A8079h,0CECFE1FAh,0E9DDCFBCh + dd 0B7C3CFEEh,08CB6BDC4h,0D3BB7A60h,0CCCDC7CBh,0B3B4CFD6h,0CDE1CBCBh,0AEB9BCCAh,09DABCAB8h + dd 039476C95h,086394346h,058684EA6h,09091947Ah,0734B569Eh,0C0CCB375h,095A096A6h,04E434388h + dd 0A68C846Bh,08D8B92A6h,098BB8790h,04A385559h,08F859288h,093969C9Bh,08B999B98h,08593807Dh + dd 06F717C85h,08E85988Dh,0818D8991h,0727C7E77h,02C4B6680h,0575F4120h,065888263h,0484A4958h + dd 0A49FA1A3h,09D9B97AFh,09499ABBDh,0778798A0h,0BABE9965h,0947F90A8h,0CBD4EABEh,0F9F3E5D2h + dd 0FAFAFAFAh,0ECECF7FAh,0FAFAFAFAh,0FAFAFAF9h,0FAFAFAFAh,0F3F4F6F7h,0FAFAF5F4h,0D9EEFAFAh + dd 0A49BA4B9h,0CBC1BAB0h,0667394C6h,05A82A5ABh,06660757Eh,053504D54h,044454646h,0A37A4542h + dd 061475478h,05362696Eh,05A422E39h,06F3D4155h,0857B6C69h,0C2B5A695h,09CA0A5AFh,0237EB4A4h + dd 08DA5D494h,0AFA5ABAFh,0837A84BBh,0409A9774h,04842665Eh,0D1C39B54h,058535CB2h,0F9EFF4B6h + dd 0F6F5F8FAh,0AAF0F1F6h,0F6E1E9BFh,0E2EBF1F6h,0ADE0F98Bh,0444F737Bh,0CED2FAF3h,0C5C7D9DEh + dd 0C2C2BFCFh,0C2B5ABCCh,0AE96819Dh,0BFB7B7C3h,08B94C4C3h,0AFB29AA9h,0B996C1CBh,08F9DB6B8h + dd 03E4A759Bh,048293936h,05D3E3674h,0C1B39371h,0311C67BFh,0C3D0C155h,0B2A79DBCh,03F41418Ah + dd 035413734h,031303230h,0404B1B31h,02411302Eh,09A988F74h,091818A8Fh,090978C8Dh,089929186h + dd 06E828C8Dh,080859880h,09691988Eh,070859696h,075755F66h,029292551h,0466F5541h,0635B4C49h + dd 0A691858Ah,0B5B3C2C0h,097B8D1D0h,09497A89Fh,0C9C4B492h,0C1B7B7C6h,0EEEEE8D3h,0FAFAF8F1h + dd 0FAFAFAFAh,0F9F7FAFAh,0F6FAFAFAh,0F6F8F9F6h,0EBF7F9F9h,0F8DAF8EAh,0FAFAF9F9h,0EEF3FAFAh + dd 0A29EADF8h,0BBB9A1B0h,06ACDCBCDh,076A36946h,05C736E53h,0364C3D42h,045383B3Fh,07B654747h + dd 058525164h,055585C5Fh,030414859h,041464839h,0A8A57648h,0A897919Ch,0B0B9A9A6h,06E38B7C4h + dd 089B89E8Ch,0AAA1A8BAh,082838E9Ah,03B938E8Eh,059415F1Eh,0BEC9B062h,051454773h,0FAF2EBC0h + dd 0F5F9FAFAh,08AE8EBEDh,0FAF0EBE1h,0D7F2F9FAh,084C9E5BAh,05EA95E7Ch,0B0E5DDC9h,0DAD9D7D3h + dd 0C0C6C9D4h,0D6C9CFCEh,0799395E2h,0C1B1B8A3h,0B7A7B7BBh,0B5B0B1C7h,0C671B6C1h,0BDB7B8CBh + dd 037317EB8h,036364338h,0583E4444h,0BFB9BE7Fh,065537EB0h,0E9BDE370h,0A5CBD0CEh,02A30397Ah + dd 032432626h,02526282Ah,01D241E23h,0150B1B27h,07681897Bh,08D848077h,0807A8287h,09A958F8Ch + dd 08A8E9291h,084899494h,09F908F87h,06A7B8794h,0757D6763h,04554636Eh,049301124h,06971745Fh + dd 0B399847Bh,0CED0E1D3h,0ACC6D0DEh,0ABA9B4BAh,0D7D5D1B0h,0DECBCCD7h,0FAFAFAF0h,0FAFAFAFAh + dd 0FAFAFAFAh,0FAFAFAFAh,0F5FAFAFAh,0FAF8F2EFh,0F2F9FAFAh,0F8D8F9E8h,0FAFAFAFAh,0F4F8FAFAh + dd 0B3BACBEEh,0C2C2ADC6h,0BDCCD4D8h,07B3A3F83h,05D6E5D70h,0464B5750h,04A414A41h,06061534Fh + dd 05454564Ch,04D515357h,05B7C835Ah,04D36353Eh,09E58304Ah,0989FB5B7h,0DDBAB79Ah,0B93D28BFh + dd 0A3918598h,09A95A4B7h,08F7D8A9Ah,086AEA499h,053396038h,0ADC4A465h,050484957h,0FAF8DEBDh + dd 0FAFAFAFAh,08CD8E1EBh,0FAF7F3E4h,0E4EDFAFAh,052A6D9C3h,09390778Eh,0C7B2DF4Bh,0E5E1E6D2h + dd 0C4C9D6E3h,0BED5CAC0h,066759DA1h,095B4AF8Ch,0B3BA919Eh,0A6ADC3ABh,0C97DB6C0h,0DAD3BFCCh + dd 03161D1CDh,0213A343Ah,0776E502Dh,0BD9CA678h,0C8BAD6E2h,0EBECFACBh,0B1CEC2D7h,0344F3669h + dd 03A40272Bh,04F565144h,03D342E45h,0291E253Ch,072707A77h,0827D7C77h,07783797Fh,096978982h + dd 08E999B9Ah,064729296h,08C887867h,06E8D8D8Ch,06D605D64h,06C595D6Eh,01B55787Fh,097796044h + dd 0CDCBCFD2h,0E8E2D7CCh,0BBCEDBF1h,0CEC4CEBAh,0E1E3E3D2h,0ECE0DAE1h,0FAFAFAF8h,0FAFAFAFAh + dd 0FAFAFAFAh,0FAF9FAFAh,0F1F7FAFAh,0FAFAEBE6h,0FAFAFAFAh,0FAF5FAF8h,0FAFAFAFAh,0F9FAFAFAh + dd 0A7C8E8EFh,0A4B19EAFh,096BAABA6h,05B98A3A1h,0A3AA9B68h,057558088h,03D405044h,0614C4B41h + dd 04242495Fh,04A444344h,0AC83644Bh,041336D93h,04A46494Dh,0A4B2A36Dh,079BCB9BCh,0DA863521h + dd 0CFC4D0CFh,0B3ADB4A5h,0A99590D5h,0566E879Dh,0412F761Dh,07EBD8B55h,0615A5541h,0FAF7E6C9h + dd 0F8FAFAFAh,097D3E5EEh,0FAF9F8ECh,0FAF9FAFAh,090AFEDD9h,0D7978EB3h,0B7FA8192h,0E4DDE4CAh + dd 0DFE7ECEEh,0D1BBCADAh,0B7B3ACE1h,08A897679h,0A9B08B96h,09AA9B79Dh,0D06EC0BEh,0CCC7BBDBh + dd 04DD4D8BCh,02C3E3B3Bh,066683C1Bh,09C7C9A7Dh,0C3C7CFCBh,0C9EDBCBFh,0ADCEB6C1h,06C946F8Ch + dd 076866661h,0A59D8876h,07D706EA7h,0625C566Ah,07E80867Ch,08B8C847Eh,0768A8B8Ch,0828E8F82h + dd 0749D8F90h,08B999E75h,077727075h,0748C857Dh,06A65686Fh,07D6A7B81h,0907D6E7Dh,051293254h + dd 0D3D6D1CFh,0E2E7E5D8h,0EBE5E4EAh,0EEE5EEEFh,0EDE7EDEDh,0F9F3ECF0h,0FAFAFAFAh,0FAFAFAFAh + dd 0FAFAFAFAh,0FAFAFAFAh,0F4F1F4F9h,0FAFAF7F4h,0FAFAFAFAh,0FAFAFAFAh,0FAFAFAFAh,0FAFAFAFAh + dd 0A3C5E1F3h,08E9DADAEh,0CCA6AC92h,0B4B2B2AAh,09A54377Dh,0714D5390h,04F4F4881h,068525150h + dd 05151506Fh,03F4E514Eh,0AA98624Eh,07099ACADh,0554A3C4Fh,0B6823D39h,01758CEBCh,0D4E3653Dh + dd 08B81AADAh,0395D7A79h,0293C3938h,0694B461Dh,02E30B676h,04E8C6944h,0594D4641h,0F4EED8C3h + dd 0F6F7F5F5h,0A2CEE6F2h,0FAF9F8F1h,0E9F3FAFAh,0AA97CDD8h,0A1ABCFB6h,0EB8C45D9h,0E6DCD2D8h + dd 0F1F4F1E7h,0D6E0DCE3h,0FAF2D5C7h,0BA8172ABh,0AB9287C2h,0C3DDDBC4h,0C762ADB5h,0D4D1C1D9h + dd 099F1C5CCh,03648513Fh,0575C3A23h,0A882A686h,0B3A6ADAEh,0C4DCACB8h,0879C999Fh,08295989Eh + dd 08C9D8489h,08B898989h,087918E8Fh,0867A6F73h,090959885h,08B8F9290h,07E8F918Dh,091968683h + dd 08E8C868Ah,09485A1A3h,076878B90h,091837E7Ah,0676F7C89h,0736B6F6Ch,087898078h,03A61797Ah + dd 0F1F7F1EEh,0F6F0EEEAh,0EFEEEFFAh,0F7F6F9EBh,0F4EFF4F7h,0F9EFF2F7h,0FAFAFAFAh,0FAFAFAFAh + dd 0FAFAFAFAh,0F5F6F7FAh,0FAF7FAF7h,0FAFAFAFAh,0FAFAFAFAh,0FAFAFAFAh,0F9F3F9F9h,0FAFAFAFAh + dd 0BBCACCE5h,07A84A7BCh,0C4BCA395h,0B1B3A8C4h,04860AABBh,0C682423Bh,04E4936B0h,044494D51h + dd 04E555243h,0464A4846h,083816F4Eh,0B6A48C78h,04E46749Fh,03A46443Eh,0392A3454h,05A8D7C3Ah + dd 020373A49h,03740342Ah,0605D492Fh,0ADB2AF7Fh,02A4FCC90h,03D4C443Fh,0604F3044h,0EEECE1C7h + dd 0F5F9F1EEh,0A7B8E5EDh,0FAF5F7EAh,0E9FAFAFAh,0B588B5E0h,07C90B0A5h,0B545B197h,0DACFCEEBh + dd 0FAF9F5E8h,0E4E8ECF5h,0D5C8DEDDh,0AC8C87CAh,0A4ADA6C3h,0B8C3B3AAh,0BE6EA8AAh,0C6D0C6CDh + dd 0D6C6C6CFh,04D4A5560h,0644B3C36h,09F879987h,0B0BBB79Bh,0DECBB7A6h,09E8F9DB4h,0A1979D8Ah + dd 082797393h,077717885h,072877984h,0877F6664h,084828786h,0979C9791h,085989D99h,0988C6F84h + dd 07581787Ah,07A908D77h,07B79808Ch,06C7D807Bh,085878176h,08B816E74h,080938D86h,06B6A6D7Dh + dd 0FAFAFAF7h,0FAF8F9F8h,0F1F3F4FAh,0FAFAFAF3h,0F1F6FAFAh,0FAF5EEEEh,0FAFAFAFAh,0F9FAF8F9h + dd 0F8F3F8F8h,0ECF3F1F9h,0CBC6E0F5h,0FAFAFAF3h,0FAFAFAFAh,0F4FAFAFAh,0E1E7FAF6h,0E7F7F8F9h + dd 0B7CAC6D6h,0839BA2B3h,0B6B4AC9Ch,0AE9F9DBCh,0ADC6CBC9h,0856A7985h,04F4E3250h,061415452h + dd 05E6C776Dh,059525053h,0948B726Ch,0BA8F7884h,09C9CB7A0h,050504854h,03F3A2B36h,0403C576Bh + dd 0666E5C3Fh,090917F68h,0AAA79D93h,0ACB5C5B9h,032649D9Ch,04341333Ah,05837483Fh,0F5F2E2B6h + dd 0EBF9F8F4h,0B9A5EDE8h,0FAF7F6E8h,0E5F7FAFAh,0A79698D7h,078A29A97h,05D808584h,0AEBBD9AFh + dd 0EDECE2D1h,0ECEFF3F0h,0E9EFF0E8h,0B5A6ADDDh,0AEC4C6D3h,0B1BFADBBh,0B87998B7h,0D0CFCBBEh + dd 0C5D7C1C4h,0484C4BB4h,05B4A3F38h,09A9EA27Fh,0ABA29D93h,0D1A0B2A6h,0B59588A9h,0969F8BA2h + dd 06C7D8979h,06E76887Ah,069788387h,087929362h,0877F6F8Dh,095959388h,082A29A97h,09A9C7A8Bh + dd 0858F8F6Bh,075808B89h,0787E7586h,06C777D77h,080877E73h,0616D7276h,06A82827Dh,063625F6Ch + dd 0FAFAFAF9h,0FAF8F6F8h,0FAFAFAF9h,0F3F7FAFAh,0F0F7F9F0h,0FAEFE6E8h,0EAEEFAFAh,0E9EADFE5h + dd 0EEEBE8EAh,0BFD3DFEBh,0B6948A98h,0FAFAFAF2h,0FAFAFAFAh,0EDF9FAFAh,0E9F1FAE9h,0E2EBE9F9h + dd 0BED7C7C6h,092AAB4BDh,0BFC7C9A8h,09EA3BCB8h,0C5CBC0C5h,06F7EA0D6h,04A48454Fh,07A4F5C52h + dd 05D64637Ah,0635A5857h,09B897470h,0B0806B8Dh,0BBA0ACABh,048808D96h,05C422830h,06B5B586Dh + dd 0E7C8B099h,0A8B7B9BFh,0A59FAB9Dh,0A7A2A4BFh,0357EC0A2h,0324F3F36h,05E3A2F28h,0EFE8D4A4h + dd 0E0EAF2F1h,0B491DDE5h,0EEEFEEE4h,0CBE5E9ECh,0A1AF99CBh,08AA09199h,093C58E86h,0D0D2E387h + dd 0DDCABDB3h,0DEE1E4E6h,0DAD8D8D9h,0B1B8D3D6h,0B0C2C4CAh,0ABA8A8B9h,0BD85A5BBh,0BFC3D7BDh + dd 0CBD3CCD5h,0434867D1h,04A55423Dh,091A7B596h,0A6A5A69Ch,0B8B4BDA4h,0E0BE96ABh,0B0A6ABC9h + dd 0896F88ABh,06D7B9396h,0766F7893h,087818C75h,08974688Ch,0857E818Bh,06B978788h,09B89857Fh + dd 07E738980h,07F7B8188h,0777E7A87h,081858074h,08D8E8680h,05360737Dh,0757B7568h,067666372h + dd 0EDF5F4EEh,0F6F3F2EBh,0F1F8FAFAh,0E2E9F1EBh,0E3E8E8DEh,0F6E8DEDEh,0D5D7FAFAh,0DEE2CED1h + dd 0ABC1D3D9h,0717A909Ch,0AD77797Ah,0F9FAFAF0h,0FAFAFAFAh,0EDECFAF9h,0C6DCEAF7h,0CFCBD3C9h + dd 0C1DBCAC5h,096BBBBBDh,0E3CCC1A3h,0C3C2C1C4h,08C9AB3C4h,0927D7891h,04B4E6385h,06F555F50h + dd 05F6B7270h,05C5D5556h,091767B63h,0AC917883h,09DA4B2AFh,0ABBC9896h,0A3A1ADB2h,08B9DADAFh + dd 0A2978EA4h,0A4A6AAB6h,08D8A9F96h,0928C9B99h,0B6B3A49Ch,08CB9A5B5h,0A8A29B89h,0F5E8ECD6h + dd 0ECF7F4F9h,0B79AE7F2h,0DEE9EAE1h,0C1DFE2E0h,09DABB4CFh,0CECEABA2h,0E8CCCFB1h,0CDF19AA4h + dd 0CAC0D3E3h,0EBEFF2E5h,0E2E1E3E7h,0D7E6EFEBh,0BFCAC6D2h,0ABA9A4BDh,0CD8AB5A9h,0ABA2C9BDh + dd 0ECC4ECE6h,03C38B7B2h,03C5D443Fh,09198AA91h,09C939498h,078A2B5A3h,0CBB7A699h,0A2A5DAE5h + dd 0A7927A9Dh,0727B8A95h,0827D837Fh,0938E7B5Dh,0816C6588h,0958E858Ah,0718D9395h,0909D8D8Ch + dd 06779916Fh,0697C8875h,08767737Bh,079797A78h,08D8D7F79h,06F6F6B74h,073737F7Ch,05C595865h + dd 0DEE5E6DFh,0EFECE6DFh,0E9EFF4F1h,0C7CDD3E4h,0C7C8C3C1h,0E7DECCC6h,0CAC9EBEFh,0ABB8CBCBh + dd 070827F93h,07B76776Ah,0D0978376h,0F9F2F6FAh,0FAFAFAF9h,0E3D9EDEBh,0AEBDBFDCh,0AFB2D8BBh + dd 0B4C9BBB9h,095C3BAB1h,0AEAEA58Fh,0B4B6AEBCh,04C395AA5h,03F454938h,05F716D5Dh,05B5A5554h + dd 06C7A7B58h,0715D575Dh,0AD92797Eh,098928A91h,07B97AA99h,0A0A69396h,0948698A8h,09A929F91h + dd 089BF8D91h,07F7498BDh,09B8A928Dh,0AEABABA9h,09FB5B7ACh,043948798h,045263629h,0F0E3DAB0h + dd 0ECF8ECF3h,0C99EE2E6h,0FAF3F6F0h,0E5EEF8FAh,08F8AB1D2h,0B6B3968Fh,0CAE49E9Ah,0F1A8A0EDh + dd 0DBE2E2DCh,0DBDBE2DDh,0D3D3D8D9h,0EFF6E8DEh,0ACB9C0D4h,0BEA0A8C3h,0BB90C0A4h,0A57EA196h + dd 0CFD3ECB7h,0456EE1BFh,03A4A3845h,0989DA44Dh,08E9B959Fh,0B9A2AFB0h,0CBA4AEA7h,09EB3CACDh + dd 077797E85h,0706F737Ch,08E707457h,076744F7Eh,0908B407Eh,0A59E9379h,0849498A0h,09F9B7C92h + dd 06D9D968Fh,06E869872h,07E7D7972h,07A726F6Fh,086938078h,068767973h,07A71817Dh,064666370h + dd 0D4D8D6D2h,0D7D4CFCFh,0BAC7CDD6h,0CFD0D1C5h,0BCBFC0CFh,09C9BA9B3h,06172899Fh,050555B61h + dd 05F635050h,05550565Dh,0C4776767h,0FAF8EFF6h,0FAFAFAFAh,0C6CBDEF9h,0A1B4B0C0h,0889EAE97h + dd 0B2CBDDACh,0AAB89893h,0CEC9AE93h,0B6ACB2C7h,0594B6F9Eh,03F3D5260h,04D344139h,051546750h + dd 068835C45h,04D3D3C4Ch,07D866857h,064828D8Fh,097A38778h,09B8E87A6h,08DC76780h,09B91999Eh + dd 0B5A5A9BDh,0AFB1AFD3h,0829EBC9Ch,04F9CCA98h,08B88AEA7h,0799172B6h,047402D27h,0F2ECECAEh + dd 0FAF7E5EEh,0C2B5F4F7h,0F1F8FAFAh,0D3E3F6F8h,09692B9D9h,0BBC3AAABh,0CED2AEB5h,0AE9FECE7h + dd 0BEC5D9DBh,0C5BEE4DFh,0DCDED5BAh,0D8D6D2D3h,0C8D3D9ECh,0D7D4D5CDh,0898FB2ABh,0B4A1937Bh + dd 0C4D0B7BAh,055B3E3C1h,03A4A4D57h,0CEBAAD4Ah,0B5C0A4AAh,0B6AEB4BFh,0AAB5C7B9h,0A7ABAFA5h + dd 0A5A1A5BCh,09A92A1A8h,096969AB1h,09F8FA09Eh,0A4A4A4A8h,09CAD9EA3h,094868F9Fh,097A1A29Eh + dd 09F9B9993h,09BA3AE99h,09787959Ah,08D87888Ch,0B29F8E7Eh,067687D8Ch,06D71726Eh,0818D6E73h + dd 0AEB3B7B8h,096A6B4B3h,08A7E718Bh,07B7E7F96h,055575D77h,0524F5051h,03D535154h,05E5A5643h + dd 04D564F55h,05C45484Bh,0C7846A6Fh,0FAFAEBE9h,0FAFAFAFAh,0C3C7D7F7h,08A989EB3h,093859F8Bh + dd 0BFBCC4B3h,0BBB1A8AFh,0C4DBB39Bh,0CAD6B3CCh,08B8388ACh,058747989h,05C4A6251h,05F524B65h + dd 0888C6561h,042454D6Dh,060695C49h,0A3908B6Eh,0ADBA9F97h,0B8B0ACB4h,0B296CFCDh,0B19F858Fh + dd 0A0A5B1B3h,09EB5B0C1h,08FA7A6A4h,019A4D8B1h,04F1F2523h,081935677h,0443D2A22h,0F6F0E4AAh + dd 0F7F1EDF4h,0AFB7E8EBh,0F1ECE4DDh,0C3E6F6F8h,09A92B5BEh,0D4C9B0AAh,0DCC5C4D6h,09EE6E0CDh + dd 0D6D5C8D3h,0DBE3F8DAh,0D0CFCBD6h,0D1CAC7CEh,0CADEDFE1h,0CCBDBCBEh,092929FA8h,08C718483h + dd 0CBDBADA8h,03CA5C7ACh,0312D2929h,09FB97F22h,0B9993F1Ah,0B8969BBAh,0B2CFC3B1h,0B1A59889h + dd 09C9D9FAEh,0888C9793h,08EA5A6A5h,0A794829Ah,0A6A2BFBBh,0ABABA1AFh,087718CA1h,0A2A3AD9Fh + dd 08F87A1A1h,09499AE98h,097846E86h,083858488h,0A39B8978h,061748381h,071586B69h,0656A5B6Ch + dd 064646A6Fh,0545A6063h,051504A4Dh,0494C4F43h,044454746h,04A494848h,048445349h,05E554743h + dd 04A4E3948h,045434C49h,0E08B6563h,0FAFAF2F0h,0F3FAFAFAh,0C7D2E7EFh,09F9A9BABh,0A47892ABh + dd 0B7ABA6C2h,0A18BAFA6h,0C1B19B8Ah,09AC1D6C3h,0889DAC9Dh,08A809FAEh,04195C4A3h,05A585538h + dd 0916F3853h,03F334985h,0594A4F41h,0A2758675h,0ADBBA3A6h,0AE9A9896h,09BB59A9Ch,0B49C8B99h + dd 0B0A3A1B6h,09FE5B7BAh,07B8EA1BAh,058BDD48Bh,033413F30h,01F393A1Fh,0403A3B24h,0EFE7DDA2h + dd 0F1E9EAF0h,090B7DEE1h,0EBE5E9D7h,0D5E3F2F3h,09E9BA69Dh,0C9BAB6A7h,0D4B8AFB5h,0CEC7BBD4h + dd 0D7E4C29Ch,0D4CDD2C3h,0BAB2BCC6h,0DACFC1CAh,0C0D7E0D3h,0CDBEC5BBh,083ABA7B6h,092A19078h + dd 0D1D2AD9Ch,0469AC0BAh,03C373C35h,0ABAF5722h,0913A1859h,0C88A90B2h,0D0DCBFB7h,0C0B893A8h + dd 0B2AE9F9Dh,0848B94A1h,09FA09787h,09C96B1A3h,0A7898B93h,0ACA2ACBCh,08B8E8595h,09EA19094h + dd 09E989B99h,08F95A59Ah,0858D9183h,07F817776h,07F7F9684h,08071877Fh,08F7C8076h,05F83A195h + dd 0453F4248h,046444246h,051463A45h,03E3D3E38h,039373B40h,0474D4843h,0494F5241h,067514237h + dd 0424D4E58h,056464A46h,0F3976F79h,0FAF8EFF3h,0E3FAFAFAh,098B3DBDCh,08296A597h,0AB8D8BA5h + dd 0ACA1B7A2h,0AA8CBFB4h,0D1C395B1h,0738B93D1h,04362605Dh,08D737B7Dh,0A6BAA598h,054545176h + dd 088454057h,03D4D72A7h,0483D483Ch,09A6D6D7Eh,0B0B3A7BDh,0C5A39586h,0B7929989h,0AC91A1A9h + dd 0C8CCA3B4h,09FCDA5C8h,09377909Eh,074B1B2ADh,041252E1Eh,02C313B2Eh,04A453F39h,0F1E8E7ACh + dd 0F1E9F0F3h,0ACCCDFDEh,0F4F0BB9Eh,0E4ECF9FAh,0AEB1CDE3h,0A99FB49Eh,0B6B6B0BAh,0B7B3B0A3h + dd 0C1D8B1C9h,0E0AE9988h,0C9CDBFCEh,0ECD9C1B8h,0DEE3D2C9h,0D8CDD7D3h,09F9DBFC7h,07D8C8599h + dd 0C0C1A692h,05FA8B6A6h,0303B302Dh,0AE882C24h,02B303FB8h,0AFA2C498h,0F9FAE6BEh,0CECD82B8h + dd 0A1B4B0B3h,09F938F97h,0B3A5A887h,0819DA496h,075717789h,0A89DA690h,07C848E91h,09BAC808Ah + dd 0999F9E95h,091949D8Ch,07D7A8085h,07C8F7671h,086717D75h,0616B716Ah,0878C7863h,073A0839Dh + dd 04E493D46h,040464945h,040434244h,03F40393Fh,03C3C3C33h,04041413Eh,052494E47h,059434755h + dd 04C575C50h,06C565149h,0F8C56D6Fh,0FAFAFAFAh,0DAF9FAFAh,096B6CAD9h,095A9959Fh,09B9085A0h + dd 0C2B9989Eh,0A8AAC0AFh,0D6AE87B9h,0A6828CCFh,08985799Ch,044484B67h,07D5B484Ah,0635A648Fh + dd 062535F63h,05274AAB5h,079716760h,08C8B887Ah,0B7A7A2A6h,0CDC4A7A5h,0B3AAA1A8h,0B7A7ABA7h + dd 092A5A1A4h,0A0ACAFA0h,0A9A8A4A3h,0C5C9B9B8h,05D75A665h,05446534Dh,05E5D7D60h,0F2E7EAB9h + dd 0F2EAF2F3h,0EDD5D1E5h,0F9F4F8D1h,0DEEFFAF7h,0C2DEEAD6h,0ABA8A9B5h,0A4A0A7BFh,0AC9EA2ABh + dd 0B3BBCED8h,0D0C2A2D5h,0A7BEDDDCh,0BFBAB7B4h,0C5DAD9CFh,0CCDFCCDBh,09EADB6DAh,092878E93h + dd 0B4A4948Dh,080A1B0A6h,03941503Eh,0A77E2932h,0362572B5h,0A6C28634h,0DBD2BEC5h,0D6CA9C98h + dd 0A2A0AEBBh,0AB9699ABh,09596AEA9h,0A6A4ACA9h,08897AAA1h,0A4878C74h,08D805D80h,0A09F9FA2h + dd 0989DAB9Ch,08F8999A0h,08484898Bh,05B797578h,07E787B77h,06C678491h,08D726B6Bh,0798C9295h + dd 04D4E4C51h,04B52534Bh,04242474Fh,04D4D4F46h,0514D484Fh,04E4F4749h,057565853h,053545C56h + dd 055515540h,0695E6563h,0FADA8672h,0FAFAFAFAh,0DCF5F7F9h,0A2BCCCD9h,0B4C4A7A1h,08E92807Bh + dd 08F8EA192h,099A2B5A4h,0AE9E8B96h,066788898h,0A58A725Ch,08994A5AFh,03E606C70h,04D454D44h + dd 0354F5352h,04B8E976Ch,057494D39h,07C68413Dh,0B7AFA58Ah,0AFB79092h,0B0A7B38Bh,0BAACA4A8h + dd 0A6B6ABB6h,092868FA6h,0A79AAC94h,05684A7A0h,08D747440h,046639088h,0615A4842h,0F9F6DB89h + dd 0F2F6F9FAh,0C6C5E4F6h,0FADCDEABh,0E2F1FAFAh,0BECAE0D5h,0BB9EADCAh,0B1738EBAh,0C3A8A7A4h + dd 093C9C4CDh,0C4B279DCh,0BAC8DBCDh,0ADA9B5B5h,0C6DCDFD8h,0CEECE3E1h,0998ED0D5h,0ACA29A92h + dd 0CABC9DA2h,09FB4B8AEh,0404F5652h,0996D2E39h,04044919Dh,0C0883D65h,0B2CED894h,0CCD4C1BEh + dd 0C0CCCFCDh,0848FA7BDh,0B381877Bh,0B49C89AAh,09893A3B4h,08A86A190h,09E8E7D77h,0A2A39B98h + dd 0969AA893h,088858F95h,08D979288h,07E8D9382h,08E8D8279h,08C8C9C9Eh,0816E6F7Dh,091918D90h + dd 04E4B4C46h,04B515351h,05F50444Fh,0736B676Bh,07B80887Ch,0948A8581h,09A986E84h,099949890h + dd 06D586074h,054483654h,0FAE09567h,0FAFAFAFAh,0D5F7F6F8h,0AEBDC3D0h,0A3C3B8B0h,08B897474h + dd 09C8E9B8Ah,0857E99ABh,08D8C8E8Fh,079816679h,03F535C5Bh,093836948h,06A819B9Bh,051535268h + dd 03D424247h,07DC36E3Eh,0554A534Dh,0625C4B52h,0AAB29A6Ah,0B9B09EA2h,0C5B2B3A8h,0BFA69ABEh + dd 0B9C7B5C9h,0B3B2B5BDh,0BAB0AAA8h,0413B649Ah,0624A4D4Fh,04A394C53h,05D514B4Ah,0F8EBF8ADh + dd 0EDF9F7F8h,0D1EFF3EAh,0F8EEF796h,0DEF7FAFAh,0CAC6D2CAh,0918C7FA5h,09F725D99h,0DDDFB7A7h + dd 071D6DDDCh,0CEB96497h,0B9BCC8CDh,0BAB4B6A9h,0C3D8D9D0h,0D8EAE7E1h,0B0AFEAD8h,0A7A4909Ah + dd 0F0BFA49Ch,0B4BA9FBAh,0445A4546h,0885C3340h,02369A085h,061234F7Ah,0FAE4ED75h,0B0D7DCF1h + dd 0AAAFAF79h,08293AFC1h,090887A80h,0A1909296h,0A098A6AFh,054616F72h,08A6D674Bh,0ACA2A192h + dd 09296A698h,09086808Ah,0748D8985h,07B888D7Eh,094867C8Ch,092969B94h,0706F7487h,09A9D99A1h + dd 05C504935h,07F736462h,0B9A78C8Dh,0C7CAC5B7h,0B1A8ABBBh,0BEBDB8B5h,0E6D9C0BEh,0E6DACACDh + dd 08BB4BBCBh,04A444D5Dh,0FAE7A462h,0FAFAFAFAh,0C9F8FAFAh,0AAB3B1B9h,085B7B2AFh,0C0C8A283h + dd 0C2BBB2CAh,0A6A3BDB7h,07971879Ah,04D56727Bh,061685750h,0656B7C67h,09E78466Dh,04D526EA4h + dd 045393E44h,0A57D4047h,0464E4E69h,05C3C354Ch,093906F5Ch,0ACBEA388h,0B0AEA9A5h,0B4AA8494h + dd 0B4C0AAC4h,094A9C4BBh,0629EB5A9h,0B77B3E2Fh,04577D7EAh,0494F5A46h,0AEEA8845h,0F7EDEAB1h + dd 0FAF7F9FAh,0DDE0E3F1h,0FAF1F0AAh,0EBFAFAFAh,0D0EDDCCCh,0A7B5B2B3h,0B9926997h,0CCC8DFBBh + dd 065D1EBCEh,0DBC36328h,0C0B9D2CCh,0CDC5C6B6h,0D0DAD3E9h,0E6F5E9E8h,0ACB9E1C9h,09FA891B3h + dd 0C6D0BC9Bh,0B5AA9B90h,03B4E4550h,085513940h,0337C9674h,025319054h,0C5ECC540h,0D1FAD9CAh + dd 0BEC2B1AAh,07C8FA7B2h,083878581h,0A8999389h,09D8CA1A9h,05F688587h,071656352h,0AD927B82h + dd 0908E9896h,088827481h,08C86807Ch,0867E8AA3h,0958E898Ah,098A0A198h,082919297h,0949E958Fh + dd 0B4AFADB0h,0CBC2BDB8h,0E4D8D7D2h,0EAEBF7E4h,0EDE5D5C7h,0E2E0D4DDh,0E0E3ECE6h,0FAECF2E9h + dd 066E1E7ECh,055586C68h,0F4EFA85Dh,0FAFAFAFAh,09FE0D7EBh,0ABC4B198h,08DBEB3A0h,0A8C1ADA1h + dd 0B8AB918Fh,09A9B9AA8h,059608A9Bh,04D475465h,06F635450h,0886C8079h,0495563ABh,0839C7D56h + dd 04A3F4440h,07F434E52h,058959CAFh,04639433Bh,0928A7358h,0B5ADA49Bh,0AD8C6C84h,0BEAF919Dh + dd 0A6CFA7C9h,0B69AA5A4h,03C5797A1h,0FAFAEC5Bh,0DCFAFAFAh,0833D4A73h,07BF9FAFAh,0ECF4E7A4h + dd 0E6EAF4EBh,0BCEBF0ECh,0E0CEB9C3h,0D4EED1D7h,0C9DFDDCCh,0A6A6A5AAh,099659B9Eh,066ACAEBCh + dd 076BBCCB8h,0958D6A3Fh,09AAB8091h,0B6999996h,0D3C7BDC1h,0C9E6EBDDh,0A5A1D0C3h,0A69F8799h + dd 0B3B1BE8Dh,0AEB0979Bh,04C504175h,082402B3Eh,04580919Bh,0088A8F29h,0B1B55820h,0ADBFC4AFh + dd 0C1DFC1C7h,07F83A0BEh,0A5918A8Bh,0A29CA89Eh,095969992h,0686B728Ch,07E80625Fh,09D999490h + dd 0969A9994h,08C88818Ch,074877471h,0987B6D89h,09A86938Dh,0939C9290h,0999CA0A2h,08C999A91h + dd 0DEE6E5E0h,0F6ECECE5h,0FAFAFAFAh,0E1F7FAFAh,0E8F9FAEDh,0DBD5D3D9h,0EAF6E4E2h,0FAFAFAEEh + dd 052DFE7EAh,0615D866Bh,0FAF5C27Ah,0FAFAFAFAh,097D0E0EFh,0C4BCABA3h,08FABB1BCh,09EB6BC9Bh + dd 0B6ADA3A6h,0BDAEA2B7h,05B556397h,04D444B5Eh,073735C56h,08E7B9480h,090B9A1ADh,09B5E3B5Bh + dd 057533587h,043455258h,087CBDC78h,05850545Dh,0948F7C67h,0A9A4958Eh,0A99797A3h,0AE9E8C9Bh + dd 0A6BB96A8h,08FA1A2A1h,07D4F5D57h,0FAFAF6E6h,0F9F6FAFAh,0FACBAFEFh,09FF3E0F7h,0C7BCBA90h + dd 0E5E4D7D3h,0CFE4E5E6h,0B685B8C9h,0D0D6CDD1h,0A8A8AFB5h,08C928588h,0A6798571h,083A6649Ah + dd 08489896Ah,095857F79h,06F7B739Fh,072866D7Eh,0B8ADBD90h,0DDEBE4D5h,0A9AAC0CAh,0ACB1A09Fh + dd 0A9BFC799h,0A09A8A8Ah,0424C4463h,070352F3Eh,03F7698A7h,079995238h,0BF520A57h,0CAC1ABD5h + dd 0A5D1AEABh,08F9AA3A6h,09C95978Bh,09E92A897h,0978E90A5h,081718192h,0827B5F88h,0A88F838Ah + dd 0879E9AA0h,07B7F8B82h,089907578h,08F988885h,092918E7Ch,09C989D99h,08A92999Ah,08093978Ah + dd 0F1F9FAF7h,0F9F9F8ECh,0F8F9F8F9h,0CCF4F9F8h,0D7DBE1E6h,0DED4CBCEh,0E5E6DFE0h,0F9F9FAF5h + dd 065D9E6E8h,07167766Ah,0FAFADB92h,0F3FAFAFAh,0A4C0C7DDh,0A49DA3BAh,09DA6B0A3h,08FB29DA6h + dd 09CA39680h,070828089h,06B686662h,06C74725Eh,079847665h,09790947Fh,09AA2CCADh,07764677Eh + dd 069646858h,06A6A6E6Ch,0B5DB8051h,0695E7293h,087817C71h,0B18D90A0h,090859592h,0B0B7AA9Eh + dd 0AAA4A7C7h,04087B6BAh,0FAB35F51h,0FAFAFAFAh,0FAFAFAFAh,0FAFAFAF8h,0B3FAFAFAh,0F9EAD68Bh + dd 0E7E7F2F9h,0DBDCDCE3h,0A382CBD4h,0E4E4CEC0h,0DDDBD8D6h,0AF9FBDDCh,0848195A1h,0AD8F81A8h + dd 09AB5D8C1h,06C709099h,073735369h,077737671h,0AAB6CCB1h,0E9E0C3B3h,0C8B0C7E4h,0ACBCA6B8h + dd 094BBC09Eh,093948F7Fh,0444F4766h,075323A42h,05784A7AFh,06A84323Ah,0851C3F73h,0B2CBD1F5h + dd 093B38E8Bh,0898FA29Fh,0878A9091h,09B8A8B8Ch,08C92A593h,087939396h,07F7D807Bh,07B989687h + dd 0949C8B85h,07C82A1A0h,0828A6A6Ah,0798A9689h,087787C85h,0948E978Fh,08C939899h,08C989384h + dd 0D5D7DCDDh,0D7D2D3D4h,0D5E1D7DDh,0E4EAE3E7h,0C2CFDEF0h,0CFC8C6C2h,0D5D7C3CCh,0EEE9D5D8h + dd 064D8E7E9h,08192A484h,0FAFAE499h,0E1F9FAFAh,08BB0C4D2h,0B4B9A49Ch,0A49AB4B5h,0A6AD8D9Ah + dd 0969DA8A0h,073808D9Bh,0625C535Fh,0BBA37054h,0818B9BBAh,071776C78h,06D687070h,0496C5F68h + dd 03B3C4448h,05A383536h,0AD533D4Ch,05A769DB5h,064565A5Bh,064676B6Eh,07F7A6765h,0A29C938Dh + dd 0A1A3AEA8h,043476F9Fh,0FAFAE582h,0FAFAFAF5h,0FAFAFAFAh,0FAFAF3FAh,0A0F5FAFAh,0FAF1D677h + dd 0F7F6F9FAh,0F1F2F4F8h,0A2C0E2E3h,0E5DBC6C1h,0E2E3F2E5h,0ACD1E6DFh,0898F8CA9h,0B3C38CA7h + dd 0A39B9285h,07B696C87h,0796F7F71h,057A890A7h,0BCBFA5A7h,0EAD4CCB8h,0DCCBD7F2h,0A1ACABC0h + dd 080ACABA0h,0B6AAA87Dh,04038388Dh,0732B3032h,0657A8687h,099672C30h,02E357EB1h,0A6BBD5A6h + dd 07E92839Bh,0908C8B8Ch,091949397h,0A399A6A7h,08F8C9498h,066738994h,0A191786Ch,09392989Ah + dd 0979F9689h,07C868D8Eh,0806D8D88h,0656E7B88h,0827A816Ah,0918F8781h,08D92928Eh,07E828585h + dd 0DEDFE7CCh,0EAE9E7E6h,0ECD7F9FAh,0FAF9FAFAh,0D5F0F6FAh,0CDCCDED0h,0DDDCBAD6h,0F4D0DFE2h + dd 032CDF0FAh,05B49996Bh,0FAF9E7A4h,0CCE9F9FAh,092B5B8DDh,09195A09Dh,0A78EB3A0h,08E99ACA9h + dd 08E9EA6A6h,081668A92h,0636B6563h,0818F906Ch,03E2F474Dh,06A4C3747h,04C697D7Dh,066685E4Ch + dd 0382F432Dh,0473B3F41h,0524B4C4Ch,09CCA926Ah,0534F5D7Fh,05F69464Ah,082686052h,09889A19Ch + dd 0ABAED4A9h,079454E76h,0FAFAFAF8h,0FAFAFAFAh,0FAFAFAFAh,0EDECD5E4h,070C8E1E8h,0F9E0BE7Bh + dd 0FAFAFAF8h,0F1FAFAFAh,0C0D8F5EFh,0CFE8F2DFh,0F4FAFADAh,0D6CDD9EDh,089948EAAh,0D5C08A9Ah + dd 079727E7Ch,07C6B6B6Eh,0BDB6988Dh,08C87A987h,0A2928080h,0DBCBAEA2h,0C3DDEEE8h,09BB4B5B9h + dd 079AE9A98h,090AC9997h,047374498h,072243834h,06284775Bh,0AF3F2F37h,0377E999Eh,080A1632Ch + dd 0758B827Fh,09D946A7Eh,0877B8585h,092A19CA8h,0A87B91A4h,072747D82h,07877677Bh,0B2BB887Dh + dd 0BE946E8Bh,079A5A893h,08A9D8B78h,06B7A8687h,06F8E9875h,09D9C877Fh,07C94879Dh,088807E7Ch + dd 0F8E8ECF9h,0F6EEF2F5h,0DDE7FAFAh,0FAFAFAFAh,0DCEDF9FAh,0DEDAE6E2h,0E9D6B9DBh,0E5DBCFDAh + dd 034BDF0EEh,067557440h,0FAF9EBB1h,0DDE1F6FAh,092B2ACBCh,0A395A5ABh,09EA6AFA7h,09AB2ADA4h + dd 08DB5D3C3h,0806B8593h,0575E6666h,08B7C5F4Eh,0F4EBD2BDh,0F6F5F5F6h,0E5DDF4F6h,06C7B9CBBh + dd 0333B393Fh,046423930h,057414748h,09057595Fh,0404877A7h,04E616962h,07C625241h,0A099888Dh + dd 059AC9DB1h,0F5AB4448h,0FAFAFAFAh,0BCD1F2F5h,099A7B8AFh,04956849Bh,04E3E3F42h,0F0E9AF5Eh + dd 0FAFAFAF9h,0FAFAFAFAh,0DBF4EAFAh,0D1C9CCD5h,0F8F4F4D8h,0BBD1E0EBh,0CDA6AFC2h,0C1BD84B6h + dd 07E738C70h,0A491868Fh,0B09F927Bh,06A999F9Fh,0A4A1A07Bh,0D1C5BBADh,0BFDCE5DEh,0B796B1B9h + dd 072A8D1B3h,094A0918Dh,0402F3790h,073273631h,077666F83h,0801F272Dh,07799928Fh,08D96293Bh + dd 089999A9Eh,0A4B79B95h,0907A9394h,08CACAEACh,086899881h,08B9FA378h,0678C917Bh,0949895ABh + dd 0A07C7FA3h,0889FA38Dh,0919C8D82h,0757A7387h,065827565h,07CA49979h,082878B96h,057584865h + dd 0FAFAFAFAh,0FAF6FAF4h,0E7D1FAFAh,0FAFAF9FAh,0DFE8FAFAh,0E7E9EDEEh,0CBC1BED9h,0F6DACAC2h + dd 02862B2F5h,065545428h,0FAF3F5CAh,0BFD9EBF6h,09C9FAEC5h,0A7919FAEh,0BE9DA7ACh,0A79DA1C9h + dd 074A1C2A2h,07F72727Dh,055525E78h,0F3ED494Ch,0FAF9F8FAh,0FAFAF9FAh,0FAFAFAFAh,0D8FAFAF9h + dd 03C4D7CD6h,0484D3E34h,04245484Ah,03A415159h,0637D835Bh,044595664h,07B69534Ah,08D808674h + dd 04067A18Ah,0878B5E4Ah,055484861h,07D6C5856h,0BDAAA485h,0E6E9DED5h,098D9E9E8h,0D2C8C479h + dd 0F0F4FAF1h,0E5EAEDEDh,0F6E2E2DDh,0ADB1CDE8h,0F8F9F6D1h,0C1D6D3E3h,0C9D7D4B6h,07F828EB2h + dd 0947B6E6Ah,0A98A798Fh,0A093827Ch,08B968E99h,09A928E96h,0C6BAAE9Ch,0B5D1EAE3h,09C92AAAFh + dd 0888BBFABh,08B7E99AEh,03C403E8Fh,06332362Fh,0A1768095h,04C142947h,099A78D8Ch,0874C1C6Ch + dd 09294989Eh,0A2B1918Ch,08D849FA9h,096A09996h,0AE96918Ah,07B587F95h,0A08968B1h,09995877Bh + dd 094918893h,0959A9F8Eh,0956B7181h,08B767F9Eh,07075797Bh,0859B8275h,092849591h,0547F937Bh + dd 0FAFAFAFAh,0FAFAFAFAh,0E6BEF6FAh,0FAFAF9F6h,0F9FAFAF9h,0DFFAFAFAh,0D7D3AABEh,090B9CADFh + dd 04C58697Ch,0865A573Ah,0FAF5EED7h,0B9C7D6EAh,0C9A7BAC9h,0BBB9B6C6h,0B1A3B0A9h,09AA7BBB5h + dd 0829DB1A5h,06A746A7Bh,045525673h,0EDBA4B50h,0FAF9FAFAh,0FAFAF5FAh,0FAF7FAFAh,0F7FAFAFAh + dd 0A5C0F8FAh,06A415080h,085727470h,05A757D8Bh,09D744A5Dh,0738E8E9Eh,0706F6577h,07B7E9188h + dd 0908E8B9Dh,056364D6Fh,0DFB49088h,0FAFAEFF0h,0FAF9F9FAh,0FAFAF6F8h,0D3E7F5F9h,0E1CDA792h + dd 0F6F8FAF1h,0EFF1F2F6h,0EDE4EDE9h,0C7D6DDE8h,0D0C6A4B9h,0E7EDEADEh,0D4CCCACEh,0CDC8D1CBh + dd 0B0A8A8BCh,0A3B2AC9Bh,08C8B8891h,08B808290h,0A49EA391h,0C5D0D3B8h,0B3CECCD5h,08994A8ACh + dd 092B1C9AFh,09AA2A38Fh,03F3347A2h,08D413F32h,08E7E9298h,0272C297Ah,0A3A57663h,054215DA3h + dd 0958D9CAAh,07078788Ah,09881536Fh,0B2B7B8ADh,096A9C2A8h,094A19999h,0677D958Ch,0929EA092h + dd 07A998482h,08A92967Eh,091A09890h,0737C8F9Eh,05F6C7075h,084909082h,09392958Ah,05358818Fh + dd 0F8F0FAE8h,0FAF2F7F7h,0D9D7EAF9h,0FAFAEFDFh,0EEECEDFAh,0CBD9EDEAh,0D8CDC1CCh,0514B85B4h + dd 0815B806Fh,0A7875664h,0FAFAE7C8h,0B6B7CBEEh,0B7A9AA99h,0A88CA8ABh,08893A295h,09C92A1A5h + dd 08290A392h,0687A8882h,0465F5371h,0F49D7D61h,0F7FAF6FAh,0F9F8F8E8h,0F0F7E4F5h,0FAFAF3EFh + dd 0FAFAFAFAh,05A67CDF0h,05F5B5745h,04A4F5A5Bh,062445150h,089BBC196h,04142596Dh,07E755F53h + dd 082B1A274h,0415592A7h,0F89B4A32h,0FAFAF1F5h,0FAFAFAFAh,0FAFAFAFAh,0F9FAFAFAh,0F4E3ADA1h + dd 0F9F7FAFAh,0FAF9F5F5h,0FAF4F0FAh,0EEF4ECF6h,096BECDEDh,0E8F2E1B3h,0E0E7FAECh,0C9DFC9C8h + dd 0B3A6C4C1h,091A19584h,0A7AFBE8Ch,0908598ABh,0979DB0A3h,0C7C5D7B8h,0BDD4DEDFh,08FA4C8B7h + dd 0989AA8A2h,07D8398A0h,04D5C56A5h,082493D3Eh,0767A9A80h,02F4B297Eh,08A949886h,034407CA4h + dd 0A99DAF7Bh,0ABA4A19Dh,08D9F5684h,09197968Fh,07CA38F97h,0908D9690h,09B898B98h,0819D93A1h + dd 0859C8D8Ch,0A2A09C7Dh,08F878C8Eh,075838787h,07D757672h,092868085h,089847E7Ah,09393848Ah + dd 0F0F0F8F5h,0F1DCE5DEh,0DCDBEFE7h,0EFFAEAEFh,0EDE7DCE8h,0BEB3C9DEh,085A3C8CAh,0A5E0AF82h + dd 097B8BD90h,0D9BFC5A1h,0F6FAFAF0h,091B5CDE9h,09A92847Dh,06D7CA2D3h,06E6A7278h,0888F6D75h + dd 070757C7Ch,050586257h,03E564953h,0FA54766Bh,0F1F8FAFAh,0EAE8E1D7h,0E7F0F9F2h,0FAFAFAEFh + dd 0FAFAFAFAh,0D29EF4FAh,03F4F5C92h,053514855h,05C4B616Ah,0ACA3705Ah,0555D6771h,08B7D716Eh + dd 09BAE99A1h,080B3D0A9h,04825414Ah,0FAFAF7AAh,0FAFAFAFAh,0FAFAFAFAh,0FAFAFAFAh,0E1E0AED3h + dd 0FAFAFAE7h,0FAF9F1F5h,0FAF7F9FAh,0F8FAFAFAh,0D7FAF2F8h,0FAFAFADEh,0F8FAFAFAh,0D9D0CCDAh + dd 0ACAEBFADh,09FB1A880h,0B79DAC88h,0A08C91B9h,0A4A6A29Bh,0ACA6AAADh,0C5D2F6C1h,0ADAFD9B9h + dd 08F909791h,088969C9Ah,0565348B2h,0855E3639h,079838F73h,02F3E2C7Bh,0A8CDB683h,02E5C977Ah + dd 07D877A2Eh,097949B93h,0955B3768h,0B1A98590h,06FA9A5B4h,08DAAA186h,0A4A3A49Ah,0ACAAA8A6h + dd 07E7C76A6h,099919677h,0AA989689h,09792929Ch,089868D81h,09999938Ch,08E8C8A8Ah,09A958A8Ah + dd 0FAFAFAFAh,0F2DAE7DDh,0F3F1F9EDh,0F3ECFAFAh,0E3F9FAFAh,0E2D8B9D5h,0584477A8h,06B6B7370h + dd 0CBEDFAC3h,0C2B29498h,0F8F9FAE6h,07E8ABEE3h,091919392h,0D0867B9Ch,0AAB0ADAEh,0B6B8A2A4h + dd 0707B81A4h,04C443B3Bh,047555348h,0DC2F9984h,0DAE5FAFAh,0B5BEB8BBh,0F9F4ECC6h,0FAFAFAFAh + dd 0FAFAFAFAh,0FAB6F5FAh,06179D4FAh,056564555h,069686369h,04F50555Fh,06889836Fh,09A806B6Ah + dd 0B5B29A92h,0C5C5D1C4h,0365D98C4h,0FAD0543Bh,0FAFAFAFAh,0FAFAFAFAh,0FAFAFAFAh,0ECAEAAF0h + dd 0FAF6F5DDh,0F8FAF7FAh,0ECE0DEEDh,0E4EAE8F0h,0E2E9E8EEh,0ECF4F7E4h,0F1F2F2F0h,0CBC2DCEFh + dd 09B95C1E0h,0B6BA9171h,0C9A5ABABh,0999198BFh,09FA9A19Ah,0A8A8A1ADh,0C2CACBB8h,0BEB0D0B2h + dd 0967D7796h,0C3C3B8ACh,04E4342D8h,07E533437h,0828C836Bh,036304291h,088D0BD88h,03B748D76h + dd 08B80281Eh,07E8E8C99h,0631E3555h,0BEAE766Fh,09AB4A4B8h,090A2B6A2h,09499A8B4h,0B193A197h + dd 07E7178AFh,08F7E8578h,093ACA48Eh,09C8D858Dh,08A818C7Eh,07B838E91h,0868C8F89h,0908C8780h + dd 0F9FAFAFAh,0FAE5EFE1h,0FAFAFAFAh,0FAEEDDF7h,0EDFAFAFAh,06793AFE7h,06159454Eh,0544C4D54h + dd 073B8DFAAh,0E6CAB068h,0DDF9FAF8h,07E8FB8C4h,09397AEA4h,09976A091h,0ADCBCC98h,0B6ADB7C8h + dd 05B74A7BCh,055454045h,06A575C4Eh,078479497h,099A7DAFAh,0817A8180h,0F6EAE8C1h,0FAFAFAFAh + dd 0FAFAFAFAh,0FAABEEFAh,0CEFAFAFAh,0595A5681h,0856C5E64h,051575069h,086795938h,090878384h + dd 0B1A59E86h,0AEB8ABB3h,0819FA8A3h,083473F3Eh,0FAFAFAE4h,0FAFAFAFAh,0FAFAFAFAh,0CF85C8FAh + dd 0F5EEE6EFh,0E3F1EDEFh,0D4CAC9DCh,0E6E4D4D7h,0DCD8E5DAh,0E0E2F0E9h,0E4DBD8DAh,0C1D3F0F1h + dd 0A6BABDB4h,09D9B7C6Fh,0AA9E97A7h,09BA7B69Ch,0A3CAD0A0h,0B5AC9CB5h,0C8C3D7E0h,08CC1D0B0h + dd 0A68E947Ah,09CB5AAB1h,04D5136A7h,07D4B373Dh,08696866Eh,03E354F92h,096B0B76Bh,0768D7789h + dd 09F652E58h,06F8F7E92h,0362E384Dh,09E9F866Dh,0AFC0AAA1h,09DA39F8Fh,09CA0ACBBh,0959A9A9Bh + dd 0897574A2h,0896D6F6Fh,07B949687h,0898B878Fh,086829892h,08992968Dh,09491908Eh,08E8E7C97h + dd 0F7FAFAFAh,0FAE4E7DFh,0F6FAFAFAh,0F9FAFAEEh,0E1FAF0F9h,0515160ADh,069524357h,0656B5354h + dd 0AA8BAEA2h,0ECDDE3D7h,0C9F7F9F6h,07E96ABADh,08782928Ch,0739499AEh,0D5937D8Fh,0A09A89B7h + dd 04266BFB3h,04F41444Eh,08C565D4Ch,0375994A1h,0859BD6D2h,08379786Fh,0D6D6D4C6h,0F9F5F3EAh + dd 0FAF9FAF7h,0F7B2E9FAh,0F9FAFAFAh,053695ED3h,06256656Ah,03A5B5654h,06F3C2B36h,0A3ABA691h + dd 0917B8397h,0958F8D94h,087898795h,041363692h,0FAE1904Ch,0FAFAF8F8h,0F8FAF9FAh,0796CCDF2h + dd 0E8E4C9D5h,0D5D0D7E0h,0B3BBD3E2h,0B7E0DAD0h,0D3DEDBAAh,0CECDD9D9h,0DFD6CDCDh,0D7DBE5EAh + dd 0B4B9C7D2h,0AB9F9399h,0AAA4A6BBh,0B2BCBCBDh,0A1ABA1A6h,0A0AF9EBAh,0C0B6C6B5h,0A6B3D0B2h + dd 0B29E798Eh,0A3DAC3BAh,0524E308Ah,09574343Dh,08BA9846Ch,0403C4E7Dh,0A0A7D452h,09C9B9093h + dd 0722C4C74h,06F8F829Bh,02D3E3D5Fh,0909EA451h,0BBCCC2A6h,095B0BBA7h,09C9AACA2h,0848D9099h + dd 0767082A9h,0896E6962h,07C7D8B8Dh,073848596h,08C819A94h,07E899490h,08D858081h,0959781B0h + dd 0FAFAFAFAh,0FAF7E1E2h,0F4FAFAFAh,0FAFAFAF6h,0609AD8F7h,065737463h,0675E6963h,08F696C6Dh + dd 0E9E5E0AAh,0FADFDFD9h,0B7F8F7EFh,0BEA2A9ADh,09378788Fh,07A8198A1h,09E96748Ah,0A2977C83h + dd 053628C8Ch,062584F4Ah,0AA6A5563h,066898BAFh,093ABD19Eh,0A9AC997Fh,0DCE9CCC2h,0D4D4F6EEh + dd 0F2ECE3D4h,0F3D4DAF4h,0F1FAFAFAh,07881A1F9h,0726D787Bh,062655F67h,06D685D5Ah,0C4CF9D6Ah + dd 08EA39494h,0A5B0AA88h,061757974h,05A6F8161h,099435F4Fh,0FAF9F0F1h,0F5FAFAFAh,0765973DDh + dd 0EAE3CAA3h,0E1ECF9F7h,0B9D2D5DDh,0C6D8CCC7h,0D9DCDED5h,0E1DCE0DFh,0F6EFECEDh,0EDD4F8FAh + dd 0B3B1C6D1h,09CA8A7AEh,0A1A0A993h,0BAB4B2ABh,0AFA09FC0h,0899E9FAFh,0AFBC9199h,084A7C5B0h + dd 0B3B08079h,0AAB3C0B4h,04A5B3A61h,099912C52h,05381958Fh,048443C42h,09AA7C43Bh,0A7B0A3ACh + dd 0434271B0h,09D8A7E96h,02E3E4973h,094B17A2Dh,09EABA7AEh,0969C9C96h,09497A797h,0AA979A94h + dd 074849CAFh,077767D77h,0828D939Bh,08F8D949Eh,0807B928Ch,084858582h,079747474h,07C7E8378h + dd 0ECF9F9F9h,0FAFAFAE9h,0ECF2F9FAh,0F2F9F9FAh,0634E5C98h,088867A7Ah,08D8E928Ch,0D7B99690h + dd 0FAFAF6E8h,0FAF5F2F6h,0A3DFFAFAh,0F7A4A3A0h,0BCB8B6B7h,0C4CEC7C1h,09BC1BDCEh,091A2A1A4h + dd 0736472A1h,0706E7069h,097615369h,082AB959Bh,0637DB478h,0908D7670h,0E3EAD9AAh,0DEE6E4D6h + dd 0FAFAF9F5h,0FAFADCFAh,0DFFAFAFAh,04951BFF4h,055535250h,0585A4D4Dh,044474C52h,05C6A4B5Fh + dd 09EA09A62h,0B398ABB0h,08DB0BBBEh,0B6B1848Fh,02B3C2970h,0F6EFBD5Dh,0408CD2EAh,05A33403Ah + dd 0D2D0AA6Dh,0F2EDE7DCh,0D5F6EFEEh,0DCE5D6DBh,0E1DEE0E4h,0F9F0EEE9h,0FAFAFAFAh,0F9D8F4F2h + dd 0BFCBE2F0h,0AFC6BBADh,0B0B7BDAFh,0B6B5AFA3h,0ABAAAABFh,092A6959Ah,0B8AC8676h,0A0CACDAFh + dd 0BAAC9888h,0BC9BBB93h,051675155h,0B6A95251h,054485896h,04B515859h,0A2BB9E4Eh,0A5A38F8Ah + dd 05A5BA1A7h,0B1909A72h,03C424672h,0A7863241h,095979298h,096959192h,09693928Eh,0A49F918Eh + dd 0AA9E96A0h,0979093A5h,082808A95h,07E79938Ah,076748283h,08B8D8576h,08486898Ah,0817B7A68h + dd 0F0E3D6D0h,0F7F3F9F8h,0E9DEF0FAh,060B1F6FAh,0878D5946h,0705B5960h,0A88F7B7Ah,0EEECDEC5h + dd 0FAF9F6F2h,0FAF4F8F7h,0D0C8DDE8h,0CDD1BFBFh,0DEDDE2BEh,0C9C9D0DAh,0908DA2CBh,0A7B2AC99h + dd 05E517CA8h,05C575255h,06E3D565Ah,07896A2A9h,0619EC44Fh,070604B5Ah,0AFABC59Ch,0D0C1CBB5h + dd 0F9F4F7EBh,0FAFAD9F5h,0CBF6FAFAh,05438D0FAh,04445474Fh,042505447h,0625C5754h,03A3C4543h + dd 0C4B55F3Dh,0ACBAC2AAh,099ACAA8Fh,09088967Ch,0396E8F8Bh,04847472Fh,0423B3E3Eh,052424249h + dd 0DAC37A4Ch,0F5F9F2E8h,0FAFAFAFAh,0F1E9E8F7h,0E7E6E2D6h,0FAF3F8F8h,0F4FAFAFAh,0FADDF2EFh + dd 0E7EDEFF9h,0CECCC2D1h,09FA19FAFh,095AEB798h,0A4AEA5A3h,085919091h,0C5AB946Fh,07B81AEB6h + dd 0A8987E73h,0A9A1B29Ah,04347413Ah,046AB5939h,046442C26h,03834323Ch,076AC6F33h,09A92837Fh + dd 04B5C8881h,0949F7531h,0373A3C6Fh,09834323Ch,091898B88h,07E7F7E8Ch,08E828C7Fh,087BC8685h + dd 09390978Fh,08C6D798Ch,093859D9Ah,08D87877Dh,08497979Ah,0939D8D7Ch,0979EA19Ch,079776B83h + dd 0F1EFF9F9h,0F5FAF8F5h,0EBE0F7F0h,0484D9BFAh,065664757h,0645E6056h,0E4CFA083h,0FAF7EBECh + dd 0F7F8FAFAh,0EBF9FAF7h,0EFF5DBE8h,0EDEDF0F3h,0D2A5B2D6h,0E6CFD9EBh,0B1B2E6E7h,0A5B7C7BFh + dd 072757D9Bh,052545A4Fh,03E51484Bh,0A29E9F8Bh,083E79437h,0593D3938h,099D6AB9Ch,0CBA3B095h + dd 0FAECF2E2h,0FAFAD1C7h,0F4B6FAF8h,04432D4FAh,054494342h,064645852h,0515B6674h,052615757h + dd 07B474845h,0B3A2B9B1h,0AB9099C9h,077748999h,08E8C8868h,051464364h,04D4A4253h,0555B3638h + dd 0CDA25E47h,0EEE7DEDEh,0F9FAFAFAh,0E5F2F9FAh,0EDE7DFE9h,0FAF4F5F1h,0FAFAFAFAh,0FAD4E9E3h + dd 0F1F6F3FAh,0A9BDC6D5h,0989FAB96h,071848998h,0A2A89699h,06B7A9590h,0AF9E8D60h,09198D0CAh + dd 0B2D28879h,083B398A4h,03C585133h,02A3E5B45h,03D353232h,030323B40h,08F913B3Ch,09590898Ch + dd 04E7A7F89h,08B99352Fh,02B2B2B74h,03D2C2D37h,0958E90A2h,06F837D8Ch,07F8B7968h,0A0ABA275h + dd 092A58B89h,098738C90h,08195A497h,079867A7Bh,078A29292h,0959F8261h,0979B9E92h,07E82927Fh + dd 0FAFAFAFAh,0F9F7FAFAh,0D5DFFAF9h,06138539Fh,03B505068h,096806F56h,0F5F0D7C3h,0FAFAFAF9h + dd 0FAFAFAFAh,0FAFAFAFAh,0F6EDFAF8h,0FAFAF9F9h,0F7F8C9FAh,0F3F7F6F9h,0AAC5E7F6h,0A6A7AFADh + dd 087BEA894h,055585B60h,03B504D55h,08B839C85h,0A5BA3C2Dh,0705D594Dh,0A5B09B9Ah,0CC8BA08Ch + dd 0D5DAE4CEh,0FAE2E195h,0FAC0C0F4h,05C62B5F6h,069666169h,06F686263h,0434F5E6Ch,064524542h + dd 02F2E3148h,0ADAC8351h,08E91ABB6h,0776B827Eh,06C8E7880h,062576D5Fh,07B515C6Ah,05C534525h + dd 0BE614D4Ch,0F1E6CECDh,0F0E7E8EBh,0DDEBF0F2h,0EDDED5D8h,0D9D4D8EAh,0FAF9D9C9h,0E3CFD7E9h + dd 0EAEBEEEDh,0E1E1F2F2h,097ABC5D1h,08186988Dh,0A888827Ch,0918C90ABh,0BAA3A496h,080B2C6BDh + dd 0A5CCB78Fh,073A7A5ACh,03E3C4D41h,038393A3Ch,032363A3Bh,038363431h,08E8D3F4Ah,0919C929Eh + dd 0847F8983h,0B4582440h,029282C70h,0302E202Dh,095939277h,08B8C82A0h,083817E84h,0929C937Bh + dd 099A3A095h,0837F9E93h,0949E9E93h,083888284h,06F9D9A8Fh,08F9F836Ah,099939690h,08B858F93h + dd 0FAFAFAFAh,0FAF9FAFAh,084CFFAFAh,05E5C5341h,04C4A4750h,0C8A17B71h,0F4F3DCDEh,0EFF4FAF8h + dd 0EBEFF6F2h,0FAF8F2EBh,0F1E9FAFAh,0ECF4FAFAh,0FAFAEEFAh,0FAFAF7F7h,0EAE5F0F8h,0B2CDE4EAh + dd 085B0B5A7h,04F4C5878h,041545454h,082699E53h,0B779324Ah,03C3C6E6Eh,09CAF5A58h,0A287A88Dh + dd 07C8C9390h,0E5F0D79Fh,0EDFABDD0h,0694AA7F6h,06D695E65h,06C6B696Ah,09288796Dh,0887A7D8Bh + dd 0616B667Bh,09E857270h,0AEAEAB9Fh,084839D9Fh,076628888h,08D633766h,080A5A19Eh,0516E6F4Fh + dd 07D6F9772h,0E8EAEBDEh,0EAF6EFECh,0E8F8FAF8h,0E7DEE0EFh,0DFD9D9E1h,0D9D7D9E1h,0E6E6E1D9h + dd 0FAFAF9FAh,0E8EFFAFAh,0B0C6D1D3h,093A0A99Dh,09F8A8177h,0A9907A94h,0B99980AAh,093A0B5C1h + dd 08099A19Eh,04BA5A8A0h,03B463747h,03A43403Eh,03A373B3Bh,0413D3D3Dh,0AD974155h,0A2A09899h + dd 0A0939E82h,093253289h,02F2E306Fh,0362B3433h,0A29D8841h,091928D99h,08E908B90h,0ADB09294h + dd 08E9A9AA1h,07E758477h,08D829093h,0A28B8686h,060838794h,09A968474h,092909794h,084867A92h + dd 0FAFAFAFAh,0F6FAFAFAh,04C71BAE7h,0475D5B56h,0535B3C43h,0BFBD9D6Fh,0F0EDCFC0h,0E4F1ECEFh + dd 0D5D1D8DBh,0FAFAFAE8h,0FAF3FAFAh,0F9FAFAFAh,0FADBEDF3h,0FAFAFAFAh,0CFCCE3F8h,0B6B6A8A1h + dd 09FB7B8B7h,07E76809Dh,072585F75h,08D987454h,0C5776DA5h,09A8C8FA3h,0CAC3C1B4h,0D4E8C7C8h + dd 0B6BBCBC4h,0D5EFDED8h,0F0E9EFCDh,06F7283EBh,08F8D786Ch,07A81888Bh,0585F6C74h,06465615Eh + dd 057656286h,064545761h,0A8886F5Ch,07E98A9BDh,076395D6Dh,0845A659Bh,077A496ACh,059627064h + dd 04178A696h,0EFE6E095h,0F4F4F1EFh,0EDEBE9ECh,0D9E3E6DCh,0CED0D4D8h,0E1CDC6C6h,0E5DDD9DDh + dd 0F8E9E3E2h,0EFEDF2F9h,0D4D5D7DFh,0A1A6BBCAh,09C7D879Ah,0CEC8C4C2h,0BFA7B4BEh,0ACA4B2C9h + dd 08F9AA5B3h,04E8EABBEh,04641496Dh,0484A4947h,044444A4Bh,041424545h,09D8F3C4Bh,0B5A29387h + dd 09B97A39Ch,052376B96h,03E393A4Fh,041304343h,086773D3Ch,0847E816Ah,07F7D8888h,08C858F88h + dd 08A84797Ch,0846C7778h,081818F93h,086878682h,091A19D92h,0969B989Fh,07D808F92h,082866E76h + dd 0CAD5E3EAh,0A9B4C5CCh,05D5169ADh,0707A7564h,0857C7366h,0D7E2D9C0h,0E7E3E7CDh,0DCD9E3E4h + dd 0D8D0CAC2h,0FAF8F4EAh,0E9E0F6FAh,0FAF9FAFAh,0F7F2F6F7h,0FAFAFAFAh,0C7D1EFFAh,07A8694B1h + dd 07392838Dh,07669676Fh,05E67645Fh,059783A57h,08A4852CFh,05F5865B1h,0786A5B61h,07D7C8783h + dd 0AB758E8Dh,0CDD3D6C1h,0F8F8FAF1h,06D683F95h,068737065h,061686E6Ch,05D616262h,07869626Bh + dd 058626597h,064615858h,066586265h,09EACAB8Bh,04B4C7683h,092706668h,05AB9B5ABh,05C796181h + dd 0624D4D68h,0DED4974Ah,0EFECE7E4h,0DCDCECF4h,08B9DBAD9h,081858783h,075616D79h,0CCBB9E89h + dd 0EFDCD5DAh,0ECEAECF5h,0D7D8E0DAh,0ADADBCD6h,0967A899Eh,0C6BBC7BEh,0BAA7B5D6h,0B3B3BFCBh + dd 06B8692A6h,04B809094h,0504D535Ah,04D4A4B4Eh,0524A4E4Fh,051505356h,084733369h,0BBA49F99h + dd 09E9FA3BBh,0354392A9h,03D39381Eh,042426043h,088473149h,076777278h,0757A6F77h,098997A63h + dd 0868B8881h,063787868h,075646666h,09285817Bh,08C908588h,07E978388h,07E7A7F7Ch,0516E7979h + dd 0D2F1E5F0h,0C6A7735Fh,064646E9Dh,05F5D5A67h,0AA77665Dh,0E0DED8D1h,0EAF7E7E2h,0D2DED8DFh + dd 0D9D7D8D4h,0FAF4EBDEh,0E2D3EAFAh,0FAF5E7E8h,0FAFAFAFAh,0FAFAFAFAh,09CB5DBEEh,0777A7672h + dd 0717E797Ch,05A606069h,0666D6669h,0A8865D72h,067576C94h,0655379B6h,0735D604Ch,07C74866Fh + dd 0BD958596h,0EEBBDFBFh,0B0FAFAFAh,08B705F4Dh,06F73757Bh,0505B5A5Dh,0675A5B66h,066545553h + dd 064506387h,05561594Ch,05B5D6759h,0755E5056h,069869786h,07654615Fh,06078BA9Bh,05D6B7469h + dd 04C50494Ah,0DC934B49h,0E7F2ECDFh,093C5DAE6h,058595A7Bh,0604E4F57h,0554E4D54h,089736B5Fh + dd 0CEC9AB93h,0EEE9E1D5h,0DADDE2EBh,0B5C8D0D5h,086978FB5h,0B8C1BF98h,0A58B8BC4h,0C5C8C1C7h + dd 0998C9FBAh,04E3FA979h,0595B4E4Fh,04D465756h,04B494E4Fh,0454C4845h,05A622750h,0A5969789h + dd 0A4AAAFACh,02A839EA1h,045413745h,051465341h,078333E3Dh,08C96AB91h,08B81887Fh,09B9B897Bh + dd 0A598876Bh,082829C92h,0A0989591h,08B948B91h,08C909292h,08B877F81h,07A7D7D7Bh,049678B74h + dd 0D0EDF9ECh,09ECFA775h,068676559h,05F5F616Dh,0CE9D6666h,0E1E8EADFh,0E6E9D3D8h,0F2E9DFE2h + dd 0E5E0D7DCh,0FAF7F0E9h,0ECF1F0F3h,0EEE4EFF8h,0FAFAFAF3h,0F3FAFAFAh,0A7BAD2D5h,08086898Ch + dd 06C7A806Fh,053586674h,0586C6B6Fh,06B715D5Fh,059588CAFh,06A457BA5h,06C5E5D67h,06F706973h + dd 0C2A07C58h,0F7DDC8AFh,061A6F3F4h,0DE77605Ch,063696787h,05B5A686Bh,05466665Eh,05A546066h + dd 0665F7871h,04D535E62h,050545358h,039404E54h,08C726044h,0947D9AA1h,0544D828Ah,06670897Bh + dd 047555557h,0C078635Ch,0CEEADFDEh,0525985B7h,0685E554Bh,09C8A7C74h,075829199h,05E545C60h + dd 0AE937D72h,0F2E9DBC5h,0E1E7EAEDh,0BDD3C6DAh,0809DA3BBh,0ABA18A75h,0A07D65A2h,0DABFCEB2h + dd 0A5A2A8C3h,04E4282B6h,05B594C4Eh,04E4F525Eh,04F4B4F50h,049534E4Dh,072633042h,09F8F8D8Dh + dd 0A9B5B3A9h,07097889Bh,04343412Ah,04051653Eh,03E304937h,08A9E8E9Ah,0928C7C70h,086948E88h + dd 0A2A26D8Eh,095957EA1h,0AA9CA09Eh,0948C8E9Ah,07384868Dh,085798482h,07A808587h,05472827Bh + dd 0CEEAFAEBh,0466B978Bh,050545B48h,06165746Bh,0D5C29F6Ch,0E2EDF2E3h,0DFD5C9CFh,0E8E7E5E4h + dd 0FAFAE8D5h,0FAFAFAFAh,0D6E1F4FAh,0E1D9C5CBh,0FAFAF9EBh,0D3F2FAFAh,08D94A6A6h,0848F9EAAh + dd 05F76877Bh,0687C8073h,0557A9A87h,059547067h,06A5E8183h,0734E7B99h,070676771h,06E6D6272h + dd 09B7C867Dh,0FAE5B298h,04F52ACEFh,0ED9E5F5Bh,0605869B6h,054525C64h,07A6C6554h,0D6BAA78Fh + dd 09D9DBBA9h,0A99D8E95h,0678289A7h,039466361h,051423A4Bh,065737460h,0655A3B46h,0777D717Bh + dd 060797073h,08D888273h,09DAAC8A7h,06E938D91h,0B3A9846Eh,09C9F9BA3h,0909FA49Dh,0AC97989Bh + dd 07B5E7FADh,0E8DFC9ABh,0EEF3F2E8h,0C6DFD7E4h,0939CA5B6h,0A3B0A690h,0A8A39AA0h,0DAC4B6BDh + dd 0928E9AB8h,0474B5EB7h,04C554849h,04146464Ah,0433E4343h,03E474341h,08B723646h,08A838B9Ah + dd 09DB5B4A7h,07BA48F82h,037393B29h,035626838h,028472E36h,07E919078h,093947F65h,083877D88h + dd 080A45569h,0747E8B99h,07F9E9F85h,0969C948Ah,07C828B93h,08A6F7581h,07C818585h,054837E67h + dd 0D2E9F5F4h,056547880h,065766463h,07668706Dh,0DEC5C19Ch,0DDE9EDEEh,0E8DFC1CDh,0E9E4EAEBh + dd 0FAF9EFEEh,0FAFAFAFAh,0C4E9F0F7h,0E2CEAEB3h,0F8FAFAF2h,0AFD8F6F9h,07068798Ch,08C86848Ah + dd 0687C7F84h,064787566h,0688C9888h,057587570h,056557E5Bh,0624D606Ch,06E655A4Dh,06972615Bh + dd 06D877772h,0D8B8C59Eh,06A5C658Fh,0E3E28C65h,0775557A0h,085856F6Fh,0BFA3BE94h,0B1B8C6C5h + dd 0A9A0B9BBh,09F9AA3ABh,08E95899Ah,098A8A398h,051546680h,068627F6Dh,061686863h,0625E7065h + dd 052586061h,05F565160h,0614C5C50h,0643F4954h,0B49EA79Fh,0A0A9A3A9h,0999C9D9Ah,0AE8D8785h + dd 0649ED2E9h,0D6B5835Bh,0EFF3E7E4h,0D5DDE9E6h,0798AA4B3h,0A7908779h,0BCA58793h,0AAADB1BCh + dd 082778596h,04B4B4580h,06E564B4Ch,043656D54h,043404545h,03D45413Fh,0937E2F53h,092858498h + dd 093B3B09Ch,0849FA98Eh,038353831h,03F8F883Fh,041473132h,094A68D36h,09C96A67Dh,07D7F909Ch + dd 05F56454Eh,0576A8666h,0968A926Fh,0957F929Ah,0808A9F9Eh,08686817Bh,07B7E7E7Bh,05B7A6464h + dd 0C2DCE2EAh,064684975h,067747C6Eh,0AC807975h,0D5CECEC8h,0B4C0DBDDh,0C8B5B2BAh,0F8FAE6D7h + dd 0F8F6E1E4h,0CBE0CFEBh,0A1B1B4BFh,0ECCEC1ABh,0F0F8F4EAh,0A0BDBDD4h,07489A59Ch,0728BA1A1h + dd 0A7A27964h,0A4897689h,08988A59Dh,094987891h,070707784h,05E807972h,060576C5Dh,091767171h + dd 0A9818072h,07FBCE8CDh,046586361h,0D8E4BD81h,0645B4664h,089A7A059h,07186AAA0h,0CCB5D1A0h + dd 0A2D5CEB5h,0716C7477h,0564C6990h,07C706959h,065947B86h,0645D4635h,0615B5C5Fh,052525E48h + dd 05F5C6860h,054565B76h,0545E5862h,0AA68334Eh,09E9AB9B5h,0B8B2AAA3h,09DB2C399h,0AF9696ABh + dd 0BDD0C9D2h,0A15A56A7h,0E6E8E1CBh,0D1D9E8FAh,0B7C2DAD8h,0BBB6B5A0h,0BDB6A7BEh,0C5CBBEB6h + dd 0A0A58ED2h,052685F75h,06B5F5C58h,0626E6E65h,056666566h,0776E5569h,09D8E7679h,0908D8F7Ch + dd 0818E9D9Bh,0988D8284h,059555644h,083919A4Eh,06A576E51h,0929C5B54h,07978747Dh,03E5F5B6Ch + dd 07C645443h,0748C8285h,085897784h,098908A8Ah,095969192h,0948F88A5h,0747A6B8Ch,07F7C7C78h + dd 087A8AB98h,06E8C7556h,095989696h,0D5B4848Ah,0C6C9D3DCh,0989BB0BCh,0A68D929Dh,0EDFAF3CFh + dd 0BABAD0E8h,0B1ADB6B9h,0B4C8C0B5h,0FAEED6B7h,0E0E7F5FAh,08BB9AAB1h,06E919896h,06F7C8A97h + dd 087857773h,0717A7D7Dh,08063657Bh,05973666Bh,044444D48h,042434247h,043434945h,076413B3Bh + dd 0A16C4D50h,03D5188B0h,06748473Dh,073F1D5A5h,0AA5A6948h,08881898Eh,07C7E999Ah,06F749568h + dd 07892987Bh,06F65686Ah,07B829994h,0726E6770h,06949586Bh,03251828Dh,050615D53h,066665657h + dd 047566E71h,052645354h,04E5A6761h,0B29C7351h,08A7A93B9h,0C2AE8F86h,09CAFBC9Bh,0A29984A4h + dd 0C1C8C8B8h,05291C0C5h,0EEC89A7Dh,0DADAE4EAh,0BFB4E0E2h,0D8D3B5AFh,0ADBEA9C9h,0B1CEA49Dh + dd 07C9D8CAAh,05B5C6468h,04D48555Dh,04E484B44h,04D4B4E4Fh,0396F4133h,05E608752h,07D8B896Ah + dd 08E84807Dh,09893838Dh,0303E4A39h,056879142h,0543D4531h,071615459h,087905D67h,0646A7079h + dd 08A776669h,08C8A868Ah,079775685h,094937864h,0989EA19Eh,05A5D729Bh,072756063h,08483807Fh + dd 07DB4F2F9h,06C687260h,06E5E7379h,0D7CDA779h,0CACBD1E2h,0A1A7BAC6h,0A99B9D96h,0EDFAEFD5h + dd 0C4A3C7ECh,0D0DAC8CBh,0C4D6D5D5h,0FAFAE4C7h,0E9E2DBF0h,095A6B8D5h,075BCC8B0h,06163758Ch + dd 085797978h,060757C7Bh,07F576276h,067643F65h,046455058h,058524748h,04F5A585Ah,081564E48h + dd 09CAA7460h,0554B5074h,0A94E4451h,05793F6CFh,097706B8Dh,0A7A0A29Fh,067688198h,053586445h + dd 0697B7556h,0716A776Eh,077746F97h,091877E7Bh,0747D9393h,0988D6573h,05E544350h,061605957h + dd 0666B7271h,0606E6775h,0655A6365h,090959994h,0705A81ADh,08488897Ch,093A09F90h,09D909B99h + dd 0BAB9B9A2h,0C0C4B1C3h,0B36F4E6Ch,0D5E1E9DBh,08196AACEh,0CAC5A974h,0BBBAAABBh,0BBC0AAB8h + dd 08E968CACh,04F5F5366h,0554A5153h,055484E4Dh,0464B4F54h,059363D4Ah,08C6B7F93h,071949781h + dd 093887B7Eh,08B8B7884h,02A374A2Dh,0729C8451h,03A403A39h,03625373Bh,08C87778Dh,063649793h + dd 09391836Eh,087888C8Fh,08D696471h,08B968B7Fh,09F9EA69Ch,060587B9Ah,080867D78h,08B8A8684h + dd 0677ADCFAh,08B676465h,077666974h,0DDCBC4A6h,0CFCED3E1h,091AEC0CCh,0BCAC9280h,0F2F9E0DEh + dd 0B0A2BAD8h,0CCC2AFB1h,0DCE8E0DCh,0F9FAFAECh,0B6C8CCD2h,0A6998EA3h,08494B0C8h,06F646162h + dd 082737367h,0717E8084h,084537681h,0746D83A2h,052525D59h,05E4D4F55h,04C75A985h,07145434Bh + dd 05FADAD83h,04C494141h,0D1A8624Ch,06B54B2DCh,0B7646684h,07AAAC8DBh,0585E6570h,06D655C56h + dd 0859F765Ah,070555857h,06F78789Fh,099919179h,098A0ABACh,07999938Eh,0405D9478h,05D705644h + dd 056545D5Eh,057696771h,09776545Bh,096A3898Ch,07E738E9Eh,08A959B8Ah,08D988C8Fh,0948E9890h + dd 09A9E9CA0h,0A897A693h,0807892BDh,0E3E0D8B7h,099B4C0E3h,0C2C2A377h,0B1B0BCB6h,0BBCF9BB3h + dd 0798A898Fh,056554355h,0615E5550h,0534B555Ah,03C42484Fh,0B5674030h,07788A0ACh,07488888Ah + dd 0918E7873h,08B7E6E78h,045384935h,080968365h,04A563740h,03E2F3B49h,08880909Bh,088816780h + dd 08F998A83h,08A89918Ch,07C776A6Bh,08F8D6D7Bh,0A2A2A79Dh,0725E8593h,07F7D8287h,0918F8D8Bh + dd 04F52A2F8h,08084725Ch,0876F6969h,0D5D8CFB5h,0BBC4D0D1h,074BCB4BDh,0A7AF9078h,0D7E6D8D7h + dd 0A6B1ACB7h,0C1B4A3A1h,0E7E6CED9h,0F8FAFAF4h,0AED8EBCDh,0A28798ADh,08498B2CBh,089847A82h + dd 092839985h,08B9D838Dh,06D778078h,05B6D8660h,04D4D4F53h,05256484Dh,02C4AD2AFh,082434C51h + dd 049559CA5h,0434B403Ah,0DCBFA95Eh,06144739Fh,0A1616F60h,0877CACB5h,073687983h,089918582h + dd 094948B7Eh,07E807367h,0585B6185h,0A4A4A675h,09E93ABB0h,0A79B94A4h,079918786h,07D73755Eh + dd 090878D6Ah,06A767C8Eh,07DA69C84h,091968670h,08B9AA193h,0A18B8C93h,0AEB0ADABh,0A5989795h + dd 0ACB3BAB0h,0C3B09DA2h,05097C6C9h,0D3D4C074h,0CCC0C6D8h,0B8BFB5A5h,0B5B5AAADh,0B8AD98B0h + dd 06C8490AEh,05D644D64h,0735F5D5Bh,0535D5C66h,031384051h,084979351h,0A7A1ACB7h,099989399h + dd 088979695h,08E7B7E71h,03E394D40h,0878E946Bh,0747A3847h,05F4C3352h,085848A88h,06A725D4Eh + dd 0948C8073h,0868B9195h,08070646Eh,09DA77674h,09BA4ACA6h,06E60849Eh,099857586h,0878B8E91h + dd 06A4C73DCh,06B75766Dh,0C6897177h,0C5C9C3CFh,0ABAAB4C2h,09987A8A7h,090A58F5Ah,0BFC8B7B2h + dd 0A6B4BAB3h,0C9BCA6A4h,0DCC2BDD4h,0EFF3F5DFh,0C2C4C9CAh,092A1ADB8h,0809FBEC5h,09690848Fh + dd 0A6909583h,0848B7B9Ah,09DB39E86h,0676B7870h,06F6F7075h,07576726Fh,0716E8989h,0B29E5D60h + dd 05D657379h,07E4D555Dh,0AFDAD2C7h,084627973h,09E82867Bh,06E73948Dh,0807F6773h,08A8D827Fh + dd 05B556C6Ch,058545553h,06C70676Ah,0A6967875h,0A192A3AFh,0BAA6A5ADh,09D7EA3A7h,0475B4F95h + dd 059564A4Bh,0535F5051h,07780AB6Bh,0826D6562h,0617F8880h,08B6A5E60h,0C8C5B29Dh,0A3ACA8AEh + dd 0AAAFB5ACh,0B6B0999Eh,095C9B6B7h,0D7C55D35h,0CEBFD3C9h,0C0BDAAAFh,0B6B7B0BAh,0BAC4B3BDh + dd 0A8A9B8B5h,05F684E84h,05A785D50h,054545E57h,07A594C53h,07A92A192h,0867C7880h,08F8E888Ch + dd 0A3AAA19Ah,0897E8A8Ch,054404C43h,08B818088h,05A5A3E5Ah,027324B67h,055745654h,03C3F423Ch + dd 0826E363Dh,088858687h,079616978h,09496868Ch,09C9F989Bh,06A6F8D9Bh,081795D5Bh,0797B8083h + dd 0816964A2h,075626B7Dh,0BEAB8273h,0B3C2C8BDh,08892A9B2h,09B859990h,08397A887h,08C92978Fh + dd 091948A80h,0AEA29292h,0C7C9C3C4h,0DBD4D3C7h,0B4B8ADD1h,0958B8FA1h,07B809CA5h,0CDD2C4A6h + dd 07B899FB0h,07A74757Dh,0818F9795h,07A786C7Dh,068686975h,077576568h,0626A6970h,07785645Eh + dd 04F59524Dh,0D6A45542h,06487B3E7h,04756704Dh,0AF5A5443h,0564D4D72h,065575969h,06D6B5E5Fh + dd 05B646C60h,067615D60h,06E73746Ch,0878C8A71h,0A4939692h,0C0ADB5B3h,07AAEB9BFh,04878958Dh + dd 069604B61h,06D505862h,068719CAAh,05C685E5Fh,0636C6965h,098806D62h,0BBACA19Eh,0B1AEA9C7h + dd 0ACAFAFADh,0B1AD9F9Dh,09EA7A6ABh,0BB5A4EA1h,0C3C1DBCAh,0ABA6A0BBh,0A9ADACACh,0A2B3BDB7h + dd 0B296818Eh,06C4E80B7h,07A73645Fh,052575E5Eh,0A9AA9A79h,0AAA89C9Eh,07F7A778Dh,08A877A73h + dd 096A19E98h,08D988783h,06344553Eh,08E808285h,0515F4E6Dh,055574F62h,07B473D7Eh,05B6E5959h + dd 07C7B5C4Eh,085878581h,0A89FA097h,072737590h,08B9497A0h,0837B808Ch,08B895B5Ch,07B7D7F7Fh + dd 0847C7380h,07F72727Ah,0C6D7C482h,0A1ACB2CBh,0A7A499ADh,08D8A808Eh,0A0A2A8B1h,093A39F99h + dd 0A094757Ch,0ABADA4A4h,0BABEC3C0h,0CACACEC6h,09CB6A4CEh,08F82808Bh,06F73AAC5h,0D8E0D7AAh + dd 0688085ADh,072767171h,088A39890h,0646F6E61h,054545353h,05C5B5354h,04759566Bh,03C55625Eh + dd 04B543F48h,0C0E7916Ah,05F487295h,0876D745Dh,083507E85h,041515859h,0675C6565h,0726A5C61h + dd 066735D5Fh,06E67646Ch,0897A706Fh,076777793h,0A298958Fh,0BEA2B0ABh,09BADA9C0h,06691A38Fh + dd 07263554Ch,0A25F606Eh,0756A7DA3h,0605F596Eh,064666268h,0A8A68D6Ch,0AFA8A29Fh,0B5AFBCC5h + dd 0ACB0AAB0h,0A3A4A4A1h,095AC95A5h,07B469E9Dh,0B3C1C5C9h,0919DA6BAh,0B1B3A799h,09D97BABAh + dd 0BEC99EA9h,04768ACB3h,041604A3Fh,088776357h,0ACAAAFA2h,0AEA9A5AAh,08C867389h,07C888682h + dd 092A3A5A4h,0819D8785h,07E3C4433h,0907E8A95h,050623379h,0233F4D53h,09D896186h,07C8D8245h + dd 087918266h,08F908C87h,09D999995h,0304DA4A0h,08D9C918Bh,096575885h,08B703069h,076767776h + dd 05B565550h,0858B7A5Ch,0DBDDE3B1h,0ACC3D8D7h,0878EA4A9h,0A8909893h,0ABA1A2B3h,09BA99EA0h + dd 0AC9E8285h,0A6A9ADA9h,0BBCDD0C2h,0BDC8D1C9h,0B8AEB2C7h,0B3B0C1BAh,09295C2C7h,0ECE9EFDEh + dd 0728787B4h,081918276h,0908C8C8Eh,0576D807Fh,054545A5Ah,04F5A5358h,04B485974h,04E4A5052h + dd 06B6E6560h,076918893h,0685F595Fh,08B856362h,075508895h,06556505Ch,0587B7E7Dh,07C70605Eh + dd 06C675869h,06C5F6870h,093958D6Ch,08081777Dh,097908980h,0C49D9699h,0969D98ADh,0929E7275h + dd 0736D453Eh,088986664h,06658714Ch,077685E70h,047525465h,06B8E6264h,09594B5A0h,0A1AE8B7Eh + dd 0ACA4A798h,08B86909Ch,094A2968Bh,04C6E8E8Dh,0BDC1BD8Fh,088A0B1CBh,0ACA49794h,07E76B1C2h + dd 0CBC2886Fh,084A6BDC0h,0B1848271h,0BACFD3DDh,0A7B6C1CAh,0A8ABA9A9h,0B08C758Ah,0A5B6B0A5h + dd 09F9BAFA5h,0749C909Ah,08E4D4637h,0847B8C8Bh,04C892F79h,027404B52h,097574A8Ch,0979F5839h + dd 08E9E7F85h,0908B8B88h,0A9949C97h,04A46A99Fh,09C95918Eh,08C334595h,07A540E71h,0797C7B7Dh + dd 0574E5354h,0A8897A67h,0E3E5EADEh,0A9B9D0D9h,0948C98A5h,0918D929Bh,09B94959Ah,0A09C9894h + dd 0AB96767Ch,0B09AA6A3h,0BACDD0C7h,094B7D1C6h,0D7A7ACAEh,0C084CEEFh,09EA2BACCh,0D7D4E6F2h + dd 073869AC7h,0768A7F7Dh,0AF91937Ch,05D76A995h,05F5E656Ah,05F685E5Fh,04F4B476Ah,0605B5861h + dd 0636D645Eh,0656B6570h,065565458h,07970525Eh,061536E78h,065554F58h,054737E81h,063585259h + dd 063425677h,064615B5Dh,0759CA666h,06E716C82h,0776D6C73h,0BB9A8983h,09AA9A0A6h,09C798B93h + dd 06A73587Fh,0979A8B5Bh,0838E8E86h,077807E8Ah,0997F7A73h,0AEABA595h,0B59DB1A6h,0859CACA6h + dd 0ABA3A699h,0C5C1B2ADh,0B0A0A6BFh,092ADAAAEh,0C9CC9D69h,09495B4BDh,0B9A2B59Fh,0A281B7CAh + dd 0B2A9AE98h,07D8FA2BCh,0B0ACA67Ch,0D7D0D0DCh,0ACE4CBBAh,0ABAAA7A1h,0B59E7D94h,0B5CDCFBBh + dd 0B29AB0B1h,074A48B90h,09870434Bh,070889E85h,04AA1616Dh,01C3A4260h,0813B5186h,0938C3A27h + dd 0919E5D7Ch,08D919289h,097979F97h,02F255EA1h,091858262h,08120468Fh,089451974h,079797F85h + dd 064595A59h,0CFA1867Ch,0E1E9E6E7h,08EA1BECBh,08C888F8Bh,0897F7480h,092A1A397h,0AE9C958Dh + dd 0BFA16D80h,0B8A6BCBEh,0B7D2D3CAh,0ABADBFC2h,0DE9D9DBAh,0A987BDE8h,09D8CB6C1h,0C5AEC1E0h + dd 094C7A4A6h,08D8B7971h,0BDA4A8ABh,0525C8797h,05A4C4854h,055575059h,0413A5665h,05443455Ch + dd 059605C51h,0646B5E67h,05553585Fh,098715C58h,0745E708Ah,07D74727Ah,087898082h,09C958980h + dd 07B7B798Ah,092908374h,09EB3B39Fh,0A3B1B29Dh,0B4BEC5ABh,0C7A3B8B4h,0A0BEC0CEh,07A6C7D8Ch + dd 0564A76A8h,05783A950h,04D494740h,044424645h,09A737F65h,09E8D9780h,08F7AA6A6h,086945E7Fh + dd 0A6AA9FBDh,0B3C8CCC8h,0BDB6B7B9h,0BABFB1CCh,0C592375Eh,0988EC0C6h,0BC9E997Fh,0A4A2BFBBh + dd 09F8494A3h,09293A8BBh,0B6B6B495h,0BFD6CDDAh,0A5D8CFAEh,09A9BA09Ch,0A49E898Dh,0A6B7C3B1h + dd 0AFA29BADh,05699AB8Eh,08C8F5445h,06E86937Eh,06452356Dh,020362A6Eh,04E195775h,0836E2C11h + dd 0A6AD576Dh,08E85848Fh,08C747A83h,021212C86h,095927946h,078195B95h,07D3A1D74h,07375767Ah + dd 06558544Bh,0DCC59679h,0DFEDF3D6h,08995A6CAh,083717380h,099978C8Fh,08BA1B49Eh,09494888Bh + dd 0C9AA7B7Fh,0BBAFC2C0h,0BCD6DBD0h,09FA7AFBEh,0E2B2A2ACh,099ACBBD6h,0998AB2ABh,0AEA2B2C8h + dd 0A6A886AEh,0919A9396h,0DDD3B2A9h,096A4A7CBh,09284828Fh,0848F939Eh,0908A848Ch,098778791h + dd 090807985h,082836E8Eh,08187817Eh,07EA89A8Ah,0897D7C9Ch,069697484h,062656270h,0787D786Dh + dd 0A68A6B89h,0BC9A8DABh,0CCC3B4C7h,0D2E1C3B6h,0C1BEBDD1h,0C892C3C5h,077A3B8C6h,072928270h + dd 074677F8Ah,072A1A16Ch,054575E53h,061584C52h,0785C8C6Bh,09EB27C92h,07181B3A8h,0817E9286h + dd 0B4A1AEC5h,0BBC3CDD2h,0AFC9B9C2h,0C6BCBCC3h,0A1575CA6h,0909DB0D5h,0B6A89388h,090A5A9ABh + dd 0A69C988Eh,09E9EA6AFh,0A49CACA6h,08FA7ABA6h,09693887Bh,08D939C98h,097919A9Bh,0979CAD95h + dd 09FA699A0h,0587FA98Dh,08B9C7364h,084828B8Ch,04F445A79h,02E474259h,05538435Ah,050462022h + dd 084704350h,08A858285h,090807E8Ch,0524F5777h,08A927F52h,08A458C90h,0845B4A98h,07B7B7A7Fh + dd 074595B61h,0CCC8A68Eh,0BECADDD5h,0969B9DAFh,086909989h,083928785h,07D838177h,086968889h + dd 0DAC4978Dh,0C5C4D1CEh,0B7CAD5D3h,0A29AB7CAh,0DEC8B8A9h,0ACB1CEECh,0C0E0D6C9h,0C5C1C7C5h + dd 0AAC4CBC6h,0A8BAB5B9h,0E0EADBB4h,074B4C8EBh,05C596268h,05B655D64h,0615E6260h,0844D504Ah + dd 069786777h,08291877Ch,08199887Ch,05B898D80h,076606398h,061646F79h,060655D60h,097776B70h + dd 077967D8Dh,0B2675C75h,0AEC1BBBCh,0DACC8FC2h,0D0D3CCD3h,0C59DC2C6h,06CB2C6BEh,06D8C9F73h + dd 05D8A7969h,072716A5Bh,04E4C516Fh,07A614A58h,08C73A171h,0A19C8686h,086B4A4A7h,0ADAC7778h + dd 0CCA1C4C5h,0B6C1BBC8h,0C4C4AF97h,0B7B5BFBCh,0634A9AB2h,06EA8C0C5h,09E8A8F80h,0ACB3BAB6h + dd 0B6C0B2A6h,0A6A7A3A5h,0B2ADAAA2h,07BB3B9A3h,07C99B46Dh,09B999886h,09EAC99A2h,0A8AAB89Eh + dd 0A5BAB5B0h,03B539A9Bh,086917D44h,08D7C8D93h,04B3B3E67h,02120202Fh,04D31635Dh,05A641C29h + dd 0644A4A5Fh,0826C6A72h,063676B87h,0272A1C37h,08F977127h,048328F83h,050172858h,07673757Bh + dd 07C7C6E6Ch,0D6D6C8AEh,0C3C3DED7h,0959B93B0h,0AC7E767Dh,0988B7FBCh,09E828AAAh,0B2ABA4A3h + dd 0DED0B0B2h,0CBC6D2DDh,0BACCD2D2h,08CAECFC4h,0DEB9B9A7h,0AEA5C1DEh,0BDD1D9C9h,0B9B4B7B0h + dd 0C2C7B3BEh,0D9C29C9Ch,0E8E2E1E3h,084B3BDE0h,06B63534Fh,0585A5C63h,051524A48h,07B45514Fh + dd 0756A7467h,081827A76h,08C897E7Eh,08D6C8375h,074646197h,0756B6C76h,07F7D7668h,082877979h + dd 089987995h,097748881h,0B5E8B5D1h,0AF889FCAh,0D8CABAABh,0C9AFDAE1h,081A3BBD5h,08782827Eh + dd 07DA3875Dh,0504A4A3Ah,04E404948h,0615E4E4Bh,0694A9564h,09F887659h,09F8099AFh,0A699776Bh + dd 0D0B8A6B4h,06592B4E4h,0A7AC9461h,0A6A2AAABh,041769797h,0AC8EB68Dh,0A9828DB0h,0B9C7ACAFh + dd 0C3C8B7B3h,0A5AAA0AAh,0BDEED6B0h,0A7A3AEC4h,0A8C2C1A4h,0999B9DA0h,0A6A89EA5h,08AAEBDA9h + dd 0A0C6C9CAh,035357C95h,096928054h,08192939Eh,03D32556Bh,015322A35h,069626070h,07C6C5C5Bh + dd 05E514559h,0826C7372h,08E796F8Eh,037404347h,083907722h,031339283h,04D173561h,06A677979h + dd 0A6866A6Fh,0D7D2D6D1h,0B9B4C9D6h,052969CB0h,04F453120h,0958F8880h,09D93949Ah,09E8E9699h + dd 0D2CFB9AEh,0B5B4D2DBh,0CFCEC9BEh,09C94AEBCh,0D8CEC297h,0C0B4B6D6h,0C1CDD3C5h,0DFC7C5C3h + dd 0C4D5CEDCh,0DCDFD8BBh,0DCD9D9D6h,094A5C4CDh,0595A5275h,05F5A635Eh,0515A6160h,0834D6256h + dd 07B73806Eh,074797377h,0908C8D75h,0AC8D8685h,07467668Ch,0654D4F6Ah,06D6E6C6Ah,0668B7580h + dd 08B917872h,065798082h,0D7CCA6DCh,0A5C0B8B8h,093858580h,0BCB7B9A8h,0B5B3D2D1h,07A7282BBh + dd 0808E7067h,05B584E4Dh,062556257h,06E706966h,07D6E8552h,0BD9F9586h,0889F9799h,091998890h + dd 0B4AC9DA6h,0B4AFA3B1h,0AB9998C9h,09297A5ACh,073A8AD96h,0B9A9A176h,0BCB49EB5h,0D0D8D1C7h + dd 0DACEC6CDh,0AFB290A8h,0CDCDCAB9h,0D0B4BCBDh,0CFCABCB6h,09BA4A2B4h,0A6A19DA2h,08AC1B59Bh + dd 0A5C4B7AEh,05829588Ch,086807A95h,08491929Ch,04D35696Fh,01B2D2F4Bh,055526E7Eh,05A5D6257h + dd 0481D0824h,07F696264h,08E887D8Bh,032545645h,07875612Eh,0283F927Fh,0452A616Fh,06E6C7264h + dd 0B6895962h,0CFD3D8DAh,0ACA5B7C9h,039A2A0A7h,06624381Fh,0969E95B4h,095979CA0h,0A59C998Fh + dd 0D6C6A7A7h,0D4C8C9D2h,0CDBCBEC9h,096AAB4C4h,0EBEBD89Dh,0BBB2ADE7h,0D2D6D6CBh,0D8CDD7D8h + dd 0C5C8D7CFh,0DBCACAD0h,0BCC6C9E6h,09B9B94A6h,0514D6B7Ch,062647272h,04549505Ch,06A304E45h + dd 08C738060h,07A858D98h,0A9A39882h,0A37C9583h,0454A525Fh,05D504E4Ah,0786D635Fh,0807A7F74h + dd 0604E4B6Ah,0393F4E4Eh,09FD1AD8Bh,0F7E4E1C8h,0B2CCE0EAh,0928C94A3h,0B4B6C5B1h,0A5808FBAh + dd 0BCA593A3h,09E839DADh,09194A996h,07D949B9Bh,08DB39EB5h,0C0B0A8ABh,0BC89B5BDh,09BAD929Ch + dd 0C1AD9AA6h,0BFA8B1C8h,0C3BFCFBEh,0B0BDC8B7h,075ACBAB8h,059654339h,05A524341h,0B8B9F1A8h + dd 0D3C5CDC3h,0ADAE8FABh,0BCC0D1C7h,0A99B929Dh,0A2CBC894h,0A2968C95h,0978E989Fh,0A2BF838Bh + dd 08D9B989Dh,06C313C6Ch,07B7F8092h,0778A938Bh,037316B5Bh,02A252437h,060606F70h,069708E78h + dd 0250D2335h,075696252h,07984797Eh,03076834Bh,07D685626h,04A598583h,0635E8A8Ch,0786D7060h + dd 0BD945760h,0D6E1E2DDh,09E95A1BFh,06A94A19Ah,065341A44h,0A69B8D98h,096777EAEh,09F948494h + dd 0D2BEB6B0h,0C1D0B4C0h,0C1BCB7B7h,07DA0ABBEh,0EFEFDEA1h,0C6BCA7ECh,0D0D9E7EAh,0D7DBE4DCh + dd 0B5CFD7DBh,0D4CAB4A4h,0ABBBC5D4h,0889B9791h,061615294h,06569796Bh,05B585466h,095715156h + dd 09B838371h,0AAB1AFA8h,0B7BCA7ADh,0B2B2C5ACh,0817D8469h,080717680h,09A908A8Fh,08D979D93h + dd 084789285h,08E707976h,0BE877F68h,0FAF2E7E2h,0F8FAFAFAh,0ACEDEEF4h,0A284657Dh,0D7C498ADh + dd 0C8BBD2C8h,092B0E0D7h,09084A08Ah,05C5E7A8Eh,0A68A5062h,0A9AFA3ADh,07278A9B8h,0B2B1756Fh + dd 0C4CCB3B0h,0E4B5BFC9h,0B7C2C7BAh,0ADC1C5ACh,084ABCBB8h,06E3C2439h,0997A75A3h,0B2CAE095h + dd 0CFC2B4ABh,08E908AAEh,088878885h,08A817E93h,09197A08Eh,0A48695A4h,0857C919Eh,098826C7Ah + dd 08FA8917Fh,07A4D365Fh,072726B76h,0767F7E7Eh,030447C66h,043393432h,048585A58h,0727C685Bh + dd 0080E2934h,07D4E4F34h,06D857F7Dh,03C90862Eh,06B705D23h,067808E7Ah,08A7F7878h,07D6B6E62h + dd 0C3AE976Bh,0C8D0D7DBh,0A5868FBBh,07D9BA7A6h,086467C73h,09DA0AD9Eh,0B2A498C3h,0BCA9BAB8h + dd 0C8C0B4ADh,0B2AEBDB6h,0B6CDB6B7h,09A9EB1BCh,0E7DFC8AEh,0B99FBAD9h,0B2BDC6D3h,0C2B1ACB4h + dd 0BCBDB2B9h,0E6CCA1A4h,0B4A1B0C3h,0A6AFA6A8h,091879F9Fh,088849384h,06C8D5F85h,05A615D6Ch + dd 04D4C6267h,0887F6962h,082656462h,06F959080h,06B4B5C41h,0807C7776h,0767C7577h,07973676Ch + dd 06E648D68h,070735F51h,0F6CA8B80h,0FAFAFAFAh,0FAFAFAFAh,0F8FAFAFAh,06984BAD4h,0C7CEC789h + dd 0B6A3C4C9h,086AFD0BEh,07D898477h,053465489h,096585254h,0B9BAA99Ch,0647088ADh,0BCA58D59h + dd 0BFBDB8AEh,0B9C4AFCBh,0B6BBCCCFh,0A7A29DBEh,0B7B3B9A8h,0833B3561h,0705D94C3h,0737C868Bh + dd 0988B7D70h,09BAF94A3h,0B7AAB098h,0A5ACB0BBh,0AAB3B1BFh,0B3A7A6C4h,092A8A2A6h,0A29F9A9Fh + dd 06A9D9FAEh,09273503Ch,086979089h,0A9AB9B93h,05862938Ah,062556857h,0646A6F80h,05E706762h + dd 05875764Eh,0888D8432h,075747B77h,047817264h,08D8D6C51h,06A6F9989h,0896E8975h,06B77658Ch + dd 0C9C3BBA1h,0A7B1BAC8h,07A7B809Ah,07C858F8Ch,0A4849C85h,098A68F96h,0999C9F95h,09C908794h + dd 0C8A59D96h,0A4A6B6BBh,0BCA19B9Dh,0A890A8BEh,0E2E4CAB1h,0A39BA9D1h,0BECCDEDEh,0A4B4BAB5h + dd 0A4A8A6ABh,0DFBD9393h,0C09CB6CFh,0B0B7C3D4h,06F76A398h,09B9A646Bh,04D6A7B7Ah,044596058h + dd 06F898060h,074626A76h,0817A7C96h,05F80A18Eh,0866A5D56h,0818F8074h,085837A7Eh,081706676h + dd 05D578173h,06B68615Eh,0F7FAD066h,0FAFAFAFAh,0FAFAFAFAh,0FAFAFAFAh,0BDE1DEF1h,0C7A97B88h + dd 0A2C9CEDBh,080D1E8E1h,07E7E7461h,059595172h,089585F51h,0A19E8085h,0606A9AA3h,0B1A6A97Dh + dd 0D0C8BEBFh,0C6C9B2D0h,0C3BBBABAh,0ABC0CFC5h,089849C99h,0453B3862h,069403247h,05B676B76h + dd 05D575F59h,07C876C6Fh,0986E8683h,0B9C1B8C5h,0B2BBB9C7h,0C199A4C6h,081A99CA3h,0AEACA1A1h + dd 07CA9B2A1h,07E846656h,07E8C8379h,08488837Eh,04B4A7782h,0462A463Ch,0807C6B86h,07298A49Eh + dd 06A887A2Ch,091854918h,03A466374h,0458C7E48h,0706C4C3Dh,06C758D7Ah,06D718C75h,057615B77h + dd 0CED6D4C8h,0A5B2BEC8h,07781849Ch,08B828A8Ch,092797892h,09395989Eh,073697E8Dh,08C839892h + dd 0BC93958Eh,09193C2C8h,06E93A6A2h,0967C88A5h,0DEE6C29Ah,0ADB1A7CFh,097A9D4E0h,09AA5A29Bh + dd 0807E8481h,0DDB2847Eh,0C4AABDE4h,0B3B7C9C5h,0889CB1A6h,095974B6Fh,04D586E77h,04D4B4153h + dd 0979F6A34h,0657389A9h,07975687Eh,04D40436Fh,070616061h,086938069h,082807A86h,0667B7873h + dd 055587169h,0734E6369h,0FAFAF7C3h,0FAFAFAFAh,0FAFAFAFAh,0FAFAFAFAh,0E9EBEAF5h,07E93CEF1h + dd 09BE1D586h,0AFE5D3BCh,070815E62h,057755B59h,06688825Fh,0A08E655Ah,09E7F8B95h,0BBA48690h + dd 0BFBAACBAh,0CCC3C0C5h,0C2D2D0CEh,05E7593B1h,0938D6561h,0A19D9193h,0C2B4AAA5h,0676D616Ah + dd 06A685A6Ch,084847275h,096839598h,0ABB9B8C3h,0A9BBAFB1h,0BEC1BFA4h,08A8BA7A9h,0A4A9A19Eh + dd 07B8BA7AEh,0807F7E7Bh,08B929590h,07E909286h,047488589h,0632B363Bh,06F5C696Ah,0799EA4A6h + dd 06B6B7F35h,06A502837h,030317577h,03D78544Ah,070624438h,08681767Ch,061758A87h,06B61555Ch + dd 0D4DAD2D0h,096A5B7C2h,07C7E888Eh,0877E8286h,09C8B617Ch,0909E8B96h,087988D86h,0A5B38797h + dd 0B497949Ch,0BF88D1D7h,080AAC9C2h,09CA4A48Ch,0DCE1BA93h,0A2B5A0D4h,08B92C7DFh,0B9A69096h + dd 06D758E93h,0C8A68B7Bh,0B8A1BBD5h,09EBBCFBBh,07CA1A5A8h,070795972h,04357567Ah,06A584D4Eh + dd 071765456h,041463F65h,05B555043h,04C3E3E53h,06D5B4B4Ch,0898A8C81h,0A6948389h,080969187h + dd 04A61766Fh,0B36E5A60h,0FAFAFADCh,0FAFAFAFAh,0FAFAFAFAh,0FAFAFAFAh,0F7F8FAFAh,0E2FAF1F4h + dd 0BAA79CABh,0D6E2D0A8h,085866D8Dh,077836E63h,0738A8985h,090818A8Ch,0AFA7A2B8h,0B8A59C9Ch + dd 0BFB9B0CBh,0B8C9D5B9h,08396BCB7h,0A28F818Ch,0B2C1BFB3h,0A9A9B6C9h,0B9AAB2B1h,066664B75h + dd 0667EA190h,090827471h,0959EA5A6h,0BDBABCB2h,09DBEB2B7h,0BCABBDA2h,0A0A1A7B5h,09EABA6A3h + dd 08284838Bh,08F797A81h,073748893h,09CA69978h,04C5BB2B4h,064345450h,06C5D6E5Fh,069B2A4B2h + dd 073786C35h,07842254Dh,032418B88h,039635E4Eh,07B745A41h,06F7B788Fh,0484E4E5Eh,05A59626Bh + dd 0D2E0DED5h,097A4B2BFh,0837B9191h,07B7F747Ch,0A98E8E7Dh,092949CA9h,0999C9B8Ch,09CA69586h + dd 0C1AFA48Ch,0D5DBD4CCh,09075B6C1h,08A6B96A9h,0D8DABEA6h,0848FA8CCh,08C99CDC7h,0A7867A88h + dd 07B81B2B4h,0D8B7937Eh,0B893B5D9h,0ACC3A6B5h,075AAB592h,03D7F5478h,04F673E94h,07A553D38h + dd 0483A4B4Eh,0594E5D5Eh,0828A7467h,0546A8678h,067514943h,0AA908D7Fh,0717C7977h,0787C7779h + dd 05F6E8077h,0D5C67E71h,0FAFAF9E2h,0FAFAFAFAh,0FAFAFAFAh,0FAFAFAFAh,0FAFAFAFAh,0FAFAFAFAh + dd 085AFEFFAh,0C7C5CAA1h,08DA085B8h,06A878E8Dh,04345985Eh,057573A4Bh,0A3866162h,08463605Dh + dd 07678694Fh,063925483h,0726C4B4Ah,0C5B6A375h,0AAACB4C0h,0B3AFAEAAh,0B3AEB7B6h,0896B447Ch + dd 06F7A929Fh,088A79F85h,091897A91h,0BABFB5A5h,0BAC0BFB1h,0C8BBC38Ah,0958D8EBFh,09498AD9Ch + dd 068739188h,09C8F7476h,07867717Ah,075696875h,0483A907Dh,0764A4548h,05A4C5D64h,04F8D8680h + dd 06F826639h,066472C5Bh,045366A87h,047525E47h,083845053h,0807E8C8Fh,068536480h,06E617073h + dd 0C2D1D3D0h,0949BB2BAh,08E808F94h,07C838789h,0AAA18B87h,0A7A2B7B3h,091A39998h,0778A7989h + dd 0D5D4CD7Dh,0E8E1DDD7h,059489BCFh,08B71948Bh,0DCD9C49Dh,093807EBDh,05F70A6B4h,0B0877A9Eh + dd 0A5B5C3C1h,0C9AA8E85h,0B38CA7D2h,0BCBF9CACh,086A499A6h,091977482h,067737A9Eh,09A967E7Eh + dd 0928A9DA0h,0B69E9994h,0D2DFE4DCh,0A5B4D3C3h,06D97968Dh,093886185h,08083818Ch,07A75797Dh + dd 07E7E7C6Eh,0F2E6CA85h,0FAFAFAFAh,0FAFAFAFAh,0FAFAFAFAh,0FAFAFAFAh,0FAFAFAFAh,0FAFAFAFAh + dd 07FD5FAFAh,09171604Eh,05D625F7Dh,02C575756h,04D3D6637h,052817659h,0A59E7F6Ch,07E69596Fh + dd 0978E6F6Bh,081667991h,0C1C5ACA5h,0C0BEBABFh,09DA5ACB0h,0AEAEA69Eh,0A6A4AAABh,0818A5D84h + dd 09291938Eh,0ACA99285h,09896A7A8h,0ADACA5A4h,09BA0A8B5h,0ADAEAFAFh,077818CA7h,08B7C8787h + dd 0938D9489h,095969CA0h,09785849Ch,0978B86A2h,07A5A9395h,08B6C6470h,05B4D626Eh,05E6C5A5Ch + dd 0979C7E56h,076406AA2h,07C54549Eh,0565D7188h,0706B5054h,06E7B6B66h,0786F6A62h,085877F64h + dd 0C9CCC5C0h,0929BB1C4h,0978B9C96h,0898F958Fh,08CABA298h,0A2888F7Fh,06378A09Eh,08A76666Ah + dd 0ACA7B294h,0BECAC6B7h,09D758FADh,0818E9F9Eh,0BCC3AD93h,0B2A89CB4h,0A8A9C3C3h,0C9CCAF9Dh + dd 0AEB7C4CBh,0CEB7A190h,0A5AAB4CFh,099A9B2B6h,09BB0AE99h,09CB5A196h,0676F8071h,0A96B6B7Ah + dd 07070ABC9h,0D2A8836Fh,0ECDCDBE3h,0489DD9D4h,0405E4E41h,06D7A5476h,0435D5841h,069505253h + dd 0696D8658h,0F1D3E8ACh,0FAFAFAF5h,0FAFAFAFAh,0FAFAFAFAh,0FAFAFAFAh,0FAFAFAFAh,0FAFAFAFAh + dd 0E2EDF7F8h,07F55589Dh,064596088h,0535C5956h,03D447C5Eh,09577A288h,088898294h,0B6676981h + dd 061535A84h,0EACCA265h,0CCDDD0DBh,0ADAEAAC2h,09FA4A9A7h,0B2B4AAA0h,0B6AAADAFh,0A095468Fh + dd 07E8F93A1h,06D89BA8Ch,0706C8768h,09790878Ch,089867890h,08D7E7CACh,09798968Dh,088909A92h + dd 095929597h,09DA49D97h,09793929Dh,0898498A2h,04F46897Ah,07C63423Fh,061485261h,05B8D8B78h + dd 0536B5637h,04741635Dh,0745B537Ch,0839C9297h,0917E6D65h,08078889Bh,03E444A5Bh,07965504Dh + dd 0C6C2BFBEh,096A3B3C0h,0947F7D91h,09F9C998Eh,0A1B3BAA3h,0CAD0CCACh,0BB9A9FA9h,0B09EA1B5h + dd 0C4AFB8AFh,0D0DFE1D9h,0BCB3A7C4h,0909BA2A4h,0CBBBA0ABh,0B59C8BB2h,0B3C5DAD4h,0E8D8AFA4h + dd 0A59AD1E7h,0D3B48A8Dh,0A199AFC9h,0867F8A9Ah,0B2AAB392h,06BAA8393h,05248494Bh,0924F585Ah + dd 06164D8F4h,0BB9A6E5Bh,0D6E1D8CFh,05277CFC9h,058754F5Ch,04B678C82h,049646148h,0895C5850h + dd 0AF75869Fh,0FAF9D9DFh,0FAFAF4FAh,0FAFAFAFAh,0FAFAFAFAh,0FAFAFAFAh,0FAFAFAFAh,0FAF6F9FAh + dd 0F2F4F3F5h,04A7CACDFh,063667A53h,0645B5452h,05B5D7148h,083777154h,095927D7Ah,080776C58h + dd 09B6F5A52h,0F7FAF5D9h,0C3E4E1EFh,0B7B5B0ABh,0ACB2B5B7h,09FA1AAACh,0B1A1A3A0h,0A585589Bh + dd 071615777h,04853AF8Eh,060536543h,08A9E9B9Ah,06D75727Bh,0917E8A8Dh,09A94998Ah,089878D8Ch + dd 09E9EA1A9h,0A6A3969Dh,0989D9B90h,09088ADA7h,03F336E90h,0966E443Bh,07689828Dh,04B9A8C86h + dd 06562593Bh,051486C60h,09A4E467Ch,0789F989Eh,093785843h,070788A94h,070725C4Ch,06C573E45h + dd 0CCD0D5D5h,0B8B9C1C6h,0A39DA0ADh,0B9C0BFACh,0A5A87D95h,0C4D8D5B7h,0A99E9BC4h,0BBAFAE9Eh + dd 0D9D8CBC6h,0B9CCD0D5h,0C2B5A7AAh,06F707BC0h,0CAB59D91h,0AFBD89B8h,0ADC2B8B7h,0B5B9CAA2h + dd 0A8AECDD0h,0A1CB77A8h,08891A7DEh,0A47B8276h,0BCC2CBB0h,06F949EB7h,0485A5C5Ah,06E475668h + dd 0757FD0E0h,0AA8F7C6Ch,0BCCAC8B7h,06681BDE9h,04F656241h,037718073h,043444641h,0573A3E42h + dd 0D3B55B91h,0FAFAF2DCh,0FAFAFAFAh,0FAFAFAFAh,0FAFAFAFAh,0FAFAFAFAh,0D7CDF6FAh,0DCD6E3E0h + dd 0E2DCD9E1h,0A3DDE0E2h,0555A5152h,060635F45h,0424E6A45h,056503E5Fh,076455B65h,060597A81h + dd 0E3CA8F6Eh,0F7F8F2E4h,0C8CEC8E1h,0A79AA2AEh,0B0ADB8AFh,090A0A4AFh,07E93A597h,0ACC54F8Eh + dd 05950617Dh,04B5BB097h,07E666955h,05A668BA1h,0646A8073h,07A897181h,0B1B79797h,089828390h + dd 0A9A994B3h,0979DA794h,0989FADB1h,09D8E9FAAh,04139508Ch,0B38C472Eh,09D98A6A2h,04D9C9897h + dd 05853664Ch,02A355967h,08F523F4Eh,085A2ABA9h,09E735F44h,05D77878Fh,04E5A834Ch,06650534Eh + dd 0D3DBE0E1h,0C3BFC1C9h,0ACAAA7C0h,0B2BAC8ABh,0ABBAC2B7h,0CEDBCCC5h,0B49E97C5h,0CAB8BFB4h + dd 0D8DAD2D3h,0A0BDC4CEh,0CEAFB2AEh,06476B2BBh,09EA27F73h,0BEB697A9h,0B4C6BCBCh,09CA9B1ADh + dd 0AEBACEC4h,0B7C28F9Fh,087A7B7C8h,0CEA37E81h,0B2C4B6B7h,063789D9Bh,053455B67h,049564C52h + dd 07A7CDCC2h,08D84736Ch,0CFD0CFC3h,0607DA3DBh,04E607163h,043466176h,040484E4Fh,03D464445h + dd 0E6CDA436h,0FAFAFAFAh,0FAFAE6FAh,0FAFAFAFAh,0FAFAFAFAh,0E4ECF3FAh,0D4D3E4EAh,0D1D2D0D5h + dd 0BDBEBEC7h,0CDCFC6BEh,0886A71B3h,0959E9EA3h,07D84988Eh,080898A96h,0AD948F85h,0A0736E87h + dd 0F9F7E7E1h,0FAFAF8F2h,0B5ABC1E3h,0B0AFB8BDh,0B09E95A4h,09B9B9AAAh,09AA59F9Bh,0B0C35895h + dd 05D60577Bh,05D7CA87Fh,08B837157h,0847A6F86h,067899566h,08895868Bh,08CB0AE89h,05E618F86h + dd 0A19A97A5h,0B5AD959Ch,0B1989698h,0756CA3B2h,03844487Bh,090845A2Dh,090868E9Bh,026877E8Bh + dd 04C5D7540h,028555D50h,082493A59h,08E9CB3ADh,098815E39h,062618B9Ch,057465139h,071604D4Ah + dd 0D7DDE1E1h,0C0C6CBCEh,0A1A4A2B6h,09DA29C99h,0B7DDCDA7h,0D7E1D9C4h,0BFA5A1D0h,0C6CEC6C8h + dd 0B4BFD2C6h,0A3AAA9ACh,0BDB2A8A1h,07A95C7C6h,0BBB1857Ah,0BABE9097h,0A0B1AAADh,0BDCEB79Ch + dd 0A8BAC9B7h,0C29FA0A8h,08FBDD7D4h,0B29A7790h,09D97AD9Eh,08F7E827Fh,03E4C6796h,0544B4A4Ah + dd 08382B88Fh,0A88A7272h,0B8CBC3C1h,077A2AAD0h,06F828080h,064645667h,07877746Dh,0687F7162h + dd 0F4C7D08Fh,0FAFAFAFAh,0FAF6DDF9h,0FAFAFAFAh,0FAFAFAFAh,0E1E2E9F9h,0DADDE4E4h,0BFC3C8D5h + dd 0B2B7B0BAh,0C4CBBAADh,07298C6C6h,0565A5F4Fh,03E47535Ah,057413939h,05A65584Eh,0E5AD715Ch + dd 0F5EEEEE8h,0F9FAF7F6h,0B6B5C2DAh,0ACA6A6B6h,0989B999Bh,0A59D9C9Ah,0A29F9FA5h,092924694h + dd 070636A7Bh,06D889D7Fh,0856F726Ah,06A83717Eh,0888C8262h,0687C8F9Dh,088769C61h,05E7E989Bh + dd 09C939A99h,0919B9599h,0AC9CA195h,05C60A493h,01E2C234Dh,04A5A5334h,058484A42h,011625665h + dd 050565F32h,042535A54h,07A6B5A6Ah,08DAAA397h,091795334h,0546C848Ch,0616B643Fh,06E5C4E67h + dd 0D2D8DBDBh,0C7CBD0D2h,0929499B7h,098A79793h,0D0E1B79Fh,0C9DCDED7h,0CBC3A8CAh,0C1C2C9CEh + dd 0A7B1BFC1h,090A3A1A2h,0CBD2B99Fh,08997B5C5h,0B6B1917Fh,0C5C29288h,0BBCDC9CFh,0CACAC4ACh + dd 0ACB9CABDh,0C3CDB2B8h,0A0A4B3B5h,0A7A79BAAh,0AD91A99Bh,0B3A8A193h,0AAAEA0B3h,0848D9DA5h + dd 0979D9E84h,0A6A7AA9Bh,0B7AFBAA8h,098DBBDC7h,082939895h,086887A85h,08C919592h,07B879384h + dd 0FAD8A2C6h,0C8DCF9FAh,0DADBD1CCh,0FAFAFAEAh,0DDE7F8FAh,0C1CECFD6h,0C2BEADB4h,0B1B1B9C1h + dd 0B4B1B0ADh,0C0B8B9B5h,097D0B1CAh,0675A4542h,05B5C5D5Bh,04833474Dh,058564C3Dh,0FAEEC988h + dd 0F9F9FAFAh,0FAFAFAFAh,0BBC2CAE2h,09C97A0AEh,09AA19B98h,0ABADAC9Fh,0A7ABA5A9h,0ABA43EADh + dd 0A18B8D9Ch,0969C9C93h,0A9979A92h,0989A94A9h,09CA7929Ah,0A0989EA0h,08A8CA297h,08B918C84h + dd 08A8A898Dh,094928E88h,0A3A3A1A2h,0A494A89Dh,0564A5057h,08A8D9D9Ah,09F9E918Eh,05D96A5AEh + dd 0A0AAAD75h,0577F97A2h,0857F774Dh,09382818Bh,079735958h,07C848376h,07F77677Ah,08C8E8E84h + dd 0D8D2D1D4h,0C8CACED5h,08D9392B8h,0868C8585h,0D2BEAF8Ch,0B7C0C6DAh,0C2BCB3B1h,0B5BCC4BFh + dd 0AAB0B6BAh,0A8979995h,0C7C2C1BEh,0A2A8BEC1h,0C4BFB0AFh,0BABCADB8h,0B9A6AABCh,0CABEB8B2h + dd 0B7B8C1D2h,0C8ACABB2h,0BFBDD2CFh,0BCC2A9BEh,0C3B6BAA8h,09BA1A697h,06E94B19Bh,0A2AA875Ah + dd 08D8A828Dh,06C7A8C84h,0928CA07Eh,06A6E8889h,05865836Ch,08F93867Ah,0A37F5A8Dh,0C4ADA7A9h + dd 0FAE6BDA1h,0D4CFE7FAh,0D1C5C8C4h,0FAFAF8D4h,0EBD8D7FAh,0A8BED8EAh,0C1BE9A99h,0B2BCB3BBh + dd 0AEAEA6A9h,0AFACACACh,0C8ACB9B6h,06C4C3974h,05E6D667Eh,07A4F6748h,08D818879h,0FAFAFAE9h + dd 0FAFAFAFAh,0F9FAFAFAh,0ABBED1E2h,0999FABA9h,09C9FA196h,0B0B2B2A4h,0A2ACAAB4h,0888D43BCh + dd 061848496h,0616C5C5Eh,08971636Eh,0A7B18DA8h,0A3A6B0A7h,089899EADh,093988272h,09FA89990h + dd 086918896h,0A8A48D88h,0A2B4BDA8h,0799D96A8h,055112135h,0A9A6A496h,0677C8D98h,037565B4Ah + dd 01D63401Fh,02D2D152Bh,05B726C1Dh,08575706Ah,06554345Ah,059676A6Ch,065565B5Ah,06D81795Dh + dd 0DFD8D6D9h,0DADEDFE2h,0A3A7A5CBh,0A7A39597h,0DCD4CBAFh,0B0C2C5D4h,0AD9FA29Dh,0C2BBB6B1h + dd 0B1B0B7BAh,0A7AFB4A6h,0CEDAB2A2h,0B6ACC0CEh,0C1D3C8BBh,0AFB1A1B3h,0A7A49FB7h,0A9AFB2B4h + dd 09DC0C1C3h,0CFBFAC84h,0B5B6C8CEh,0B9A2AAB1h,0AEA7B4ABh,0B3A2B6A8h,0727EACADh,0AFA57960h + dd 08287AEB0h,04A65716Ah,070686557h,06B605967h,06E6A806Dh,09B9A7E81h,08C76A196h,0A9E4A4B2h + dd 0F8F1E7AAh,0BCE2ECECh,0C6B3C1ABh,0FAFAEED7h,0E5DFDFEEh,09EAFBFD4h,0B3AB9A94h,0AFB2B1B2h + dd 0B1B3B3AFh,0B49D9DA7h,0B2ADB3B9h,05A3F84B2h,03844585Fh,0794E4E42h,0E99F7471h,0FAFAFAEEh + dd 0F0F7FAFAh,0EFF9E0E8h,0BAC0D6DFh,0ABADABB1h,0A5A1A1A5h,0B0B0B4AFh,0A6BBADB4h,0928651C3h + dd 07EA2B2A0h,0696C6E91h,09B62716Dh,0B0B89EB3h,0ACB6B4AAh,0BAB3B3B1h,09E978B7Dh,0A7A6B4A8h + dd 09AA09AA8h,0A0A8A7A4h,0ACA8B3A3h,050ADABAFh,07C3D2A3Dh,083969F90h,08CA7AE8Ah,0909D6E7Fh + dd 04D7D4762h,070A37F7Ah,06E6F934Dh,08A6F696Bh,0645B394Bh,06B7D7570h,05C44556Ah,074887657h + dd 0D8D3D3D3h,0D3D2D2D6h,09AA7AFC7h,09191898Ch,0D2D3C294h,097ADBBC8h,08872878Ah,0B6999E91h + dd 0C3C1B3ACh,0A696A3A8h,0D4D6C4B6h,0C4B0C6D3h,0C7D4D1BDh,0959497C1h,0788F89A3h,0C0C1AD99h + dd 09CA7BAC9h,0C9D2B999h,0B8C0CBD9h,0ADA2A6AFh,0A8AAAEAEh,08694ABACh,06E6CAD99h,0A3B19267h + dd 0A9B2C8A8h,04E515D70h,06971727Ch,061696158h,0625D6A61h,08EA5A189h,0A890B987h,09ED5C7A7h + dd 0E8F4FAE4h,0ADCEE4EDh,0B6AEC39Eh,0FAFAEFE5h,0CBD1DFEAh,0AFB6B8BFh,0B7B3AAAAh,0BABCAFB5h + dd 0B6B7B7B6h,0B4ACAEB3h,08EACB1B5h,03C86B2A6h,04C4D5428h,0525B3A46h,0D7DAB365h,0FAFAFAEBh + dd 0CFDCF0F4h,0CCE5CCC7h,0A59AAFC4h,0A69E9295h,0A7A29BA0h,08A8D96A0h,096998F8Ah,0C67B72BBh + dd 09BA796B2h,07B847CA8h,0986D636Fh,0A9B1A7A8h,09FA5AAABh,0B6B2B0AAh,09D939080h,0AD9F9798h + dd 09D93969Eh,0999FAAA7h,09E95A2A8h,0366BAD99h,09070315Bh,06A6D8B89h,0647D7F78h,075626F5Eh + dd 052785C63h,066846668h,05E909A30h,07F545E64h,06040345Dh,05F757172h,04D4E5C5Ch,07A8F774Dh + dd 0D1CECED0h,0DAD6D3D3h,09DA5AED2h,09D9B9294h,0DAE1C6A2h,0A3A9BECBh,0886E889Fh,0B1AA9A94h + dd 0D6C9B9AEh,0BCB0C5C7h,0CFD3D5D4h,0ABBACBD4h,0C7DFD6C1h,0B5A49EC1h,078818DB2h,0CAD0BD9Dh + dd 09EBDBB9Fh,0C9D3B8A0h,0ACBCBBDAh,0A7ABA49Eh,0ABB9ADA7h,0B3A28BA4h,0697BA2BEh,0A1A5614Ah + dd 0857B9B7Fh,0594E4F5Bh,0716E8490h,054667363h,07052605Dh,0C6BA958Ah,0ACAF9BB4h,09C7BBBB6h + dd 0D7F1FAFAh,09EABCBE6h,0929FC4A2h,0EBFAF4D3h,0B2B9C7D1h,0B8B3B8B7h,0ADADAFB7h,09297A4AAh + dd 09D978E8Dh,0B0A49E9Eh,09CB1B2B1h,07FB5A28Ah,086785145h,09E7D6E6Ch,0DDDCF5D8h,0FAFAFAFAh + dd 0D1D9E8EEh,0CBEFD6CAh,0B0B3BEC6h,0ACA69FADh,0B3B6B5AEh,0A6ADA7A8h,0B3ABB6A6h,0BF668CAAh + dd 0939B799Eh,08E8C638Bh,076896578h,09EBDA79Bh,098939EA9h,08D9BB0ABh,090909C7Ah,093948A9Ah + dd 0A2889698h,09C999A9Ch,09DA499A9h,0583B9D9Bh,08D9A6961h,0608A9C87h,0A98A9282h,0717294A6h + dd 0677B735Fh,06F8E7772h,060625709h,03812203Eh,06D462D47h,05A717379h,04D575E5Dh,07F8F7552h + dd 0D6D1CFCFh,0CFCFD0D3h,0809AB0C5h,09C90806Dh,0D4E4D2B3h,09EA2AEBAh,07E657B96h,0A4BD9391h + dd 0D6C2A8A1h,0C9BFCACBh,0C0D3C0BEh,0C9C4C8C8h,0D2D0D8D7h,0C2B3B7D3h,0746E84AFh,0C1CCB08Bh + dd 09D9DA6AEh,0C9CBA9AAh,0B2BCBDC3h,0B199ADA3h,09DBBB1A5h,0A09F8FADh,07D7EABAAh,0AD8E696Dh + dd 093778580h,07C6F6876h,0807A908Dh,06D727785h,06F6C7973h,06D797A83h,0838F7686h,0E7B5A5D2h + dd 0DDF8FAFAh,097B7E0D8h,09F9DC2AEh,0E7F4F3D5h,0998792C3h,0C2C2AA9Dh,0B9B2C0C1h,0BDBDB9BAh + dd 0BBBEC2BDh,09BACB2B9h,0A1A9A69Eh,0B1AFAEA4h,04A612D5Eh,0BE695242h,0EDC6DBD2h,0F7FAFAFAh + dd 0CCC8D8F0h,0B4D2B7B9h,0ABBBBFC5h,0ACA7A8AAh,0A3ABB2B4h,0A8ABA19Eh,0B09CB7A7h,0844D969Bh + dd 08D837E75h,07C7D5F7Ah,07B787366h,079898B99h,085807471h,073869B93h,0757B876Eh,081787E6Eh + dd 08D7E8583h,0A1A2978Ah,088B2ACAAh,05F2E3C76h,0777E6555h,08290A594h,07C987D91h,08B978987h + dd 07D808277h,07492947Fh,03E877624h,06B6B371Fh,078836568h,0757F7A7Dh,058575C76h,08086715Ah + dd 0D2D4C7BDh,0C8D0D8D3h,07C8483B9h,0A286767Dh,0C3D0D3CDh,09E9CA7B3h,08F7BA5A4h,0A1B3AAA2h + dd 0B9B1969Ah,0B7B8B7B9h,0C2B5B0B1h,0C2BDBBBFh,0BDA6C8C2h,0B6B4BFCDh,0817B86A6h,0AFBAC9BEh + dd 0B1A5999Fh,0B9C0B4BAh,0A9ADB7AFh,0C7B0AEAFh,0B09CA2A6h,0A4A0ACADh,09D988599h,077718CA3h + dd 0AC999191h,088979294h,086868E77h,08E947575h,054829294h,062686B6Ah,0AD5F6154h,0FAF4C8D2h + dd 0F7FAFAFAh,0A8D2EAE3h,0DBD8C0A6h,0BCCDCCCFh,0796281A7h,0ABB6AB93h,0B4B4AEA4h,0B4B6B4B4h + dd 0A4AAB0B3h,0A79F9EA2h,0AEAEADA9h,0A2929AA8h,0324A5697h,0DBD86C34h,0F2D6D4B9h,0E8F7FAFAh + dd 0B8A2A9D3h,0A4C5B4B3h,0B2BFCAB6h,0AFA9A4A7h,0A3AEB3B2h,09EA39E99h,0A79E9D9Ch,0997C87A2h + dd 0B4A8A699h,08B86A7ADh,0959C9978h,0A78F9396h,0877380A0h,08C8D8C8Dh,06F747E8Dh,078678586h + dd 07C82798Fh,09796958Ah,0A2ABAEA8h,03446506Ch,0737B7433h,0706F6F6Ch,0857B6970h,06A61777Ch + dd 06C68747Dh,08C90806Ch,03EA09345h,06B8E766Ah,062705C80h,0777C6467h,068625F65h,0736F735Fh + dd 0BEC2BDB7h,0B4BAC2C1h,0878D92A8h,0B2969283h,0B8C5CCCAh,096979DACh,0908B9798h,0A3A59F90h + dd 0A0A19FA9h,09A95979Ch,0A29C9A9Ah,0ADAFA7A4h,0B0A8B8B4h,0AEABAEB6h,0A596A8AFh,09DA5B2AFh + dd 09EA3A9AAh,0C8C7A6A2h,0B9B9C4C9h,0C7C8C6B6h,0A7ADA78Ah,096918D87h,096807998h,04C5E7A93h + dd 076746185h,06B5B5550h,0B1A6A97Dh,080845F6Fh,06B748B92h,061778187h,0C3634D52h,0FAFAE4BBh + dd 0FAFAFAFAh,0C5EACCECh,0BADADAD2h,0CEE1F2DCh,0CDC3C2C1h,0B6C7BDC9h,0B1B1ADAEh,0B4B6B1B1h + dd 0ADAFB0B3h,0AFB3B3B0h,0ADABABADh,0A5A2A6AAh,0456CAEC3h,0C9D69D4Fh,0DBDBE28Bh,0E1F5FAFAh + dd 0B5ADABC7h,0B0C7A6A8h,0ADB8CEBEh,0ACA7A1AAh,0A5ACADB1h,0A2ABA6A2h,0AA9D9C9Eh,0704D92A8h + dd 0ABB68B69h,0736481A6h,08C9F9D69h,0838B8383h,0A6A197A3h,09796999Bh,0A49F9996h,08D99AD98h + dd 0615D5774h,0797D8176h,07F999987h,03D5E7326h,04C524E50h,05B4D4849h,06E565757h,049625063h + dd 05D775B52h,077986670h,002526F2Ah,04A655764h,06E5A3E77h,07A7B4B59h,05E5D6368h,066665656h + dd 0CCBAA59Ah,0A5B2C0CAh,0A298959Bh,0C5CABCB1h,0B8BBC0CEh,0969193A2h,0808FA19Fh,0A2A7A293h + dd 0949795A2h,08D8D9192h,093919393h,09887878Eh,084867F93h,0A59F8D81h,0ADB4BAB0h,0A4AF9088h + dd 0AD9F95AAh,0C6DBBCACh,0B8B5B8C3h,08B8384A0h,0748C7B7Eh,0858187A7h,07F719395h,07E73837Dh + dd 054626D84h,073504E3Dh,0AD9CC9ABh,071835D67h,0717D7367h,05D665E71h,0C6B45B47h,0FAFAF4B4h + dd 0FAFAFAFAh,0E9E1DBF9h,0C7CFDBEFh,0CFD7E7E9h,0D9EEE9CCh,0A4C4CBDFh,0B6B6ADACh,0B4B6B6B6h + dd 0AFAEB0B3h,0B1B2B2B0h,0B3BDB7B4h,0C0ACADB3h,05790D1B6h,0D4B9AE5Ah,0D4E0D794h,0D0F1FAE7h + dd 0B3ADB4D3h,0B6C7B3B3h,0A6B7C5BBh,0ABA5A2A0h,0AFB0B2AEh,0A9AAA8ABh,0A696B1ACh,0AA6B96A9h + dd 0B3B0A8A5h,0A576827Dh,0B290A9A5h,0B0C4C3BBh,097A0A9A9h,0938F9498h,0A8AEB1AFh,097857DA7h + dd 072807485h,08085786Ch,0549B977Fh,05D8A8E24h,05D66637Dh,07B6F5B57h,07D798376h,06150656Eh + dd 07D72506Dh,0889D8F8Dh,02347902Eh,0627C6160h,06B8B6379h,059939C83h,064666662h,08680606Dh + dd 0C0C6CCD3h,090A0B3C0h,0A8A2A388h,0BAC99CBCh,098A5BBD5h,07A79868Fh,066858181h,09195A096h + dd 0868BA19Dh,07F868887h,089848887h,08C8F8A8Ah,07D838599h,0ABA68A7Ch,0A1C2B9ACh,09188A2A6h + dd 0B6BB99AFh,0CCE7C3A0h,0B1A7C0C9h,0999596A7h,09874BB93h,0928CBDB2h,083696CACh,07D768A85h + dd 067697B73h,0825D6556h,0A69ACDB6h,07C866A6Ch,07D908865h,0697A7583h,0C1CE8C80h,0FAFAF8CCh + dd 0FAFAFAFAh,0FAE5F9FAh,0E0D4F8CDh,0BEC7D5E3h,0DBF6DBB6h,0A1CBC8DDh,0BBBBC4B6h,0B3B5BABBh + dd 0ACADB0B3h,0A2AAACACh,0A59D9FA1h,09F999CA4h,08D9CAB96h,0C8BCAE51h,0AEB6927Ah,0CBD1E2CBh + dd 09797A8CDh,0A9A7949Bh,0A1B0B8BDh,09E9F9C92h,0A2A9A89Fh,09DA19F9Dh,0A08F9E9Dh,0994E95A5h + dd 0AEB99D98h,0A77DB85Eh,0B8C5B9B4h,0A4BAB2B1h,0A09EA6ACh,099959A9Fh,0BDC0BBB3h,09DB3C7B6h + dd 07B87869Fh,082858984h,065949792h,07D937554h,0686E6EB1h,07C786A65h,09D928D75h,0655C7086h + dd 0892A525Dh,08F948F87h,02844712Bh,082795068h,062908B81h,07B807782h,02E3B474Ah,0452F4735h + dd 0C6C6B4BBh,0969CA4ADh,0A7A5A795h,0BEB6B4A8h,093A8AEC2h,07B79797Ah,08384A590h,0999BA09Bh + dd 0858E9B97h,08B848282h,08179818Ah,0818A8887h,073707389h,094A3887Fh,067A3B1ABh,0827A686Bh + dd 0BFB8B69Eh,0C3D8CEC9h,08FC0CBB1h,0A38C917Bh,0A9938C8Bh,0868797A8h,083968F94h,05D718274h + dd 06E404D76h,067564D58h,09BA3C48Fh,05C798174h,06A948F90h,0706E6775h,0ABCCA072h,0FAFAFAFAh + dd 0FAFAFAFAh,0FAFAFAFAh,0D4E4FAFAh,0ACA7ADCAh,0DCD9DF9Eh,0ACC2CECDh,0A3A1A4A4h,0A7A688A1h + dd 0B3B1ACAAh,0B1B6B6B6h,0A29A9FABh,0A8A6A6B8h,0B6AFB8B6h,0CFC7A084h,0D4B4C599h,0DCDED2D3h + dd 0ABACB7D3h,0B3BABBAEh,0AFB7B3B7h,0A6ADAFB5h,0B3ABA5A5h,0A9A6AEB7h,0B1B8B0ADh,0986999B4h + dd 0C9D0BD9Ah,0AD7C8A9Fh,0D3BEB5B5h,0AAC49BA7h,0ACA7B2AEh,08D8F99A3h,09995969Dh,092959594h + dd 086858B90h,08B8C8D8Bh,079898D8Ch,06E84956Ah,07A7F8F8Ch,08C80797Ch,09D968B87h,08B828A98h + dd 0791E5376h,068AA99A9h,0244B7A27h,0798D7E5Dh,04350686Eh,04B524941h,023262728h,033261F1Eh + dd 0B9B09997h,0B1B7B7B6h,0AAA29BAEh,0B2B3AFB0h,0929D8DAEh,088777474h,08A80A9ADh,09A969A8Eh + dd 08A8E969Ch,08C8B8987h,0958D9395h,06E7E898Dh,07B786F63h,09192767Dh,082A5A8B6h,08C8B8381h + dd 0AEB18C94h,0AEC1BAC3h,086899497h,0AB827175h,0B4AE8A95h,08A97AFAAh,0869C8993h,09B96937Eh + dd 091788795h,09089747Bh,0B2BBE2B0h,08A8F998Dh,08189B0A1h,0AE9F9AA0h,0E1D5EFA9h,0FAFAFAFAh + dd 0FAFAFAFAh,0FAFAFAFAh,0E3E6FAFAh,0C5ABA9BDh,0F1EEEAD5h,0AFC8DFE2h,0B4B2B0ACh,0AFBBA4B3h + dd 0B7B7B3ABh,0BFBCBAB9h,0ACBFA8B0h,0ADBAB4B9h,0ACA0AEB1h,0D8A6598Ch,0C6B6CFACh,0EBEEE9EBh + dd 0AEADC2E9h,0BCBDB6AEh,0BFC7C6BDh,0B0B1B5B7h,0ADA7A5A6h,0A8A9ACB1h,0AAABA5A6h,0857D95B1h + dd 0A4A59DA7h,08D828B8Ah,0838C888Ch,08482918Dh,087849084h,094908884h,097959598h,08E989C9Ch + dd 098949EAAh,0908B8791h,095939493h,08CA2AF98h,094929C98h,08B8B9299h,099967E83h,08C898A95h + dd 0693F8286h,05EB0A99Ah,0688A9D60h,04A5A4955h,05F615D4Fh,0575B5958h,05F636155h,0634B495Ch + dd 0B0AEA9A2h,0BAB9B8B2h,0ABA9A5B3h,0B8BEB3A9h,0A491979Bh,0A9887797h,07B859FBEh,098989A81h + dd 08D8C8590h,093938F8Ch,082888589h,07A74827Bh,0928D715Fh,0A5AA8C94h,06B94A2B5h,08D7A8290h + dd 09F9E8992h,0B1BCC4B5h,0A097A5A1h,09DAEA39Ch,0B7B4C697h,0B4A3AFC2h,092A1A7BBh,0859B9485h + dd 07D809079h,0965A4C70h,09EBBD4CCh,05D5E6463h,07D5B5A5Dh,05A6E6B81h,0C899DF85h,0FAFAFAF5h + dd 0FAFAFAFAh,0FAFAFAFAh,0D5DBF3FAh,0D0A698A8h,0F3F4E4E4h,0A6C1E0E1h,0B1B2B4A8h,0B8C0ADB7h + dd 0C0BCBCB6h,0C4C7C3C1h,0B0B6CFC5h,0A8BBB0AFh,097A6AAACh,0FA9278A8h,0D1E1D1CEh,0F6F3ECEAh + dd 0ADB5CEF4h,0D5BFBCB9h,0E6E4E2E4h,0B5AFABD8h,0A6A4A6ADh,0ABADA9A5h,0B5B0A7AAh,0655AA1BFh + dd 0899F9B7Fh,08B94825Dh,0A9A39D8Dh,099919790h,0A5A1A894h,0A2A4A4A4h,093979C9Ch,08D959286h + dd 0A4A09085h,0ABABABA8h,0868C9FABh,095908D8Ch,09D969E9Ch,08C8D98A0h,0857F8A8Fh,08A8C8385h + dd 05C8D8C88h,02A3E574Ah,0456D7066h,05E443733h,0534C4251h,06F635F5Ah,08A7F777Ch,0867A7C86h + dd 09CA3A799h,0B5B5B2A7h,0B9B2ACB1h,09DB0C0B9h,0A2A69B8Fh,0908C7E8Ch,0797E8F8Fh,07C788E92h + dd 0989D9E8Bh,09BA39E98h,0A2C4A992h,08590A197h,09C868E8Eh,09AAD9CAAh,09E9484AAh,09694A196h + dd 0CDB2BCA4h,0BEACBCAEh,0A3A8BDC4h,0B8B7BEADh,0C0B3B3AAh,0ABA6B1C2h,0ACA7B2BCh,0739FB7ACh + dd 063827275h,0A983535Ch,0AAB1DAC5h,04E71645Eh,05E6B476Ch,07A5F5675h,0DF83CD9Ch,0FAFAFAF9h + dd 0FAFAFAFAh,0FAFAFAFAh,0CBDEE4FAh,0DAB194A8h,0F7FAEBE5h,0A4C3E2E1h,0B2B5BAABh,0B8B1BABCh + dd 0C1BEBFBFh,0C2C2C4C2h,0BBB4AEBEh,0B4BAAEABh,0959EA7B0h,0F886B1A8h,0DBD2DFEFh,0F0EBE7DEh + dd 0B0C1D4F3h,0E8D2BDB2h,0FAF7F4E4h,0BEBFBFF7h,0A4A7AAACh,0B1B1A6A4h,0BAC0B5B3h,0874C86B0h + dd 07466906Eh,0887E806Eh,0BAABA68Bh,09485AAA8h,0A39DA58Ch,09B9CA1A1h,08A979FA3h,085939284h + dd 0938B919Eh,0A49F9D9Bh,07885A4A8h,092837783h,0918E9692h,07B828D92h,085887682h,0828C7A7Fh + dd 084976A74h,05B443845h,03C5D8973h,04B513524h,0595C5F5Eh,07A696561h,0878E8D85h,0818A8B80h + dd 0989A95A1h,09494928Dh,08C8F9194h,09D9B9187h,0A29C9C91h,0616B6B79h,072717065h,0835A8285h + dd 09B98AA86h,09292929Ah,097A98689h,0A7AAA297h,0928E9095h,0958F9796h,0A5A09E94h,08F90959Ch + dd 09C8A8F89h,0AC948597h,0C3B1B99Dh,0C6CAB0C3h,0C0C1C0BFh,0C7B2B9BBh,09DA9B3BFh,073849C91h + dd 07B887B7Ch,0B47A7C8Eh,0AEC3E4D5h,059656F74h,06E5B4D51h,070877963h,0F09EBFB4h,0FAFAFAFAh + dd 0FAFAFAFAh,0FAFAFAFAh,0D0EAE6F8h,0DECBB4BAh,0F0FAF7DDh,0B7BEE5D2h,0C0B0B19Ch,0C3C4AEBEh + dd 0BCC9C3C3h,0C3C9C5CCh,0A6C4C1BBh,0AFB0B2AFh,0A6B5B7B4h,0AF5CA5A5h,0F6DDCFDBh,0CCD9D5F0h + dd 0A6ADCDB8h,0E4D7D0B6h,0FAFAFAEEh,0ADB7A3E5h,0A9A4AEA8h,08F8D9192h,0A5AE9893h,0B66073B8h + dd 0A19EADAAh,0A79498A0h,0BAA5A59Eh,090A09B8Fh,09D9C9583h,0999C94AFh,07D87A699h,0848D888Dh + dd 08D919080h,08B989188h,071788690h,07F877E6Fh,0938C7E87h,08C93868Bh,093A09692h,0847F9992h + dd 07E87808Bh,06C5D4F74h,046686D70h,061645D3Ah,067707877h,07C757656h,078787874h,06F818271h + dd 09191948Ch,09C9A9899h,09593909Bh,0A0988A98h,0989FA99Dh,077707A7Fh,0717D6F78h,07B778D7Ch + dd 0ADA79E70h,0998B94ABh,09C988B97h,0A6B2959Fh,09EA1AF94h,09192868Eh,09A969294h,08E878E9Ch + dd 0898A9A91h,09187877Dh,0BEAEB4A6h,0AEB6C0BFh,0B2B5BCB8h,0B69DB3BCh,0849ABAA9h,0907E8B8Fh + dd 0867E899Bh,0AA6B638Bh,0AFC2E2C6h,05B606270h,0556C665Dh,073936F69h,0ED888FB4h,0F9FAF9F6h + dd 0FAFAFAFAh,0FAFAFAFAh,0C3DEE2F7h,0DACABCB5h,0F1FAF9E0h,0A0C9DAD3h,0B6B4ACAFh,0A8A9B6B5h + dd 09DAAA0A4h,0959E9EA8h,09DAA9E96h,0ABA4A49Fh,093ACB4B2h,0939CA2A1h,0EEEAE4DCh,0D6E9E4EEh + dd 0C8D0E7D4h,0EFE4DBC9h,0DCE6F4F7h,0B4BAB3C8h,0B9ADB4B0h,0A8A2AEAEh,098AEB7AFh,09C86627Dh + dd 0AEA5A090h,0ACA8B3B5h,09CBCABA4h,078929C93h,0A0AB868Eh,094A79BA3h,08594AA99h,08F958E8Ah + dd 08C949588h,099A19E93h,07E8C9496h,08988806Fh,08B888E8Fh,08F979596h,09296A89Ah,08F8E9895h + dd 0948E8C8Ah,06E737690h,0707E8E86h,070768960h,09794897Dh,0676B757Dh,07A7B7B73h,07C78736Bh + dd 09E968BA6h,0908B8889h,088868492h,09A98948Ah,089A58997h,0726C8166h,08D82626Ch,08C817581h + dd 0A2B59B8Fh,09B7DA6AFh,09EA39DA6h,0A1B79AA3h,099A7B396h,0969F948Dh,09E9A9796h,09C9298A6h + dd 0928E9689h,083838680h,0BDA2A09Dh,0A8A3B5C3h,0C5BBB2BBh,0C8CEC4C3h,09EA3A3A0h,0958281A2h + dd 080758595h,09E6E6588h,0AFB2DEBCh,0714F5773h,06B79796Dh,090978D8Bh,0D5A494B0h,0F6F8F6F2h + dd 0FAFAFAFAh,0FAFAFAFAh,0B6CCD9F6h,0E9D7C5B4h,0F9FAFAF3h,08AC8E4E1h,0B1BCA3A3h,0B3B7A8AAh + dd 0899BABAEh,0AC928993h,0AAB2A2A8h,0B0B5ABAAh,0A0A9BABAh,062B1AEAEh,0EBF3EFDDh,0D6EBF3F7h + dd 0D1DFF5EBh,0FAF4ECD4h,0CADCF7FAh,0A8ACB1C8h,0AC9BA2A3h,0A49DADABh,08699B1ABh,09995826Ch + dd 0A6B7B095h,09098A6A5h,08E9A8B92h,0768E7654h,08E997D94h,09AA19B8Ah,0838F9E9Bh,08B887F6Dh + dd 07E7A7467h,08C737281h,0787E909Fh,08382837Eh,08A808977h,095A89191h,09D9FA79Ch,0957C8B93h + dd 0A69B8791h,073596C8Bh,0637E7087h,05D617A5Ch,091847068h,06E7B7889h,0666B6E6Dh,07D8C8D7Dh + dd 092929DB0h,0918B878Ch,08F909495h,0948B868Fh,08192A398h,06C718877h,0A0848C7Dh,0B2AC8892h + dd 0B5A797ABh,0A0A9A5B0h,0A19C95A4h,099B6AEA4h,0A799A097h,0A29090A3h,09CA39D86h,094919391h + dd 09E8E9991h,095948F92h,0B3A1A996h,0A99CA7B6h,0B9B7B4A8h,0A797B5BCh,0A5ABAEABh,09C9A9E9Dh + dd 0B9BFB799h,0A89AADC7h,0BFACF0CEh,0958C90A1h,080838680h,0BB849F80h,0F8CEA0CDh,0FAFAFAFAh + dd 0FAFAFAFAh,0FAFAFAFAh,0B4C3D5ECh,0F9DFBAC7h,0F8FAFAFAh,0A8ACDFE0h,0A8A4A6A7h,0A3A3A7A8h + dd 096A7A3A3h,0ABA4A1A6h,0A6B39CA8h,0ADB3A6A3h,0A0A1B7B8h,06AA6B797h,0FAFAF6E4h,0EAEFF6F6h + dd 0EEEDF6EAh,0FAFAFAECh,0C0D8F5FAh,0AAAEB8D1h,0A79AA4A6h,0A1A0AEA6h,08AADA3A2h,08C738B78h + dd 086A68C7Ch,08391937Eh,09A717491h,090A98C96h,09F9CA19Fh,0A191A898h,09E989195h,08E949B8Fh + dd 0968B8E8Bh,0A297939Fh,0A59D9899h,0A9A2A8ACh,08084A898h,07486848Eh,07E779482h,091796A76h + dd 0A6908A89h,082959E91h,0868A9081h,0818D8C87h,0908E8C8Dh,0869B8D96h,0767F898Ch,076787A78h + dd 09496ABA6h,0888F8C79h,09BA28995h,092968C8Ch,066788099h,070798879h,0909A8C82h,0908A8C8Dh + dd 0A2978896h,094A2AAAAh,0959C93A8h,08890969Bh,0817E8C93h,0A386A08Bh,07E909492h,0868A85B1h + dd 0BFA07C8Eh,09EA4A6ABh,09A9F9FA0h,09CC2AE93h,0B0ACBEA0h,09798AA9Fh,0B4A99797h,0AFB2C1BEh + dd 056C4B997h,067575A48h,09190ADB2h,054785189h,04D837F75h,0C163874Ah,0FAE995C2h,0FAFAFAFAh + dd 0FAFAFAFAh,0FAFAFAFAh,0BFCAD0F6h,0F9E9D3B4h,0EBFAFAFAh,0A8C0D8E1h,0B0A2A3B7h,0B8B4B7B0h + dd 0C3B0B2B3h,0B3B9A7B1h,0AAAFB4B3h,0ABB1AFABh,09AA7BEBCh,066AFB4C1h,0F5EEEBB3h,0E2E8E8E2h + dd 0E9EEECE6h,0FAFAFAF1h,0BCCFE4F7h,0ABA6ABCBh,09997AC99h,0A5A6ADB1h,0859CA5A4h,0615F8392h + dd 06DBB7883h,08E59848Ah,06367518Dh,0707D7A64h,091939691h,074898C8Ah,07A757376h,07A999678h + dd 09CB3BE88h,0ABAEA8A6h,0A9A6A799h,0A4AD9EB0h,061696EA3h,083819C91h,0A89E8F96h,096A9B0A6h + dd 07E877E8Fh,079787292h,08E908160h,08D919095h,098908588h,092A4A69Ah,04F768784h,05A545D53h + dd 08B827072h,07DA08C63h,08383928Dh,08F908291h,08684718Ah,07776636Fh,093927F88h,0918D9F9Ch + dd 0989A9F97h,08D959595h,0B4AE9EA0h,0A1A3C0AFh,0718FADADh,09F9FB68Eh,038484994h,0409F7D36h + dd 0692A432Fh,0A79E9AB0h,09E949292h,0B0B8A9B1h,09B979FA2h,0787C888Ch,0B29A8A80h,0B8A8B1ACh + dd 043AAB2ABh,0234B8B22h,08875864Ch,0A0B4A275h,080ADA698h,0BB605D4Ch,0FAF9D1CDh,0FAFAFAFAh + dd 0FAFAFAFAh,0FAFAFAFAh,0D5CED0FAh,0F2EBE9E0h,0E7F9FAFAh,0A4C2E1E0h,0BDA9AAC1h,0BBB9B6BCh + dd 0C2B4ADB9h,0BFC4B5B9h,0AFB1B4BBh,0BCBEB5B0h,0A2A9C2C7h,04CB3BFB4h,0E6E4D9A3h,0D8DBDAD8h + dd 0D5DADBDAh,0E8E2DCD6h,0C2BFCCDFh,097A4A7C2h,08C989193h,0A4A5AD95h,06C8EA1A2h,0746A919Bh + dd 099D9978Ch,09872999Eh,07D736E86h,0A5988571h,09A968187h,0758A9295h,094897D77h,07B81878Eh + dd 0A0A4A46Eh,0B2B1ADB1h,0A9A7A8A5h,0B0A3AFADh,09AAF87A5h,0848B9A94h,08A877787h,08F7F8590h + dd 07F7E7E9Dh,08E888490h,0928A897Ah,0959B989Ah,098939796h,093A4A69Dh,061788087h,06758616Ch + dd 07E7A7DA2h,0848A867Bh,08A8E997Fh,0666E8E7Ah,08384917Dh,0877E7D86h,0A4AA8893h,09491A5A7h + dd 0A3A7948Ah,09A9E9D9Bh,0A2B1A39Dh,0B28895ACh,0788C9AA1h,0AFAF9D8Bh,0574360A3h,083AAA13Fh + dd 0733D697Eh,0ADA5A5B7h,08E8F9D92h,084819798h,08F8C8E8Ah,07373778Eh,0AF9E877Bh,0A7A8ACACh + dd 0B0B2ACA0h,0230E2F25h,035496335h,0A09FA675h,0B1AEA48Bh,0D1647598h,0FAF7E6DDh,0FAFAFAFAh + dd 0FAFAFAFAh,0F9FAFAFAh,0D2D1D9F9h,0EEE8DDDBh,0DDEDEFECh,0AFC5DAD7h,0BBC7C1D3h,0BEC5C9B6h + dd 0ABA9B5C1h,0A3ADA9A8h,0ABABA9A6h,0AC9AB4BBh,0AAB0BBB7h,0829AB1B8h,0DDDFD6B4h,0E2E2E6E8h + dd 0D0CFD3D7h,0DED7CDCCh,0A6B5CFDFh,0AFB09990h,094858F94h,0A4A2AAABh,08D9AA2A4h,0989E958Ah + dd 0A8A79E89h,09A7D7385h,07C736590h,0A68E9383h,099948B8Ch,0758A9497h,0827F7B7Ch,07589938Fh + dd 0AAB0B179h,0B0AAA8B3h,0A3A4A7A6h,0AE93ACA5h,0838D97A1h,0928E838Dh,06C7C919Fh,0827B8E83h + dd 08B828492h,077738189h,09C978971h,09B8F929Fh,09D9AA4A1h,091A1A69Eh,07B84848Eh,0636F6F6Eh + dd 085816E6Bh,07C87919Bh,08593967Ch,08A613759h,085707079h,081776C84h,0A9AE9295h,0A498A4A7h + dd 0A29C8E8Eh,0ABA1A4A5h,07FBDADA1h,097968589h,078798584h,0B4A97F84h,05A64859Ah,08E6B534Dh + dd 0B5644B5Dh,09DAAB2CDh,08887858Eh,08C8F868Ch,084858985h,09886819Ch,097A09E9Eh,09DA5A8A8h + dd 0D0AAB4A1h,068587A91h,08B807A79h,06FA58DA9h,0B1969279h,0B87F9BB0h,0E2C9CBBAh,0E3EBECE6h + dd 0E7E1DEDEh,0E3E8E5E3h,0E9F7FAE2h,0E5E2DBDEh,0E1F2F2E9h,0BAD3D4D5h,09CB4B1BBh,09EBAAB95h + dd 0AEB0ABA8h,0A6A8AAAAh,0AFAFACA9h,0AD95A9B3h,0B0B7BBB6h,0ADABAFAEh,0DACEB4A5h,0D4D3D7DEh + dd 0D3C9C9D1h,0CEC0B4C4h,099B3CED4h,0BEA2919Ch,09C9294A1h,0ACACACACh,0A7A3AEAFh,0897F9E9Bh + dd 09892B078h,09E8C887Bh,08A7E768Dh,07E879189h,0989B928Ch,0788A908Eh,077757379h,07377808Bh + dd 0A8B7B06Ch,0B3AAAAAFh,0AFB1B6AFh,0B09AA5B0h,0A1ACB3ACh,08C838DAAh,085878496h,088897B79h + dd 098888792h,087728888h,0969B8275h,09C96939Ch,0A2A19E9Dh,08B9EA59Eh,07A858181h,0586B6A6Fh +end; diff --git a/16/ADT2PLAY/TXTSCRIO.PAS b/16/ADT2PLAY/TXTSCRIO.PAS new file mode 100644 index 00000000..d187824d --- /dev/null +++ b/16/ADT2PLAY/TXTSCRIO.PAS @@ -0,0 +1,1683 @@ +unit TxtScrIO; +interface + +const + Black = $00; DGray = $08; + Blue = $01; LBlue = $09; + Green = $02; LGreen = $0a; + Cyan = $03; LCyan = $0b; + Red = $04; LRed = $0c; + Magenta = $05; LMagenta = $0d; + Brown = $06; Yellow = $0e; + LGray = $07; White = $0f; + Blink = $80; + +procedure ShowStr(var dest; x,y: Byte; str: String; attr: Byte); +procedure ShowVStr(var dest; x,y: Byte; str: String; attr: Byte); +procedure ShowCStr(var dest; x,y: Byte; str: String; atr1,atr2: Byte); +procedure ShowVCStr(var dest; x,y: Byte; str: String; atr1,atr2: Byte); +procedure ShowC3Str(var dest; x,y: Byte; str: String; atr1,atr2,atr3: Byte); +procedure ShowVC3Str(var dest; x,y: Byte; str: String; atr1,atr2,atr3: Byte); +function CStrLen(str: String): Byte; +function AbsPos(x,y: Byte): Word; +function Color(fgnd,bgnd: Byte): Byte; +procedure CleanScreen(var dest); +procedure initialize; + +type + tCUSTOM_VIDEO_MODE = 0..52; + +procedure SetCustomVideoMode(vmode: tCUSTOM_VIDEO_MODE); + +type + tFRAME_SETTING = Record + shadow_enabled, + wide_range_type, + zooming_enabled, + update_area: Boolean; + end; +const + fr_setting: tFRAME_SETTING = + (shadow_enabled: TRUE; + wide_range_type: FALSE; + zooming_enabled: FALSE; + update_area: TRUE); + +procedure Frame(var dest; x1,y1,x2,y2,atr1: Byte; + title: String; atr2: Byte; border: String); + +const + solid1 = ' '; + solid2 = 'ÛßÛÛÛÛÜÛ'; + single = 'ÚÄ¿³³ÀÄÙ'; + double = 'ÉÍ»ººÈͼ'; + dbside = 'ÖÄ·ººÓĽ'; + dbtop = 'Õ͸³³Ô;'; + +var + MaxLn,MaxCol, + work_maxln,work_maxcol: Byte; + area_x1,area_y1,area_x2,area_y2: Byte; + v_mode: Byte; + DispPg: Byte; + v_seg,v_ofs: Longint; + CheckSnow: Boolean; + +function iEGA: Boolean; +function iVGA: Boolean; +function iPS2: Boolean; +function iMDA: Boolean; +function iCGA: Boolean; +function iMCGA: Boolean; + +function WhereX: Byte; +function WhereY: Byte; +procedure GotoXY(x,y: Byte); +procedure ResetMode; + +function GetCursor: Longint; +procedure SetCursor(cursor: Longint); +procedure ThinCursor; +procedure WideCursor; +procedure HideCursor; +function GetCursorShape: Word; +procedure SetCursorShape(shape: Word); + +type + tVIDEO_STATE = Record + font: Byte; + cursor: Longint; + MaxLn,MaxCol,v_mode: Byte; + v_ofs: Longint; + screen: array[0..PRED(8192)] of Byte; + data: array[0..PRED(4096)] of Byte; + end; + +procedure GetVideoState(var data: tVIDEO_STATE); +procedure SetVideoState(var data: tVIDEO_STATE; restore_screen: Boolean); +procedure GetRGBitem(color: Byte; var red,green,blue: Byte); +procedure SetRGBitem(color: Byte; red,green,blue: Byte); +procedure WaitRetrace; +procedure GetPalette(var pal; first,last: Word); +procedure SetPalette(var pal; first,last: Word); + +type + tFADE = (first,fadeOut,fadeIn); + tDELAY = (fast,delayed); + +type + tFADE_BUF = Record + action: tFADE; + pal0: array[0..255] of Record r,g,b: Byte end; + pal1: array[0..255] of Record r,g,b: Byte end; + end; + +const + fade_speed: Byte = 63; + +procedure VgaFade(var data: tFADE_BUF; fade: tFADE; delay: tDELAY); +procedure RefreshEnable; +procedure RefreshDisable; +procedure Split2Static; +procedure SplitScr(line: Integer); +procedure SetSize(columns,lines: Integer); +procedure SetTextDisp(x,y: Integer); + +implementation +uses DPMI; + +var + absolute_pos: Word; + +procedure DupChar; assembler; +asm + pushad { IN/ al -column } + xor ebx,ebx { ah -line } + xchg ax,bx { dl -character } + xor eax,eax { dh -attribute } + xchg ax,bx { ecx -count } + mov bl,al { edi -ptr. to write } + mov al,MaxCol + mul ah + add ax,bx + mov bl,MaxCol + sub ax,bx + dec ax + shl ax,1 + jecxz @@1 + add edi,eax + xchg ax,dx + rep stosw + xchg ax,dx +@@1: mov absolute_pos,ax + popad +end; + +procedure ShowStr(var dest; x,y: Byte; str: String; attr: Byte); assembler; +asm + mov edi,[dest] + mov esi,[str] + mov al,x + mov ah,y + xor ecx,ecx + call DupChar + xor edx,edx + mov dx,absolute_pos + lodsb + mov cl,al + jecxz @@2 + add edi,edx + mov ah,attr +@@1: lodsb + stosw + loop @@1 +@@2: +end; + +procedure ShowVStr(var dest; x,y: Byte; str: String; attr: Byte); assembler; +asm + mov al,MaxCol + dec al + xor ah,ah + xor ebx,ebx + mov bl,2 + mul bl + mov bx,ax + mov edi,[dest] + mov esi,[str] + mov al,x + mov ah,y + xor ecx,ecx + call DupChar + xor edx,edx + mov dx,absolute_pos + lodsb + mov cl,al + jecxz @@2 + add edi,edx + mov ah,attr +@@1: lodsb + stosw + add edi,ebx + loop @@1 +@@2: +end; + +procedure ShowCStr(var dest; x,y: Byte; str: String; atr1,atr2: Byte); assembler; +asm + mov esi,[str] + mov edi,[dest] + lodsb + xor ecx,ecx + mov cl,al + jecxz @@3 + push ecx + mov al,x + mov ah,y + xor ecx,ecx + call DupChar + xor edx,edx + mov dx,absolute_pos + pop ecx + add edi,edx + mov ah,atr1 + mov bh,atr2 +@@1: lodsb + cmp al,'~' + jz @@2 + stosw + loop @@1 + jmp @@3 +@@2: xchg ah,bh + loop @@1 +@@3: +end; + +procedure ShowVCStr(var dest; x,y: Byte; str: String; atr1,atr2: Byte); assembler; +asm + mov al,MaxCol + dec al + xor ah,ah + mov bl,2 + mul bl + mov bx,ax + mov esi,[str] + mov edi,[dest] + lodsb + xor ecx,ecx + mov cl,al + jecxz @@3 + push ecx + mov al,x + mov ah,y + xor ecx,ecx + call DupChar + xor edx,edx + mov dx,absolute_pos + pop ecx + add edi,edx + mov dx,bx + mov ah,atr1 + mov bh,atr2 +@@1: lodsb + cmp al,'~' + jz @@2 + stosw + add edi,edx + loop @@1 + jmp @@3 +@@2: xchg ah,bh + loop @@1 +@@3: +end; + +procedure ShowC3Str(var dest; x,y: Byte; str: String; atr1,atr2,atr3: Byte); assembler; +asm + mov esi,[str] + mov edi,[dest] + lodsb + xor ecx,ecx + mov cl,al + jecxz @@3 + push ecx + mov al,x + mov ah,y + xor ecx,ecx + call DupChar + xor edx,edx + mov dx,absolute_pos + pop ecx + add edi,edx + mov ah,atr1 + mov bl,atr2 + mov bh,atr3 +@@1: lodsb + cmp al,'~' + jz @@2 + cmp al,'`' + jz @@3 + stosw + loop @@1 + jmp @@4 +@@2: xchg ah,bl + loop @@1 + jmp @@4 +@@3: xchg ah,bh + loop @@1 +@@4: +end; + +procedure ShowVC3Str(var dest; x,y: Byte; str: String; atr1,atr2,atr3: Byte); assembler; +asm + mov al,MaxCol + dec al + xor ah,ah + mov bl,2 + mul bl + mov bx,ax + mov esi,[str] + mov edi,[dest] + lodsb + xor ecx,ecx + mov cl,al + jecxz @@4 + push ecx + mov al,x + mov ah,y + xor ecx,ecx + call DupChar + xor edx,edx + mov dx,absolute_pos + pop ecx + add edi,edx + mov dx,bx + mov ah,atr1 + mov bl,atr2 + mov bh,atr3 +@@1: lodsb + cmp al,'~' + jz @@2 + cmp al,'`' + jz @@3 + stosw + add edi,edx + loop @@1 + jmp @@4 +@@2: xchg ah,bl + loop @@1 + jmp @@4 +@@3: xchg ah,bh + loop @@1 +@@4: +end; + +function CStrLen(str: String): Byte; assembler; +asm + mov edi,[str] + xor ecx,ecx + mov cl,[edi] + inc edi + mov bx,cx + jecxz @@2 + mov al,'~' +@@1: repne scasb + jnz @@2 + dec bx + jmp @@1 +@@2: mov ax,bx +end; + +function AbsPos(x,y: Byte): Word; assembler; +asm + mov al,x + mov ah,y + xor ecx,ecx + call DupChar + mov ax,absolute_pos +end; + +function Color(fgnd,bgnd: Byte): Byte; assembler; +asm + mov al,bgnd + xor ah,ah + mov bh,16 + mul bh + add al,fgnd +end; + +procedure CleanScreen(var dest); assembler; +asm + mov edi,[dest] + mov al,1 + mov bh,1 + mov cl,MaxCol + xor ch,ch +@@1: mov ah,bh + mov dl,' ' + mov dh,07h + call DupChar + inc bh + cmp bh,MaxLn + jle @@1 +end; + +procedure Frame(var dest; x1,y1,x2,y2,atr1: Byte; + title: String; atr2: Byte; border: String); assembler; +var + xexp1,xexp2,xexp3,yexp1,yexp2: Byte; + offs: Longint; + +asm + cmp fr_setting.update_area,1 + jnz @@0 + mov al,x1 + mov area_x1,al + mov al,y1 + mov area_y1,al + mov al,x2 + mov area_x2,al + mov al,y2 + mov area_y2,al +@@0: mov bl,fr_setting.wide_range_type + mov bh,fr_setting.shadow_enabled + mov esi,[border] + mov edi,[dest] + mov offs,edi + cmp bl,0 + je @@1 + mov xexp1,4 + mov xexp2,-1 + mov xexp3,7 + mov yexp1,1 + mov yexp2,2 + jmp @@2 +@@1: mov xexp1,1 + mov xexp2,2 + mov xexp3,1 + mov yexp1,0 + mov yexp2,1 + jmp @@4 +@@2: mov al,x1 + sub al,3 + mov ah,y1 + dec ah + mov dl,' ' + mov dh,atr1 + xor ecx,ecx + mov cl,x2 + sub cl,x1 + add cl,7 + call DupChar + mov ah,y2 + inc ah + call DupChar + mov bl,y1 +@@3: mov al,x1 + sub al,3 + mov ah,bl + mov dl,' ' + mov ecx,3 + call DupChar + mov al,x2 + inc al + mov dl,' ' + mov ecx,3 + call DupChar + inc bl + cmp bl,y2 + jng @@3 +@@4: mov al,x1 + mov ah,y1 + mov dl,[esi+1] + mov dh,atr1 + mov ecx,1 + push edi + call DupChar + inc al + mov dl,[esi+2] + mov dh,atr1 + mov cl,x2 + sub cl,x1 + dec cl + call DupChar + mov al,x2 + mov dl,[esi+3] + mov dh,atr1 + mov ecx,1 + call DupChar + mov bl,y1 +@@5: inc bl + mov al,x1 + mov ah,bl + mov dl,[esi+4] + mov dh,atr1 + mov ecx,1 + call DupChar + inc al + mov dl,' ' + mov dh,atr1 + mov cl,x2 + sub cl,x1 + dec cl + call DupChar + mov al,x2 + mov dl,[esi+5] + mov dh,atr1 + mov ecx,1 + call DupChar + cmp bl,y2 + jnge @@5 + mov al,x1 + mov ah,y2 + mov dl,[esi+6] + mov dh,atr1 + mov ecx,1 + call DupChar + inc al + mov dl,[esi+7] + mov cl,x2 + sub cl,x1 + dec cl + call DupChar + mov al,x2 + mov dl,[esi+8] + mov dh,atr1 + mov ecx,1 + call DupChar + mov esi,[title] + mov cl,[esi] + jecxz @@7 + xor eax,eax + mov al,x2 + sub al,x1 + sub al,cl + mov bl,2 + div bl + add al,x1 + add al,ah + mov ah,y1 + xor ecx,ecx + call DupChar + push eax + xor eax,eax + mov ax,absolute_pos + mov edi,offs + add edi,eax + pop eax + lodsb + mov cl,al + mov ah,atr2 +@@6: lodsb + stosw + loop @@6 +@@7: cmp bh,0 + je @@11 + mov bl,y1 + sub bl,yexp1 +@@8: inc bl + mov al,x2 + add al,xexp1 + mov ah,bl + xor ecx,ecx + call DupChar + push eax + xor eax,eax + mov ax,absolute_pos + mov edi,offs + add edi,eax + pop eax + inc edi + mov al,07 + stosb + cmp MaxLn,80 + jae @@9 + inc edi + stosb + cmp MaxCol,132 + jna @@9 + inc edi + stosb +@@9: cmp bl,y2 + jng @@8 + mov al,x1 + add al,xexp2 + mov ah,y2 + add ah,yexp2 + xor ecx,ecx + call DupChar + push eax + xor eax,eax + mov ax,absolute_pos + mov edi,offs + add edi,eax + pop eax + inc edi + mov al,07 + mov cl,x2 + sub cl,x1 + add cl,xexp3 + cmp MaxLn,45 + jb @@10 + dec cl +@@10: stosb + inc edi + loop @@10 +@@11: +end; + +function iEGA: Boolean; assembler; +asm + mov ax,01200h + mov bx,00010h + mov cx,0ffffh + int 10h + cmp cx,0ffffh + jz @@1 + mov al,1 + jmp @@2 +@@1: xor al,al +@@2: +end; + +function iVGA: Boolean; assembler; +asm + mov ax,1a00h + int 10h + cmp al,1ah + jnz @@1 + cmp bl,7 + jb @@1 + cmp bl,0ffh + jnz @@2 +@@1: xor al,al + jmp @@3 +@@2: mov al,1 +@@3: +end; + +function iPS2: Boolean; assembler; +asm + mov ax,1a00h + int 10h + and al,0ffh + cmp al,1ah + jnz @@1 + and bl,0ffh + cmp bl,07h + jb @@1 + cmp bl,0ch + ja @@1 + cmp bl,09h + jz @@1 + cmp bl,0ah + jz @@1 + mov al,1 + jmp @@2 +@@1: xor al,al +@@2: +end; + +function iMDA: Boolean; assembler; +asm + cmp v_mode,07h + jnz @@1 + mov al,1 + jmp @@2 +@@1: xor al,al +@@2: +end; + +function iCGA: Boolean; assembler; +asm + call iMDA + cmp al,0 + jnz @@1 + call iEGA + cmp al,0 + jnz @@1 + call iPS2 + cmp al,0 + jnz @@1 + mov al,1 + jmp @@2 +@@1: xor al,al +@@2: +end; + +function iMCGA: Boolean; assembler; +asm + call iMDA + cmp al,0 + jnz @@1 + call iEGA + cmp al,0 + jnz @@1 + call iPS2 + cmp al,1 + jnz @@1 + mov al,1 + jmp @@2 +@@1: xor al,al +@@2: +end; + +function WhereX: Byte; assembler; +asm + mov bh,DispPg + mov ah,03h + int 10h + inc dl + mov al,dl +end; + +function WhereY: Byte; assembler; +asm + mov bh,DispPg + mov ah,03h + int 10h + inc dh + mov al,dh +end; + +procedure GotoXY(x,y: Byte); assembler; +asm + mov dh,y + mov dl,x + dec dh + dec dl + mov bh,DispPg + mov ah,02h + int 10h +end; + +procedure ResetMode; assembler; +asm + xor ah,ah + mov al,v_mode + mov bh,DispPg + int 10h +end; + +function GetCursor: Longint; assembler; +asm + xor edx,edx + mov bh,DispPg + mov ah,03h + int 10h + shl edx,16 + xor eax,eax + push edx + call GetCursorShape + pop edx + add edx,eax + mov eax,edx +end; + + +procedure SetCursor(cursor: Longint); assembler; +asm + xor eax,eax + mov ax,word ptr [cursor] + push eax + call SetCursorShape + mov dx,word ptr [cursor+2] + mov bh,DispPg + mov ah,02h + int 10h +end; + +procedure ThinCursor; assembler; +asm + xor ecx,ecx + call iMDA + cmp al,1 + jnz @@1 + mov cx,0b0ch + jmp @@5 +@@1: call iCGA + cmp al,1 + jnz @@2 + mov cx,0708h + jmp @@5 +@@2: call iMCGA + cmp al,1 + jnz @@3 + mov cx,0708h + jmp @@5 +@@3: call iVGA + cmp al,1 + jnz @@4 + mov cx,0d0eh + jmp @@5 +@@4: mov cx,0b0ch +@@5: push ecx + call SetCursorShape +end; + +procedure WideCursor; assembler; +asm + xor ecx,ecx + call iMDA + cmp al,1 + jnz @@1 + mov cx,010ch + jmp @@5 +@@1: call iCGA + cmp al,1 + jnz @@2 + mov cx,0107h + jmp @@5 +@@2: call iMCGA + cmp al,1 + jnz @@3 + mov cx,0107h + jmp @@5 +@@3: call iVGA + cmp al,1 + jnz @@4 + mov cx,010eh + jmp @@5 +@@4: mov cx,010ch +@@5: push ecx + call SetCursorShape +end; + +procedure HideCursor; assembler; +asm + xor ecx,ecx + mov cx,1010h + push ecx + call SetCursorShape +end; + +function GetCursorShape: Word; assembler; +asm + mov dx,03d4h + mov al,0ah + out dx,al + inc dx + in al,dx + and al,1fh + mov ah,al + dec dx + mov al,0bh + out dx,al + inc dx + in al,dx + and al,1fh +end; + +procedure SetCursorShape(shape: Word); assembler; +asm + mov dx,03d4h + mov al,0ah + out dx,al + inc dx + in al,dx + mov ah,BYTE(shape)[1] + and al,0e0h + or al,ah + out dx,al + dec dx + mov al,0bh + out dx,al + inc dx + in al,dx + mov ah,BYTE(shape)[0] + and al,0e0h + or al,ah + out dx,al +end; + +procedure initialize; +begin + asm + mov ah,0fh + int 10h + and al,7fh + mov v_mode,al + mov DispPg,bh + end; + + If (MEM[0:$449] = 7) then + begin + v_seg := $0b000; + MaxLn := 25; + end + else begin + v_seg := $0b800; + MaxLn := SUCC(MEM[0:$484]); + end; + + v_ofs := MEM[0:$44e]; + MaxCol := MEM[0:$44a]; + + work_MaxLn := MaxLn; + work_MaxCol := MaxCol; + + If iCGA then CheckSnow := TRUE + else CheckSnow := FALSE; +end; + +var + dos_seg: Word; + bios_data_backup: array[0..167] of Byte; + regs: tRmRegs; + +procedure GetVideoState(var data: tVIDEO_STATE); +begin + Move(Ptr(v_seg,v_ofs)^,data.screen,SizeOf(data.screen)); + data.cursor := GetCursor; + data.font := MEMW[0:$0485]; + data.v_mode := v_mode; + data.MaxLn := MaxLn; + data.MaxCol := MaxCol; + data.v_ofs := v_ofs; + Move(MEM[$40:0],bios_data_backup,168); + dos_seg := DosMemoryAlloc(SizeOf(tVIDEO_STATE(data).data)); + ClearRmRegs(regs); + regs.cx := 7; + regs.es := dos_seg; + regs.ax := $1c01; + RealModeInt($10,regs); + Move(bios_data_backup,MEM[$40:0],168); + Move(POINTER(DWORD(dos_seg)*16)^,tVIDEO_STATE(data).data, + SizeOf(tVIDEO_STATE(data).data)); + DosMemoryFree(dos_seg); +end; + +procedure SetVideoState(var data: tVIDEO_STATE; restore_screen: Boolean); +begin + v_mode := data.v_mode; + ResetMode; + Move(MEM[$40:0],bios_data_backup,168); + dos_seg := DosMemoryAlloc(SizeOf(tVIDEO_STATE(data).data)); + Move(tVIDEO_STATE(data).data,POINTER(DWORD(dos_seg)*16)^, + SizeOf(tVIDEO_STATE(data).data)); + ClearRmRegs(regs); + regs.cx := 7; + regs.es := dos_seg; + regs.ax := $1c02; + RealModeInt($10,regs); + DosMemoryFree(dos_seg); + Move(bios_data_backup,MEM[$40:0],168); + + MEM[0:$44e] := data.v_ofs; + MEM[0:$484] := PRED(data.MaxLn); + MEM[0:$44a] := data.MaxCol; + + Case data.font of + 8: asm mov ax,1112h; xor bl,bl; int 10h end; + 14: asm mov ax,1111h; xor bl,bl; int 10h end; + else asm mov ax,1114h; xor bl,bl; int 10h end; + end; + + initialize; + SetCursor(data.cursor); + If restore_screen then + Move(data.screen,Ptr(v_seg,v_ofs)^,SizeOf(data.screen)); +end; + +procedure GetRGBitem(color: Byte; var red,green,blue: Byte); +begin + PORT[$3c7] := color; + red := PORT[$3c9]; + green := PORT[$3c9]; + blue := PORT[$3c9]; +end; + +procedure SetRGBitem(color: Byte; red,green,blue: Byte); +begin + PORT[$3c8] := color; + PORT[$3c9] := red; + PORT[$3c9] := green; + PORT[$3c9] := blue; +end; + +procedure WaitRetrace; assembler; +asm + mov dx,3dah +@@1: in al,dx + and al,08h + jnz @@1 +@@2: in al,dx + and al,08h + jz @@2 +end; + +procedure GetPalette(var pal; first,last: Word); assembler; +asm + xor eax,eax + xor ecx,ecx + mov ax,first + mov cx,last + sub ecx,eax + inc ecx + mov dx,03c7h + out dx,al + add dx,2 + mov edi,[pal] + add edi,eax + add edi,eax + add edi,eax + mov eax,ecx + add ecx,eax + add ecx,eax + rep insb +end; + +procedure SetPalette(var pal; first,last: Word); assembler; +asm + mov dx,03dah +@@1: in al,dx + test al,8 + jz @@1 + xor eax,eax + xor ecx,ecx + mov ax,first + mov cx,last + sub ecx,eax + inc ecx + mov dx,03c8h + out dx,al + inc dx + mov esi,[pal] + add esi,eax + add esi,eax + add esi,eax + mov eax,ecx + add ecx,eax + add ecx,eax + rep outsb +end; + +const + fade_first: Byte = 0; + fade_last: Byte = 255; + +procedure wait_ms; assembler; +asm +@@1: mov di,-1*1193*2 + xor al,al + out 43h,al + in al,40h + mov bl,al + in al,40h + mov bh,al +@@2: xor al,al + out 43h,al + in al,40h + mov ah,al + in al,40h + xchg ah,al + sub ax,bx + cmp ax,di + jnc @@2 +end; + +procedure VgaFade(var data: tFADE_BUF; fade: tFADE; delay: tDELAY); + +var + i,j: Byte; + +begin + If (fade = fadeOut) and (data.action in [first,fadeIn]) then + begin + GetPalette(data.pal0,fade_first,fade_last); + If delay = delayed then + For i := fade_speed downto 0 do + begin + For j := fade_first to fade_last do + begin + data.pal1[j].r := data.pal0[j].r * i DIV fade_speed; + data.pal1[j].g := data.pal0[j].g * i DIV fade_speed; + data.pal1[j].b := data.pal0[j].b * i DIV fade_speed; + end; + SetPalette(data.pal1,fade_first,fade_last); + wait_ms; + end + else + begin + FillChar(data.pal1,SizeOf(data.pal1),0); + SetPalette(data.pal1,fade_first,fade_last); + end; + data.action := fadeOut; + end; + + If (fade = fadeIn) and (data.action = fadeOut) then + begin + If delay = delayed then + For i := 0 to fade_speed do + begin + For j := fade_first to fade_last do + begin + data.pal1[j].r := data.pal0[j].r * i DIV fade_speed; + data.pal1[j].g := data.pal0[j].g * i DIV fade_speed; + data.pal1[j].b := data.pal0[j].b * i DIV fade_speed; + end; + SetPalette(data.pal1,fade_first,fade_last); + wait_ms; + end + else + SetPalette(data.pal0,fade_first,fade_last); + data.action := fadeIn; + end; +end; + +procedure RefreshEnable; assembler; +asm mov ax,1200h; mov bl,36h; int 10h end; + +procedure RefreshDisable; assembler; +asm mov ax,1201h; mov bl,36h; int 10h end; + +procedure Split2Static; + +var + temp: Byte; + +begin + temp := PORT[$3da]; + PORT[$3c0] := $10 OR $20; + PORT[$3c0] := PORT[$3c1] OR $20; +end; + +procedure SplitScr(line: Integer); + +var + temp: Byte; + +begin + PORT[$3d4] := $18; + PORT[$3d5] := LO(line); + PORT[$3d4] := $07; + temp := PORT[$3d5]; + + If (line < $100) then temp := temp AND $0ef + else temp := temp OR $10; + + PORT[$3d5] := temp; + PORT[$3d4] := $09; + temp := PORT[$3d5]; + + If (line < $200) then temp := temp AND $0bf + else temp := temp OR $40; + + PORT[$3d5] := temp; +end; + +procedure SetSize(columns,lines: Integer); +begin + PORT[$3d4] := $13; + PORT[$3d5] := columns SHR 1; + MEMW[$0000:$44a] := columns; + MEMW[$0000:$484] := lines-1; + MEMW[$0000:$44c] := columns*lines; +end; + +procedure SetTextDisp(x,y: Integer); + +var + temp: Byte; + +begin + While (PORT[$3da] AND 1 = 1) do ; + While (PORT[$3da] AND 1 <> 1) do ; + + PORT[$3d4] := $0c; + PORT[$3d5] := HI((y SHR 4)*MaxCol+(x DIV 9)); + PORT[$3d4] := $0d; + PORT[$3d5] := LO((y SHR 4)*MaxCol+(x DIV 9)); + PORT[$3d4] := $08; + PORT[$3d5] := (PORT[$3d5] AND $0e0) OR (y AND $0f); + temp := PORT[$3da]; + PORT[$3c0] := $13 OR $20; + PORT[$3c0] := (x+9) MOD 9; +end; + +procedure SetCustomVideoMode(vmode: tCUSTOM_VIDEO_MODE); + +const + vmode_data: array[0..52,0..63] of Byte = ( + +{ 1..5 - BIOS variables, + 6..9 - Sequencer, + 10 - Miscellaneous Output, + 11..35 - CRTC, + 36..55 - Attribute, + 56..64 - Graphics } + +{ 0, Text 36x14, 9x14, complete } +( 36, 13, 14, 0, 4, 8, 3, 0, 2, 99, + 40, 35, 36,138, 38,192,183, 31, 0,205, 11, 12, 0, 0, 0, + 0,148,134,135, 18, 31,142,177,163,255, 0, 1, 2, 3, 4, + 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 12, 0, 15, 8, + 0, 0, 0, 0, 0, 16, 14, 0, 255), + +{ 1, Text 40x14, 8x14, complete } +( 40, 13, 14, 0, 5, 9, 3, 0, 2, 99, + 45, 39, 40,144, 43,160,183, 31, 0,205, 11, 12, 0, 0, 0, + 0,148,134,135, 20, 31,142,177,163,255, 0, 1, 2, 3, 4, + 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 12, 0, 15, 0, + 0, 0, 0, 0, 0, 16, 14, 0, 255), + +{ 2, Text 40x14, 9x14, complete } +( 40, 13, 14, 0, 5, 8, 3, 0, 2, 103, + 45, 39, 40,144, 43,160,183, 31, 0,205, 11, 12, 0, 0, 0, + 0,148,134,135, 20, 31,142,177,163,255, 0, 1, 2, 3, 4, + 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 12, 0, 15, 8, + 0, 0, 0, 0, 0, 16, 14, 0, 255), + +{ 3, Text 46x14, 8x14, complete } +( 46, 13, 14, 0, 6, 9, 3, 0, 2, 103, + 52, 45, 46,151, 50,150,183, 31, 0,205, 11, 12, 0, 0, 0, + 0,148,134,135, 23, 31,142,177,163,255, 0, 1, 2, 3, 4, + 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 12, 0, 15, 0, + 0, 0, 0, 0, 0, 16, 14, 0, 255), + + +{ 4, Text 36x15, 9x16, complete } +( 36, 14, 16, 0, 5, 8, 3, 0, 2, 227, + 40, 35, 36,138, 38,192, 11, 62, 0,207, 13, 14, 0, 0, 0, + 0,234,172,223, 18, 31,231, 6,163,255, 0, 1, 2, 3, 4, + 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 12, 0, 15, 8, + 0, 0, 0, 0, 0, 16, 14, 0, 255), + +{ 5, Text 40x15, 8x16, complete } +( 40, 14, 16, 0, 5, 9, 3, 0, 2, 227, + 45, 39, 40,144, 43,160, 11, 62, 0,207, 13, 14, 0, 0, 0, + 0,234,172,223, 20, 31,231, 6,163,255, 0, 1, 2, 3, 4, + 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 12, 0, 15, 0, + 0, 0, 0, 0, 0, 16, 14, 0, 255), + +{ 6, Text 40x15, 9x16, complete } +( 40, 14, 16, 0, 5, 8, 3, 0, 2, 231, + 45, 39, 40,144, 43,160, 11, 62, 0,207, 13, 14, 0, 0, 0, + 0,234,172,223, 20, 31,231, 6,163,255, 0, 1, 2, 3, 4, + 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 12, 0, 15, 8, + 0, 0, 0, 0, 0, 16, 14, 0, 255), + +{ 7, Text 46x15, 8x16, complete } +( 46, 14, 16, 0, 6, 9, 3, 0, 2, 231, + 52, 45, 46,151, 50,150, 11, 62, 0,207, 13, 14, 0, 0, 0, + 0,234,172,223, 23, 31,231, 6,163,255, 0, 1, 2, 3, 4, + 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 12, 0, 15, 0, + 0, 0, 0, 0, 0, 16, 14, 0, 255), + + +{ 8, Text 36x17, 9x14, complete } +( 36, 16, 14, 0, 5, 8, 3, 0, 2, 227, + 40, 35, 36,138, 38,192, 7, 62, 0,205, 11, 12, 0, 0, 0, + 0,230,168,219, 18, 31,227, 2,163,255, 0, 1, 2, 3, 4, + 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 12, 0, 15, 8, + 0, 0, 0, 0, 0, 16, 14, 0, 255), + +{ 9, Text 40x17, 8x14, complete } +( 40, 16, 14, 0, 6, 9, 3, 0, 2, 227, + 45, 39, 40,144, 43,160, 7, 62, 0,205, 11, 12, 0, 0, 0, + 0,230,168,219, 20, 31,227, 2,163,255, 0, 1, 2, 3, 4, + 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 12, 0, 15, 0, + 0, 0, 0, 0, 0, 16, 14, 0, 255), + +{ 10, Text 40x17, 9x14, complete } +( 40, 16, 14, 0, 6, 8, 3, 0, 2, 231, + 45, 39, 40,144, 43,160, 7, 62, 0,205, 11, 12, 0, 0, 0, + 0,230,168,219, 20, 31,227, 2,163,255, 0, 1, 2, 3, 4, + 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 12, 0, 15, 8, + 0, 0, 0, 0, 0, 16, 14, 0, 255), + +{ 11, Text 46x17, 9x14, complete } +( 46, 16, 14, 0, 7, 9, 3, 0, 2, 231, + 52, 45, 46,151, 50,150, 7, 62, 0,205, 11, 12, 0, 0, 0, + 0,230,168,219, 23, 31,227, 2,163,255, 0, 1, 2, 3, 4, + 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 12, 0, 15, 0, + 0, 0, 0, 0, 0, 16, 14, 0, 255), + + +{ 12, Text 36x22, 9x16, complete } +( 36, 21, 16, 0, 7, 8, 3, 0, 2, 163, + 40, 35, 36,138, 38,192,193, 31, 0, 79, 13, 14, 0, 0, 0, + 0,133,165, 95, 18, 31,101,187,163,255, 0, 1, 2, 3, 4, + 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 12, 0, 15, 8, + 0, 0, 0, 0, 0, 16, 14, 0, 255), + +{ 13, Text 40x22, 8x16, complete } +( 40, 21, 16, 0, 7, 9, 3, 0, 2, 163, + 45, 39, 40,144, 43,160,193, 31, 0, 79, 13, 14, 0, 0, 0, + 0,133,165, 95, 20, 31,101,187,163,255, 0, 1, 2, 3, 4, + 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 12, 0, 15, 0, + 0, 0, 0, 0, 0, 16, 14, 0, 255), + +{ 14, Text 40x22, 9x16, complete } +( 40, 21, 16, 0, 7, 8, 3, 0, 2, 167, + 45, 39, 40,144, 43,160,193, 31, 0, 79, 13, 14, 0, 0, 0, + 0,133,165, 95, 20, 31,101,187,163,255, 0, 1, 2, 3, 4, + 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 12, 0, 15, 8, + 0, 0, 0, 0, 0, 16, 14, 0, 255), + +{ 15, Text 46x22, 8x16, complete } +( 46, 21, 16, 0, 8, 9, 3, 0, 2, 167, + 52, 45, 46,151, 50,150,193, 31, 0, 79, 13, 14, 0, 0, 0, + 0,133,165, 95, 23, 31,101,187,163,255, 0, 1, 2, 3, 4, + 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 12, 0, 15, 0, + 0, 0, 0, 0, 0, 16, 14, 0, 255), + +{ 16, Text 70x22, 9x16, complete } +( 70, 21, 16, 0,13, 0, 3, 0, 2, 163, + 83, 69, 70,150, 75, 21,193, 31, 0, 79, 13, 14, 0, 0, 0, + 0,133,165, 95, 35, 31,101,187,163,255, 0, 1, 2, 3, 4, + 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 12, 0, 15, 8, + 0, 0, 0, 0, 0, 16, 14, 0, 255), + +{ 17, Text 80x22, 8x16, complete } +( 80, 21, 16, 0,14, 1, 3, 0, 2, 163, + 95, 79, 80,130, 85,129,193, 31, 0, 79, 13, 14, 0, 0, 0, + 0,133,165, 95, 40, 31,101,187,163,255, 0, 1, 2, 3, 4, + 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 12, 0, 15, 0, + 0, 0, 0, 0, 0, 16, 14, 0, 255), + +{ 18, Text 80x22, 9x16, complete } +( 80, 21, 16, 0,14, 0, 3, 0, 2, 167, + 95, 79, 80,130, 85,129,193, 31, 0, 79, 13, 14, 0, 0, 0, + 0,133,165, 95, 40, 31,101,187,163,255, 0, 1, 2, 3, 4, + 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 12, 0, 15, 8, + 0, 0, 0, 0, 0, 16, 14, 0, 255), + +{ 19, Text 90x22, 8x16, complete } +( 90, 21, 16, 0,16, 1, 3, 0, 2, 167, + 107, 89, 90,142, 95,138,193, 31, 0, 79, 13, 14, 0, 0, 0, + 0,133,165, 95, 45, 31,101,187,163,255, 0, 1, 2, 3, 4, + 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 12, 0, 15, 0, + 0, 0, 0, 0, 0, 16, 14, 0, 255), + + +{ 20, Text 36x25, 9x16, complete } +( 36, 24, 16, 0, 8, 8, 3, 0, 2, 99, + 40, 35, 36,138, 38,192,191, 31, 0, 79, 13, 14, 0, 0, 0, + 0,156,142,143, 18, 31,150,185,163,255, 0, 1, 2, 3, 4, + 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 12, 0, 15, 8, + 0, 0, 0, 0, 0, 16, 14, 0, 255), + +{ 21, Text 40x25, 8x16, complete } +( 40, 24, 16, 0, 8, 9, 3, 0, 2, 99, + 45, 39, 40,144, 43,160,191, 31, 0, 79, 13, 14, 0, 0, 0, + 0,156,142,143, 20, 31,150,185,163,255, 0, 1, 2, 3, 4, + 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 12, 0, 15, 0, + 0, 0, 0, 0, 0, 16, 14, 0, 255), + +{ 22, Text 40x25, 9x16, complete } +( 40, 24, 16, 0, 8, 8, 3, 0, 2, 103, + 45, 39, 40,144, 43,160,191, 31, 0, 79, 13, 14, 0, 0, 0, + 0,156,142,143, 20, 31,150,185,163,255, 0, 1, 2, 3, 4, + 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 12, 0, 15, 8, + 0, 0, 0, 0, 0, 16, 14, 0, 255), + +{ 23, Text 46x25, 8x16, complete } +( 46, 24, 16, 0,10, 9, 3, 0, 2, 103, + 52, 45, 46,151, 50,150,191, 31, 0, 79, 13, 14, 0, 0, 0, + 0,156,142,143, 23, 31,150,185,163,255, 0, 1, 2, 3, 4, + 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 12, 0, 15, 0, + 0, 0, 0, 0, 0, 16, 14, 0, 255), + +{ 24, Text 70x25, 9x16, complete } +( 70, 24, 16, 0,14, 0, 3, 0, 2, 99, + 83, 69, 70,150, 75, 21,191, 31, 0, 79, 13, 14, 0, 0, 0, + 0,156,142,143, 35, 31,150,185,163,255, 0, 1, 2, 3, 4, + 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 12, 0, 15, 8, + 0, 0, 0, 0, 0, 16, 14, 0, 255), + +{ 25, Text 80x25, 8x16, complete } +( 80, 24, 16, 0,16, 1, 3, 0, 2, 99, + 95, 79, 80,130, 85,129,191, 31, 0, 79, 13, 14, 0, 0, 0, + 0,156,142,143, 40, 31,150,185,163,255, 0, 1, 2, 3, 4, + 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 12, 0, 15, 0, + 0, 0, 0, 0, 0, 16, 14, 0, 255), + +{ 26, Text 80x25, 9x16, standard } +( 80, 24, 16, 0,16, 0, 3, 0, 2, 103, + 95, 79, 80,130, 85,129,191, 31, 0, 79, 13, 14, 0, 0, 0, + 0,156,142,143, 40, 31,150,185,163,255, 0, 1, 2, 3, 4, + 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 12, 0, 15, 8, + 0, 0, 0, 0, 0, 16, 14, 0, 255), + +{ 27, Text 90x25, 8x16, complete } +( 90, 24, 16, 0, 18 , 1, 3, 0, 2, 103, + 107, 89, 90,142, 95,138,191, 31, 0, 79, 13, 14, 0, 0, 0, + 0,156,142,143, 45, 31,150,185,163,255, 0, 1, 2, 3, 4, + 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 8, 0, 15, 0, + 0, 0, 0, 0, 0, 16, 14, 0, 255), + + +{ 28, Text 46x29, 8x16, complete } +( 46, 28, 14, 0,11, 9, 3, 0, 2, 103, + 52, 45, 46,151, 50,150,193, 31, 0, 77, 11, 12, 0, 0, 0, + 0,159,145,149, 23, 31,155,185,163,255, 0, 1, 2, 3, 4, + 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 12, 0, 15, 0, + 0, 0, 0, 0, 0, 16, 14, 0, 255), + +{ 29, Text 70x29, 9x14, complete } +( 70, 28, 14, 0, 16 , 0, 3, 0, 2, 99, + 83, 69, 70,150, 75, 21,193, 31, 0, 77, 11, 12, 0, 0, 0, + 0,159,145,149, 35, 31,155,185,163,255, 0, 1, 2, 3, 4, + 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 8, 0, 15, 8, + 0, 0, 0, 0, 0, 16, 14, 0, 255), + +{ 30, Text 80x29, 8x14, complete } +( 80, 28, 14, 0, 19 , 1, 3, 0, 2, 99, + 95, 79, 80,130, 85,129,193, 31, 0, 77, 11, 12, 0, 0, 0, + 0,159,145,149, 40, 31,155,185,163,255, 0, 1, 2, 3, 4, + 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 8, 0, 15, 0, + 0, 0, 0, 0, 0, 16, 14, 0, 255), + +{ 31, Text 80x29, 9x14, complete } +( 80, 28, 14, 0, 19 , 0, 3, 0, 2, 103, + 95, 79, 80,130, 85,129,193, 31, 0, 77, 11, 12, 0, 0, 0, + 0,159,145,149, 40, 31,155,185,163,255, 0, 1, 2, 3, 4, + 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 8, 0, 15, 8, + 0, 0, 0, 0, 0, 16, 14, 0, 255), + +{ 32, Text 90x29, 8x14, complete } +( 90, 28, 14, 0, 21 , 1, 3, 0, 2, 103, + 107, 89, 90,142, 95,138,193, 31, 0, 77, 11, 12, 0, 0, 0, + 0,159,145,149, 45, 31,155,185,163,255, 0, 1, 2, 3, 4, + 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 8, 0, 15, 0, + 0, 0, 0, 0, 0, 16, 14, 0, 255), + + +{ 33, Text 70x30, 9x16, complete } +( 70, 29, 16, 0, 17 , 0, 3, 0, 2, 227, + 83, 69, 70,150, 75, 21, 11, 62, 0, 79, 13, 14, 0, 0, 0, + 0,234,172,223, 35, 31,231, 6,163,255, 0, 1, 2, 3, 4, + 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 8, 0, 15, 8, + 0, 0, 0, 0, 0, 16, 14, 0, 255), + +{ 34, Text 80x30, 8x16, complete } +( 80, 29, 16, 0, 19 , 1, 3, 0, 2, 227, + 95, 79, 80,130, 85,129, 11, 62, 0, 79, 13, 14, 0, 0, 0, + 0,234,172,223, 40, 31,231, 6,163,255, 0, 1, 2, 3, 4, + 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 8, 0, 15, 0, + 0, 0, 0, 0, 0, 16, 14, 0, 255), + +{ 35, Text 80x30, 9x16, complete } +( 80, 29, 16, 0, 19 , 0, 3, 0, 2, 231, + 95, 79, 80,130, 85,129, 11, 62, 0, 79, 13, 14, 0, 0, 0, + 0,234,172,223, 40, 31,231, 6,163,255, 0, 1, 2, 3, 4, + 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 8, 0, 15, 8, + 0, 0, 0, 0, 0, 16, 14, 0, 255), + +{ 36, Text 90x30, 8x16 ,complete } +( 90, 29, 16, 0, 22 , 1, 3, 0, 2, 231, + 107, 89, 90,142, 95,138, 11, 62, 0, 79, 13, 14, 0, 0, 0, + 0,234,172,223, 45, 31,231, 6,163,255, 0, 1, 2, 3, 4, + 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 8, 0, 15, 0, + 0, 0, 0, 0, 0, 16, 14, 0, 255), + + +{ 37, Text 70x34, 9x14, complete } +( 70, 33, 14, 0, 19 , 0, 3, 0, 2, 227, + 83, 69, 70,150, 75, 21, 7, 62, 0, 77, 11, 12, 0, 0, 0, + 0,230,168,219, 35, 31,227, 2,163,255, 0, 1, 2, 3, 4, + 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 8, 0, 15, 8, + 0, 0, 0, 0, 0, 16, 14, 0, 255), + +{ 38, Text 80x34, 8x14, complete } +( 80, 33, 14, 0, 22 , 1, 3, 0, 2, 227, + 95, 79, 80,130, 85,129, 7, 62, 0, 77, 11, 12, 0, 0, 0, + 0,230,168,219, 40, 31,227, 2,163,255, 0, 1, 2, 3, 4, + 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 8, 0, 15, 0, + 0, 0, 0, 0, 0, 16, 14, 0, 255), + +{ 39, Text 80x34, 9x14, complete } +( 80, 33, 14, 0, 22 , 0, 3, 0, 2, 231, + 95, 79, 80,130, 85,129, 7, 62, 0, 77, 11, 12, 0, 0, 0, + 0,230,168,219, 40, 31,227, 2,163,255, 0, 1, 2, 3, 4, + 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 8, 0, 15, 8, + 0, 0, 0, 0, 0, 16, 14, 0, 255), + +{ 40, Text 90x34, 8x14, complete } +( 90, 33, 14, 0, 24 , 1, 3, 0, 2, 231, + 107, 89, 90,142, 95,138, 7, 62, 0, 77, 11, 12, 0, 0, 0, + 0,230,168,219, 45, 31,227, 2,163,255, 0, 1, 2, 3, 4, + 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 8, 0, 15, 0, + 0, 0, 0, 0, 0, 16, 14, 0, 255), + + +{ 41, Text 70x44, 9x8, complete } +( 70, 43, 8, 0,25, 0, 3, 0, 2, 163, + 83, 69, 70,150, 75, 21,193, 31, 0, 71, 6, 7, 0, 0, 0, + 0,133,135, 95, 35, 15,101,187,163,255, 0, 1, 2, 3, 4, + 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 12, 0, 15, 8, + 0, 0, 0, 0, 0, 16, 14, 0, 255), + +{ 42, Text 80x44, 8x8, complete } +( 80, 43, 8, 0,28, 1, 3, 0, 2, 163, + 95, 79, 80,130, 85,129,193, 31, 0, 71, 6, 7, 0, 0, 0, + 0,133,135, 95, 40, 15,101,187,163,255, 0, 1, 2, 3, 4, + 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 12, 0, 15, 0, + 0, 0, 0, 0, 0, 16, 14, 0, 255), + +{ 43, Text 80x44, 9x8, complete } +( 80, 43, 8, 0,28, 0, 3, 0, 2, 167, + 95, 79, 80,130, 85,129,193, 31, 0, 71, 6, 7, 0, 0, 0, + 0,133,135, 95, 40, 15,101,187,163,255, 0, 1, 2, 3, 4, + 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 12, 0, 15, 8, + 0, 0, 0, 0, 0, 16, 14, 0, 255), + +{ 44, Text 90x44, 8x8, complete } +( 90, 43, 8, 0,31, 1, 3, 0, 2, 167, + 107, 89, 90,142, 95,138,193, 31, 0, 71, 6, 7, 0, 0, 0, + 0,133,135, 95, 45, 15,101,187,163,255, 0, 1, 2, 3, 4, + 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 12, 0, 15, 0, + 0, 0, 0, 0, 0, 16, 14, 0, 255), + + +{ 45, Text 70x50, 9x8, complete } +( 70, 49, 8, 0,28, 0, 3, 0, 2, 99, + 83, 69, 70,150, 75, 21,191, 31, 0, 71, 6, 7, 0, 0, 0, + 0,156,142,143, 35, 31,150,185,163,255, 0, 1, 2, 3, 4, + 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 12, 0, 15, 8, + 0, 0, 0, 0, 0, 16, 14, 0, 255), + +{ 46, Text 80x50, 8x8, complete } +( 80, 49, 8, 0,32, 1, 3, 0, 2, 99, + 95, 79, 80,130, 85,129,191, 31, 0, 71, 6, 7, 0, 0, 0, + 0,156,142,143, 40, 31,150,185,163,255, 0, 1, 2, 3, 4, + 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 12, 0, 15, 0, + 0, 0, 0, 0, 0, 16, 14, 0, 255), + +{ 47, Text 80x50, 9x8, standard } +( 80, 49, 8, 0,32, 0, 3, 0, 2, 103, + 95, 79, 80,130, 85,129,191, 31, 0, 71, 6, 7, 0, 0, 0, + 0,156,142,143, 40, 31,150,185,163,255, 0, 1, 2, 3, 4, + 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 12, 0, 15, 8, + 0, 0, 0, 0, 0, 16, 14, 0, 255), + +{ 48, Text 90x50, 8x8, complete } +( 90, 49, 8, 0, 36 , 1, 3, 0, 2, 103, + 107, 89, 90,142, 95,138,191, 31, 0, 71, 6, 7, 0, 0, 0, + 0,156,142,143, 45, 31,150,185,163,255, 0, 1, 2, 3, 4, + 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 8, 0, 15, 0, + 0, 0, 0, 0, 0, 16, 14, 0, 255), + + +{ 49, Text 70x60, 9x8, complete } +( 70, 59, 8, 0, 33 , 0, 3, 0, 2, 227, + 83, 69, 70,150, 75, 21, 11, 62, 0, 71, 6, 7, 0, 0, 0, + 0,234,172,223, 35, 31,231, 6,163,255, 0, 1, 2, 3, 4, + 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 8, 0, 15, 8, + 0, 0, 0, 0, 0, 16, 14, 0, 255), + +{ 50, Text 80x60, 8x8, complete } +( 80, 59, 8, 0, 38 , 1, 3, 0, 2, 227, + 95, 79, 80,130, 85,129, 11, 62, 0, 71, 6, 7, 0, 0, 0, + 0,234,172,223, 40, 31,231, 6,163,255, 0, 1, 2, 3, 4, + 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 8, 0, 15, 0, + 0, 0, 0, 0, 0, 16, 14, 0, 255), + +{ 51, Text 80x60, 9x8, complete } +( 80, 59, 8, 0, 38 , 0, 3, 0, 2, 231, + 95, 79, 80,130, 85,129, 11, 62, 0, 71, 6, 7, 0, 0, 0, + 0,234,172,223, 40, 31,231, 6,163,255, 0, 1, 2, 3, 4, + 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 8, 0, 15, 8, + 0, 0, 0, 0, 0, 16, 14, 0, 255), + +{ 52, Text 90x60, 8x8, complete } +( 90, 59, 8,128, 42 , 1, 3, 0, 2, 231, + 107, 89, 90,142, 95,138, 11, 62, 0, 71, 6, 7, 0, 0, 0, + 0,234,172,223, 45, 31,231, 6,163,255, 0, 1, 2, 3, 4, + 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 8, 0, 15, 0, + 0, 0, 0, 0, 0, 16, 14, 0, 255) + +); + +begin + asm + movzx eax,vmode + shl eax,6 + lea esi,[vmode_data] + add esi,eax + mov dx,3cch + in al,dx + mov dl,0d4h + test al,1 + jnz @@1 + mov dl,0b4h + @@1: add dx,6 + in al,dx + xor al,al + mov dx,3c0h + out dx,al + mov ax,100h + mov dx,3c4h + out dx,ax + add esi,5 + mov ecx,4 + mov al,1 + mov dx,3c4h + @@2: mov ah,[esi] + inc esi + out dx,ax + inc al + loop @@2 + mov al,[esi] + inc esi + mov dx,3c2h + out dx,al + mov dx,3c4h + mov ax,300h + out dx,ax + mov dx,3cch + in al,dx + mov dl,0d4h + test al,1 + jnz @@3 + mov dl,0b4h + @@3: movzx edi,SEG0040 + shl edi,4 + add edi,63h + shl edi,4 + mov [edi],dx + mov al,11h + out dx,al + inc dx + mov ah,al + in al,dx + dec dx + xchg al,ah + and ah,7fh + out dx,ax + mov ecx,25 + xor al,al + @@4: mov ah,[esi] + inc esi + out dx,ax + inc al + loop @@4 + add dx,6 + in al,dx + xor ah,ah + mov ecx,20 + mov dx,3c0h + @@5: mov al,ah + out dx,al + inc ah + mov al,[esi] + inc esi + out dx,al + loop @@5 + xor al,al + mov ecx,9 + mov dx,3ceh + @@6: mov ah,[esi] + inc esi + out dx,ax + inc al + loop @@6 + mov dx,3c0h + mov al,32 + out dx,al + end; + + MEM[SEG0040:$4a] := vmode_data[vmode,0]; + MEM[SEG0040:$84] := vmode_data[vmode,1]; + MEM[SEG0040:$85] := vmode_data[vmode,2]; + MEM[SEG0040:$4c] := vmode_data[vmode,3]; + MEM[SEG0040:$4d] := vmode_data[vmode,4]; + FillChar(MEM[SEG0040:$4e],17,0); + + MEM[SEG0040:$60] := vmode_data[vmode,20]; + MEM[SEG0040:$61] := vmode_data[vmode,21]; + MEM[SEG0040:$62] := 0; + + Case vmode_data[vmode,2] of + 8: asm mov ah,11h; mov al,2; xor bx,bx; int 10h end; + 14: asm mov ah,11h; mov al,1; xor bx,bx; int 10h end; + 16: asm mov ah,11h; mov al,4; xor bx,bx; int 10h end; + end; + + initialize; + CleanScreen(Ptr(v_seg,v_ofs)^); +end; + +begin + initialize; +end. diff --git a/16/ADT2PLAY/a2player.c b/16/ADT2PLAY/a2player.c new file mode 100644 index 00000000..92c799ff --- /dev/null +++ b/16/ADT2PLAY/a2player.c @@ -0,0 +1,239 @@ +/* Output from p2c 1.21alpha-07.Dec.93, the Pascal-to-C translator */ +/* From input file "a2player.pas" */ + + +#include + + +#define A2PLAYER_G +#include "a2player.h" + + +unsigned short opl3port = 0x388; +short error_code = 0; +uchar current_order = 0, current_pattern = 0, current_line = 0, tempo = 50, + speed = 6; +unsigned short macro_speedup = 1; +boolean irq_mode = false; +uchar max_patterns = 128; +boolean fast_forward = false; +uchar overall_volume = 63, global_volume = 63; +unsigned short song_timer = 0, song_timer_tenths = 0; +Void (*external_irq_hook) PV() = NULL; +long _delay_counter = 0; +unsigned short irq_freq = 50; +boolean irq_initialized = false, timer_fix = true, pattern_break = false, + pattern_delay = false; +uchar next_line = 0; +tPLAY_STATUS play_status = isStopped; +boolean replay_forbidden = true, force_macro_keyon = false; + +#ifndef TIMERINT_H +#include "timerint.h" +#endif + +#ifndef PARSERIO_H +#include "parserio.h" +#endif + + +typedef unsigned short tTRACK_ADDR[20]; + + +#define keyoff_flag 0x80 +#define fixed_note_flag 0x90 +#define pattern_loop_flag 0xe0 +#define pattern_break_flag 0xf0 + + +typedef struct _REC_porta_table { + unsigned short freq; + uchar speed; +} _REC_porta_table; + +typedef struct _REC_porta_table2 { + unsigned short freq; + uchar speed; +} _REC_porta_table2; + +typedef struct _REC_arpgg_table { + uchar state, note, add1, add2; +} _REC_arpgg_table; + +typedef struct _REC_arpgg_table2 { + uchar state, note, add1, add2; +} _REC_arpgg_table2; + +typedef struct _REC_vibr_table { + uchar pos, speed, depth; + boolean fine; +} _REC_vibr_table; + +typedef struct _REC_vibr_table2 { + uchar pos, speed, depth; + boolean fine; +} _REC_vibr_table2; + +typedef struct _REC_trem_table { + uchar pos, speed, depth; + boolean fine; +} _REC_trem_table; + +typedef struct _REC_trem_table2 { + uchar pos, speed, depth; + boolean fine; +} _REC_trem_table2; + +typedef struct _REC_tremor_table { + short pos; + unsigned short volume; +} _REC_tremor_table; + +typedef struct _REC_tremor_table2 { + short pos; + unsigned short volume; +} _REC_tremor_table2; + +typedef struct _REC_macro_table { + unsigned short fmreg_pos, arpg_pos, vib_pos; + uchar fmreg_count, fmreg_duration, arpg_count, vib_count, vib_delay; + boolean vib_paused; + uchar fmreg_table, arpg_table, vib_table, arpg_note; + unsigned short vib_freq; +} _REC_macro_table; + + +Static uchar _panning[3] = { + 0x30, 0x10, 0x20 +}; + +Static uchar _instr[12] = { + 0x20, 0x20, 0x40, 0x40, 0x60, 0x60, 0x80, 0x80, 0xe0, 0xe0, 0xc0, 0xbd +}; + +/* 01 - 02 - 03 - 04 - 05 - 06 - 07 - 08 - 09 - 10 - 11 - 12 - 13 - 14 - 15 - 16 - 17 - 18 - 19 - 20 */ + +Static tTRACK_ADDR _chmm_n = { + 0x3, 0, 0x4, 0x1, 0x5, 0x2, 0x6, 0x7, 0x8, 0x103, 0x100, 0x104, 0x101, + 0x105, 0x102, 0x106, 0x107, 0x108, BYTE_NULL, BYTE_NULL +}; + +Static tTRACK_ADDR _chmm_m = { + 0x8, 0, 0x9, 0x1, 0xa, 0x2, 0x10, 0x11, 0x12, 0x108, 0x100, 0x109, 0x101, + 0x10a, 0x102, 0x110, 0x111, 0x112, BYTE_NULL, BYTE_NULL +}; + +Static tTRACK_ADDR _chmm_c = { + 0xb, 0x3, 0xc, 0x4, 0xd, 0x5, 0x13, 0x14, 0x15, 0x10b, 0x103, 0x10c, 0x104, + 0x10d, 0x105, 0x113, 0x114, 0x115, BYTE_NULL, BYTE_NULL +}; + +/* BD SD TT TC HH */ + +Static tTRACK_ADDR _chpm_n = { + 0x3, 0, 0x4, 0x1, 0x5, 0x2, 0x106, 0x107, 0x108, 0x103, 0x100, 0x104, 0x101, + 0x105, 0x102, 0x6, 0x7, 0x8, 0x8, 0x7 +}; + +Static tTRACK_ADDR _chpm_m = { + 0x8, 0, 0x9, 0x1, 0xa, 0x2, 0x110, 0x111, 0x112, 0x108, 0x100, 0x109, 0x101, + 0x10a, 0x102, 0x10, 0x14, 0x12, 0x15, 0x11 +}; + +Static tTRACK_ADDR _chpm_c = { + 0xb, 0x3, 0xc, 0x4, 0xd, 0x5, 0x113, 0x114, 0x115, 0x10b, 0x103, 0x10c, + 0x104, 0x10d, 0x105, 0x13, BYTE_NULL, BYTE_NULL, BYTE_NULL, BYTE_NULL +}; + +Static tTRACK_ADDR _chan_n, _chan_m, _chan_c; +Static uchar def_vibtrem_speed_factor = 1, def_vibtrem_table_size = 32; + +Static uchar def_vibtrem_table[256] = { + 0, 24, 49, 74, 97, 120, 141, 161, 180, 197, 212, 224, 235, 244, 250, 253, + 255, 253, 250, 244, 235, 224, 212, 197, 180, 161, 141, 120, 97, 74, 49, 24, + 0, 24, 49, 74, 97, 120, 141, 161, 180, 197, 212, 224, 235, 244, 250, 253, + 255, 253, 250, 244, 235, 224, 212, 197, 180, 161, 141, 120, 97, 74, 49, 24, + 0, 24, 49, 74, 97, 120, 141, 161, 180, 197, 212, 224, 235, 244, 250, 253, + 255, 253, 250, 244, 235, 224, 212, 197, 180, 161, 141, 120, 97, 74, 49, 24, + 0, 24, 49, 74, 97, 120, 141, 161, 180, 197, 212, 224, 235, 244, 250, 253, + 255, 253, 250, 244, 235, 224, 212, 197, 180, 161, 141, 120, 97, 74, 49, 24, + 0, 24, 49, 74, 97, 120, 141, 161, 180, 197, 212, 224, 235, 244, 250, 253, + 255, 253, 250, 244, 235, 224, 212, 197, 180, 161, 141, 120, 97, 74, 49, 24, + 0, 24, 49, 74, 97, 120, 141, 161, 180, 197, 212, 224, 235, 244, 250, 253, + 255, 253, 250, 244, 235, 224, 212, 197, 180, 161, 141, 120, 97, 74, 49, 24, + 0, 24, 49, 74, 97, 120, 141, 161, 180, 197, 212, 224, 235, 244, 250, 253, + 255, 253, 250, 244, 235, 224, 212, 197, 180, 161, 141, 120, 97, 74, 49, 24, + 0, 24, 49, 74, 97, 120, 141, 161, 180, 197, 212, 224, 235, 244, 250, 253, + 255, 253, 250, 244, 235, 224, 212, 197, 180, 161, 141, 120, 97, 74, 49, 24 +/* p2c: a2player.pas, line 484: + * Note: Line breaker spent 0.0 seconds, 5000 tries on line 167 [251] */ +}; + +Static uchar vibtrem_speed_factor, vibtrem_table_size; +Static uchar vibtrem_table[256]; + +Static tFM_PARAMETER_TABLE fmpar_table[20]; +Static boolean volume_lock[20]; +Static unsigned short volume_table[20]; +Static unsigned short vscale_table[20]; +Static boolean peak_lock[20]; +Static boolean pan_lock[20]; +Static tADTRACK2_EVENT event_table[20]; +Static uchar voice_table[20]; +Static uchar modulator_vol[20]; +Static uchar carrier_vol[20]; +Static unsigned short freq_table[20]; +Static unsigned short effect_table[20]; +Static unsigned short effect_table2[20]; +Static uchar fslide_table[20]; +Static uchar fslide_table2[20]; +Static unsigned short glfsld_table[20]; +Static unsigned short glfsld_table2[20]; +Static _REC_porta_table porta_table[20]; +Static _REC_porta_table2 porta_table2[20]; +Static _REC_arpgg_table arpgg_table[20]; +Static _REC_arpgg_table2 arpgg_table2[20]; +Static _REC_vibr_table vibr_table[20]; +Static _REC_vibr_table2 vibr_table2[20]; +Static _REC_trem_table trem_table[20]; +Static _REC_trem_table2 trem_table2[20]; +Static uchar retrig_table[20]; +Static uchar retrig_table2[20]; +Static _REC_tremor_table tremor_table[20]; +Static _REC_tremor_table2 tremor_table2[20]; +Static uchar panning_table[20]; +Static unsigned short last_effect[20]; +Static unsigned short last_effect2[20]; +Static uchar volslide_type[20]; +Static boolean event_new[20]; +Static uchar notedel_table[20]; +Static uchar notecut_table[20]; +Static short ftune_table[20]; +Static boolean keyoff_loop[20]; +Static _REC_macro_table macro_table[20]; + +Static uchar loopbck_table[20]; +Static uchar loop_table[20][256]; +Static uchar misc_register; +Static uchar current_tremolo_depth = 0, current_vibrato_depth = 0; + +Static boolean speed_update, lockvol, panlock, lockVP; +Static uchar tremolo_depth, vibrato_depth; +Static boolean volume_scaling, percussion_mode; +Static uchar last_order; +Static boolean reset_chan[20]; +/* p2c: a2player.pas, line 484: + * Warning: Expected BEGIN, found 'assembler' [227] */ + + +extern Void opl2out PP((int reg, int data)); +/* p2c: a2player.pas, line 485: Warning: Expected END, found 'asm' [227] */ +/* p2c: a2player.pas, line 504: + * Warning: Expected a '.', found PROCEDURE [227] */ +/* p2c: a2player.pas, line 504: + * Warning: Junk at end of input file ignored [277] */ + + + + +/* End. */ diff --git a/16/ADT2PLAY/a2player.h b/16/ADT2PLAY/a2player.h new file mode 100644 index 00000000..9538c6a9 --- /dev/null +++ b/16/ADT2PLAY/a2player.h @@ -0,0 +1,354 @@ +/* Header for module A2player, generated by p2c 1.21alpha-07.Dec.93 */ +#ifndef A2PLAYER_H +#define A2PLAYER_H + + +#ifdef A2PLAYER_G +# define vextern +#else +# define vextern extern +#endif + + +#define MAX_IRQ_FREQ 1000 + + +#define BYTE_NULL 0xff + +#define WORD_NULL 0xffffL +/* p2c: typconst.inc, line 4: Warning: Mismatched '$' signs [241] */ + +#define DWORD_NULL 0 +/* p2c: typconst.inc, line 4: + * Warning: Expected a semicolon, found 'ffffffff' [227] */ + + +typedef uchar tCHAR8x8[256][8]; +typedef uchar tCHAR8x16[256][16]; + + +typedef struct tRGB { + uchar r, g, b; +} tRGB; + +typedef tRGB tRGB_PALETTE[256]; + + +#define ef_Arpeggio 0 +#define ef_FSlideUp 1 +#define ef_FSlideDown 2 +#define ef_TonePortamento 3 +#define ef_Vibrato 4 +#define ef_TPortamVolSlide 5 +#define ef_VibratoVolSlide 6 +#define ef_FSlideUpFine 7 +#define ef_FSlideDownFine 8 +#define ef_SetModulatorVol 9 +#define ef_VolSlide 10 +#define ef_PositionJump 11 +#define ef_SetInsVolume 12 +#define ef_PatternBreak 13 +#define ef_SetTempo 14 +#define ef_SetSpeed 15 +#define ef_TPortamVSlideFine 16 +#define ef_VibratoVSlideFine 17 +#define ef_SetCarrierVol 18 +#define ef_SetWaveform 19 +#define ef_VolSlideFine 20 +#define ef_RetrigNote 21 +#define ef_Tremolo 22 +#define ef_Tremor 23 +#define ef_ArpggVSlide 24 +#define ef_ArpggVSlideFine 25 +#define ef_MultiRetrigNote 26 +#define ef_FSlideUpVSlide 27 +#define ef_FSlideDownVSlide 28 +#define ef_FSlUpFineVSlide 29 +#define ef_FSlDownFineVSlide 30 +#define ef_FSlUpVSlF 31 +#define ef_FSlDownVSlF 32 +#define ef_FSlUpFineVSlF 33 +#define ef_FSlDownFineVSlF 34 +#define ef_Extended 35 +#define ef_Extended2 36 +#define ef_SetGlobalVolume 37 +#define ef_SwapArpeggio 38 +#define ef_SwapVibrato 39 +#define ef_ForceInsVolume 40 +#define ef_Extended3 41 +#define ef_ExtraFineArpeggio 42 +#define ef_ExtraFineVibrato 43 +#define ef_ExtraFineTremolo 44 +#define ef_SetCustomSpeedTab 45 +#define ef_GlobalFSlideUp 46 +#define ef_GlobalFSlideDown 47 +#define ef_ex_SetTremDepth 0 +#define ef_ex_SetVibDepth 1 +#define ef_ex_SetAttckRateM 2 +#define ef_ex_SetDecayRateM 3 +#define ef_ex_SetSustnLevelM 4 +#define ef_ex_SetRelRateM 5 +#define ef_ex_SetAttckRateC 6 +#define ef_ex_SetDecayRateC 7 +#define ef_ex_SetSustnLevelC 8 +#define ef_ex_SetRelRateC 9 +#define ef_ex_SetFeedback 10 +#define ef_ex_SetPanningPos 11 +#define ef_ex_PatternLoop 12 +#define ef_ex_PatternLoopRec 13 +#define ef_ex_MacroKOffLoop 14 +#define ef_ex_ExtendedCmd 15 +#define ef_ex_cmd_RSS 0 +#define ef_ex_cmd_ResetVol 1 +#define ef_ex_cmd_LockVol 2 +#define ef_ex_cmd_UnlockVol 3 +#define ef_ex_cmd_LockVP 4 +#define ef_ex_cmd_UnlockVP 5 +#define ef_ex_cmd_VSlide_mod 6 +#define ef_ex_cmd_VSlide_car 7 +#define ef_ex_cmd_VSlide_def 8 +#define ef_ex_cmd_LockPan 9 +#define ef_ex_cmd_UnlockPan 10 +#define ef_ex_cmd_VibrOff 11 +#define ef_ex_cmd_TremOff 12 +#define ef_ex_cmd_FVib_FGFS 13 +#define ef_ex_cmd_FTrm_XFGFS 14 +#define ef_ex_cmd_NoRestart 15 +#define ef_ex2_PatDelayFrame 0 +#define ef_ex2_PatDelayRow 1 +#define ef_ex2_NoteDelay 2 +#define ef_ex2_NoteCut 3 +#define ef_ex2_FineTuneUp 4 +#define ef_ex2_FineTuneDown 5 +#define ef_ex2_GlVolSlideUp 6 +#define ef_ex2_GlVolSlideDn 7 +#define ef_ex2_GlVolSlideUpF 8 +#define ef_ex2_GlVolSlideDnF 9 +#define ef_ex2_GlVolSldUpXF 10 +#define ef_ex2_GlVolSldDnXF 11 +#define ef_ex2_VolSlideUpXF 12 +#define ef_ex2_VolSlideDnXF 13 +#define ef_ex2_FreqSlideUpXF 14 +#define ef_ex2_FreqSlideDnXF 15 +#define ef_ex3_SetConnection 0 +#define ef_ex3_SetMultipM 1 +#define ef_ex3_SetKslM 2 +#define ef_ex3_SetTremoloM 3 +#define ef_ex3_SetVibratoM 4 +#define ef_ex3_SetKsrM 5 +#define ef_ex3_SetSustainM 6 +#define ef_ex3_SetMultipC 7 +#define ef_ex3_SetKslC 8 +#define ef_ex3_SetTremoloC 9 +#define ef_ex3_SetVibratoC 10 +#define ef_ex3_SetKsrC 11 +#define ef_ex3_SetSustainC 12 + + +#define ef_fix1 0x80 +#define ef_fix2 0x90 + + + +typedef struct tFM_INST_DATA { + uchar AM_VIB_EG_modulator, AM_VIB_EG_carrier, KSL_VOLUM_modulator, + KSL_VOLUM_carrier, ATTCK_DEC_modulator, ATTCK_DEC_carrier, + SUSTN_REL_modulator, SUSTN_REL_carrier, WAVEFORM_modulator, + WAVEFORM_carrier, FEEDBACK_FM; +} tFM_INST_DATA; + + +typedef struct tADTRACK2_INS { + tFM_INST_DATA fm_data; + uchar panning; + short fine_tune; + uchar perc_voice; +} tADTRACK2_INS; + + +typedef struct tARPEGGIO_TABLE { + uchar length, speed, loop_begin, loop_length, keyoff_pos; + uchar data[255]; +} tARPEGGIO_TABLE; + + +typedef struct tVIBRATO_TABLE { + uchar length, speed, delay, loop_begin, loop_length, keyoff_pos; + short data[255]; +} tVIBRATO_TABLE; + + +typedef struct tREGISTER_TABLE_DEF { + tFM_INST_DATA fm_data; +/* p2c: a2player.pas, line 192: + * Warning: Symbol 'SMALLINT' is not defined [221] */ + long freq_slide; + uchar panning, duration; +} tREGISTER_TABLE_DEF; + +typedef long Smallint; + + +typedef struct tREGISTER_TABLE { + uchar length, loop_begin, loop_length, keyoff_pos, arpeggio_table, + vibrato_table; + tREGISTER_TABLE_DEF data[255]; +} tREGISTER_TABLE; + + +typedef struct tMACRO_TABLE { + tARPEGGIO_TABLE arpeggio; + tVIBRATO_TABLE vibrato; +} tMACRO_TABLE; + + +typedef struct tFM_PARAMETER_TABLE { + struct { + uchar attck, dec, sustn, rel, wform; + } adsrw_car, adsrw_mod; + uchar connect, feedb, multipM, kslM, tremM, vibrM, ksrM, sustM, multipC, + kslC, tremC, vibrC, ksrC, sustC; +} tFM_PARAMETER_TABLE; + + +typedef struct tADTRACK2_EVENT { + uchar note, instr_def, effect_def, effect, effect_def2, effect2; +} tADTRACK2_EVENT; + + +typedef boolean tDIS_FMREG_COL[28]; + + +typedef struct tFIXED_SONGDATA { + Char songname[43]; + Char composer[43]; + Char instr_names[255][43]; + tADTRACK2_INS instr_data[255]; + tREGISTER_TABLE instr_macros[255]; + tMACRO_TABLE macro_table[255]; + uchar pattern_order[0x80]; + uchar tempo, speed, common_flag; + unsigned short patt_len; + uchar nm_tracks; + unsigned short macro_speedup; + uchar flag_4op; + uchar lock_flags[20]; + Char pattern_names[0x80][43]; + tDIS_FMREG_COL dis_fmreg_col[255]; +} tFIXED_SONGDATA; + + +typedef enum { + isPlaying, isPaused, isStopped +} tPLAY_STATUS; + + +typedef tADTRACK2_EVENT tVARIABLE_DATA[8][20][0x100]; + + +typedef tVARIABLE_DATA tPATTERN_DATA[16]; + + +typedef uchar tDUMMY_BUFF[655350L]; + + +typedef struct tOLD_ADTRACK2_INS { + tFM_INST_DATA fm_data; + uchar panning; + short fine_tune; +} tOLD_ADTRACK2_INS; + + +typedef struct tOLD_FIXED_SONGDATA { + Char songname[43]; + Char composer[43]; + Char instr_names[250][33]; + tOLD_ADTRACK2_INS instr_data[250]; + uchar pattern_order[0x80]; + uchar tempo, speed, common_flag; +} tOLD_FIXED_SONGDATA; + + +typedef struct tOLD_CHUNK { + uchar note, instr_def, effect_def, effect; +} tOLD_CHUNK; + + +typedef tADTRACK2_EVENT tCHUNK; + + +typedef tOLD_CHUNK tOLD_VARIABLE_DATA1[0x10][0x40][9]; + + +typedef tOLD_CHUNK tOLD_VARIABLE_DATA2[8][18][0x40]; + + +typedef long tByteSet[9]; + + +#define INSTRUMENT_SIZE (sizeof(tADTRACK2_INS)) +#define CHUNK_SIZE (sizeof(tADTRACK2_EVENT)) +#define PATTERN_SIZE (CHUNK_SIZE * 5120) + + +typedef struct tDECAY_BAR { + short dir; + double lvl, max_lvl; +} tDECAY_BAR; + + +extern unsigned short opl3port; +extern short error_code; +extern uchar current_order, current_pattern, current_line, tempo, speed; +extern unsigned short macro_speedup; +extern boolean irq_mode; +extern uchar max_patterns; +extern boolean fast_forward; +extern uchar overall_volume, global_volume; +extern unsigned short song_timer, song_timer_tenths; + +vextern unsigned short timer_temp, timer_det; +vextern long ticks, tick0, tickD, tickXF; +vextern boolean limit_exceeded; + +vextern double time_playing; +vextern tVARIABLE_DATA *pattdata; +vextern tFIXED_SONGDATA songdata; +vextern tOLD_FIXED_SONGDATA old_songdata; +vextern tOLD_VARIABLE_DATA1 old_hash_buffer; +vextern tOLD_VARIABLE_DATA2 hash_buffer; +vextern uchar buffer[sizeof(tVARIABLE_DATA)]; +extern Void (*external_irq_hook) PV(); +extern long _delay_counter; +extern unsigned short irq_freq; +extern boolean irq_initialized, timer_fix, pattern_break, pattern_delay; +extern uchar next_line; +extern tPLAY_STATUS play_status; +extern boolean replay_forbidden, force_macro_keyon; +vextern tDECAY_BAR decay_bar[96]; + + +extern Void start_playing PV(); +extern Void set_overall_volume PP((int level)); +extern Void stop_playing PV(); +extern Void init_old_songdata PV(); +extern Void init_songdata PV(); +extern Void init_irq PV(); +extern Void done_irq PV(); +extern Void get_chunk PP((int pattern, int line, int channel, + tADTRACK2_EVENT *chunk)); +extern Void put_chunk PP((int pattern, int line, int channel, + tADTRACK2_EVENT chunk)); +extern Void count_order PP((uchar *entries)); +extern Void timer_poll_proc PV(); +extern Void opl3exp PP((int data)); + +extern short calc_following_order PP((int order)); +extern Char *asciiz_string PP((Char *Result, Char *str)); + + +#undef vextern + +#endif /*A2PLAYER_H*/ + +/* End. */ diff --git a/16/ADT2PLAY/a2player.pas b/16/ADT2PLAY/a2player.pas new file mode 100644 index 00000000..caed7aba --- /dev/null +++ b/16/ADT2PLAY/a2player.pas @@ -0,0 +1,4590 @@ +unit A2player; +interface + +const + MAX_IRQ_FREQ = 1000; + +{$i typconst.inc} + +const + ef_Arpeggio = 0; + ef_FSlideUp = 1; + ef_FSlideDown = 2; + ef_TonePortamento = 3; + ef_Vibrato = 4; + ef_TPortamVolSlide = 5; + ef_VibratoVolSlide = 6; + ef_FSlideUpFine = 7; + ef_FSlideDownFine = 8; + ef_SetModulatorVol = 9; + ef_VolSlide = 10; + ef_PositionJump = 11; + ef_SetInsVolume = 12; + ef_PatternBreak = 13; + ef_SetTempo = 14; + ef_SetSpeed = 15; + ef_TPortamVSlideFine = 16; + ef_VibratoVSlideFine = 17; + ef_SetCarrierVol = 18; + ef_SetWaveform = 19; + ef_VolSlideFine = 20; + ef_RetrigNote = 21; + ef_Tremolo = 22; + ef_Tremor = 23; + ef_ArpggVSlide = 24; + ef_ArpggVSlideFine = 25; + ef_MultiRetrigNote = 26; + ef_FSlideUpVSlide = 27; + ef_FSlideDownVSlide = 28; + ef_FSlUpFineVSlide = 29; + ef_FSlDownFineVSlide = 30; + ef_FSlUpVSlF = 31; + ef_FSlDownVSlF = 32; + ef_FSlUpFineVSlF = 33; + ef_FSlDownFineVSlF = 34; + ef_Extended = 35; + ef_Extended2 = 36; + ef_SetGlobalVolume = 37; + ef_SwapArpeggio = 38; + ef_SwapVibrato = 39; + ef_ForceInsVolume = 40; + ef_Extended3 = 41; + ef_ExtraFineArpeggio = 42; + ef_ExtraFineVibrato = 43; + ef_ExtraFineTremolo = 44; + ef_SetCustomSpeedTab = 45; + ef_GlobalFSlideUp = 46; + ef_GlobalFSlideDown = 47; + ef_ex_SetTremDepth = 0; + ef_ex_SetVibDepth = 1; + ef_ex_SetAttckRateM = 2; + ef_ex_SetDecayRateM = 3; + ef_ex_SetSustnLevelM = 4; + ef_ex_SetRelRateM = 5; + ef_ex_SetAttckRateC = 6; + ef_ex_SetDecayRateC = 7; + ef_ex_SetSustnLevelC = 8; + ef_ex_SetRelRateC = 9; + ef_ex_SetFeedback = 10; + ef_ex_SetPanningPos = 11; + ef_ex_PatternLoop = 12; + ef_ex_PatternLoopRec = 13; + ef_ex_MacroKOffLoop = 14; + ef_ex_ExtendedCmd = 15; + ef_ex_cmd_RSS = 0; + ef_ex_cmd_ResetVol = 1; + ef_ex_cmd_LockVol = 2; + ef_ex_cmd_UnlockVol = 3; + ef_ex_cmd_LockVP = 4; + ef_ex_cmd_UnlockVP = 5; + ef_ex_cmd_VSlide_mod = 6; + ef_ex_cmd_VSlide_car = 7; + ef_ex_cmd_VSlide_def = 8; + ef_ex_cmd_LockPan = 9; + ef_ex_cmd_UnlockPan = 10; + ef_ex_cmd_VibrOff = 11; + ef_ex_cmd_TremOff = 12; + ef_ex_cmd_FVib_FGFS = 13; + ef_ex_cmd_FTrm_XFGFS = 14; + ef_ex_cmd_NoRestart = 15; + ef_ex2_PatDelayFrame = 0; + ef_ex2_PatDelayRow = 1; + ef_ex2_NoteDelay = 2; + ef_ex2_NoteCut = 3; + ef_ex2_FineTuneUp = 4; + ef_ex2_FineTuneDown = 5; + ef_ex2_GlVolSlideUp = 6; + ef_ex2_GlVolSlideDn = 7; + ef_ex2_GlVolSlideUpF = 8; + ef_ex2_GlVolSlideDnF = 9; + ef_ex2_GlVolSldUpXF = 10; + ef_ex2_GlVolSldDnXF = 11; + ef_ex2_VolSlideUpXF = 12; + ef_ex2_VolSlideDnXF = 13; + ef_ex2_FreqSlideUpXF = 14; + ef_ex2_FreqSlideDnXF = 15; + ef_ex3_SetConnection = 0; + ef_ex3_SetMultipM = 1; + ef_ex3_SetKslM = 2; + ef_ex3_SetTremoloM = 3; + ef_ex3_SetVibratoM = 4; + ef_ex3_SetKsrM = 5; + ef_ex3_SetSustainM = 6; + ef_ex3_SetMultipC = 7; + ef_ex3_SetKslC = 8; + ef_ex3_SetTremoloC = 9; + ef_ex3_SetVibratoC = 10; + ef_ex3_SetKsrC = 11; + ef_ex3_SetSustainC = 12; + +const + ef_fix1 = $80; + ef_fix2 = $90; + +const + opl3port: Word = $388; + error_code: Integer = 0; + current_order: Byte = 0; + current_pattern: Byte = 0; + current_line: Byte = 0; + tempo: Byte = 50; + speed: Byte = 6; + macro_speedup: Word = 1; + irq_mode: Boolean = FALSE; + max_patterns: Byte = 128; + fast_forward: Boolean = FALSE; + overall_volume: Byte = 63; + global_volume: Byte = 63; + +const + song_timer: Word = 0; + song_timer_tenths: Word = 0; + +var + timer_temp,timer_det: Word; + ticks,tick0,tickD, + tickXF: Longint; + limit_exceeded: Boolean; + +type + tFM_INST_DATA = Record + AM_VIB_EG_modulator, + AM_VIB_EG_carrier, + KSL_VOLUM_modulator, + KSL_VOLUM_carrier, + ATTCK_DEC_modulator, + ATTCK_DEC_carrier, + SUSTN_REL_modulator, + SUSTN_REL_carrier, + WAVEFORM_modulator, + WAVEFORM_carrier, + FEEDBACK_FM: Byte; + end; +type + tADTRACK2_INS = Record + fm_data: tFM_INST_DATA; + panning: Byte; + fine_tune: Shortint; + perc_voice: Byte; + end; +type + tARPEGGIO_TABLE = Record + length, + speed, + loop_begin, + loop_length, + keyoff_pos: Byte; + data: array[1..255] of Byte; + end; +type + tVIBRATO_TABLE = Record + length, + speed, + delay, + loop_begin, + loop_length, + keyoff_pos: Byte; + data: array[1..255] of Shortint; + end; +type + tREGISTER_TABLE_DEF = Record + fm_data: tFM_INST_DATA; + freq_slide: Smallint; + panning: Byte; + duration: Byte; + end; +type + tREGISTER_TABLE = Record + length, + loop_begin, + loop_length, + keyoff_pos, + arpeggio_table, + vibrato_table: Byte; + data: array[1..255] of tREGISTER_TABLE_DEF; + end; +type + tMACRO_TABLE = Record + arpeggio: tARPEGGIO_TABLE; + vibrato: tVIBRATO_TABLE; + end; +type + tFM_PARAMETER_TABLE = Record + adsrw_car, + adsrw_mod: Record + attck,dec,sustn,rel, + wform: Byte; + end; + connect, + feedb, + multipM,kslM,tremM,vibrM,ksrM,sustM, + multipC,kslC,tremC,vibrC,ksrC,sustC: Byte; + end; +type + tADTRACK2_EVENT = Record + note, + instr_def, + effect_def, + effect, + effect_def2, + effect2: Byte; + end; + +type + tDIS_FMREG_COL = array[0..27] of Boolean; + +type + tFIXED_SONGDATA = Record + songname: String[42]; + composer: String[42]; + instr_names: array[1..255] of String[42]; + instr_data: array[1..255] of tADTRACK2_INS; + instr_macros: array[1..255] of tREGISTER_TABLE; + macro_table: array[1..255] of tMACRO_TABLE; + pattern_order: array[0..$7f] of Byte; + tempo: Byte; + speed: Byte; + common_flag: Byte; + patt_len: Word; + nm_tracks: Byte; + macro_speedup: Word; + flag_4op: Byte; + lock_flags: array[1..20] of Byte; + pattern_names: array[0..$7f] of String[42]; + dis_fmreg_col: array[1..255] of tDIS_FMREG_COL; + end; +type + tPLAY_STATUS = (isPlaying,isPaused,isStopped); + +type + tVARIABLE_DATA = array[0..7] of + array[1..20] of + array[0..$0ff] of tADTRACK2_EVENT; +type + tPATTERN_DATA = array[0..15] of tVARIABLE_DATA; + +type + tDUMMY_BUFF = array[0..PRED(655350)] of Byte; + +type + tOLD_ADTRACK2_INS = Record + fm_data: tFM_INST_DATA; + panning: Byte; + fine_tune: Shortint; + end; +type + pOLD_FIXED_SONGDATA = ^tOLD_FIXED_SONGDATA; + tOLD_FIXED_SONGDATA = Record + songname: String[42]; + composer: String[42]; + instr_names: array[1..250] of String[32]; + instr_data: array[1..250] of tOLD_ADTRACK2_INS; + pattern_order: array[0..$7f] of Byte; + tempo: Byte; + speed: Byte; + common_flag: Byte; + end; +type + tOLD_CHUNK = Record + note: Byte; + instr_def: Byte; + effect_def: Byte; + effect: Byte; + end; +type + tCHUNK = tADTRACK2_EVENT; + +type + tOLD_VARIABLE_DATA1 = array[0..$0f] of array[0..$3f] of + array[1..9] of tOLD_CHUNK; +type + tOLD_VARIABLE_DATA2 = array[0..7] of array[1..18] of + array[0..$3f] of tOLD_CHUNK; +type + tByteSet = Set of Byte; + +const + INSTRUMENT_SIZE = SizeOf(tADTRACK2_INS); + CHUNK_SIZE = SizeOf(tCHUNK); + PATTERN_SIZE = 20*256*CHUNK_SIZE; + +var + time_playing: Real; + pattdata: ^tPATTERN_DATA; + songdata: tFIXED_SONGDATA; + old_songdata: tOLD_FIXED_SONGDATA; + old_hash_buffer: tOLD_VARIABLE_DATA1; + hash_buffer: tOLD_VARIABLE_DATA2; + buffer: array[0..PRED(SizeOf(tVARIABLE_DATA))] of Byte; + +const + external_irq_hook: procedure = NIL; + _delay_counter: Longint = 0; + irq_freq: Word = 50; + irq_initialized: Boolean = FALSE; + timer_fix: Boolean = TRUE; + pattern_break: Boolean = FALSE; + pattern_delay: Boolean = FALSE; + next_line: Byte = 0; + play_status: tPLAY_STATUS = isStopped; + replay_forbidden: Boolean = TRUE; + force_macro_keyon: Boolean = FALSE; + +type + tDECAY_BAR = Record + dir: Integer; + lvl,max_lvl: Real; + end; +var + decay_bar: array[1..96] of tDECAY_BAR; + +procedure start_playing; +procedure set_overall_volume(level: Byte); +procedure stop_playing; +procedure init_old_songdata; +procedure init_songdata; +procedure init_irq; +procedure done_irq; +procedure get_chunk(pattern,line,channel: Byte; var chunk: tADTRACK2_EVENT); +procedure put_chunk(pattern,line,channel: Byte; chunk: tADTRACK2_EVENT); +procedure count_order(var entries: Byte); +procedure timer_poll_proc; +procedure opl3exp(data: Word); + +function calc_following_order(order: Byte): Integer; +function asciiz_string(str: String): String; + +implementation +uses DOS,TimerInt,ParserIO; + +const + _panning: array[0..2] of Byte = ($30,$10,$20); + +const + _instr: array[0..11] of Byte = ($20, $20, + $40, $40, + $60, $60, + $80, $80, + $0e0,$0e0, + $0c0, + $0bd); +type + tTRACK_ADDR = array[1..20] of Word; + +const { 01 - 02 - 03 - 04 - 05 - 06 - 07 - 08 - 09 - 10 - 11 - 12 - 13 - 14 - 15 - 16 - 17 - 18 - 19 - 20 } + _chmm_n: tTRACK_ADDR = ($003,$000,$004,$001,$005,$002,$006,$007,$008,$103,$100,$104,$101,$105,$102,$106,$107,$108,BYTE_NULL,BYTE_NULL); + _chmm_m: tTRACK_ADDR = ($008,$000,$009,$001,$00a,$002,$010,$011,$012,$108,$100,$109,$101,$10a,$102,$110,$111,$112,BYTE_NULL,BYTE_NULL); + _chmm_c: tTRACK_ADDR = ($00b,$003,$00c,$004,$00d,$005,$013,$014,$015,$10b,$103,$10c,$104,$10d,$105,$113,$114,$115,BYTE_NULL,BYTE_NULL); + { BD SD TT TC HH } + _chpm_n: tTRACK_ADDR = ($003,$000,$004,$001,$005,$002,$106,$107,$108,$103,$100,$104,$101,$105,$102,$006,$007,$008,$008,$007); + _chpm_m: tTRACK_ADDR = ($008,$000,$009,$001,$00a,$002,$110,$111,$112,$108,$100,$109,$101,$10a,$102,$010,$014,$012,$015,$011); + _chpm_c: tTRACK_ADDR = ($00b,$003,$00c,$004,$00d,$005,$113,$114,$115,$10b,$103,$10c,$104,$10d,$105,$013,BYTE_NULL,BYTE_NULL,BYTE_NULL,BYTE_NULL); + +var + _chan_n: tTRACK_ADDR; + _chan_m: tTRACK_ADDR; + _chan_c: tTRACK_ADDR; + +const + keyoff_flag = $080; + fixed_note_flag = $090; + pattern_loop_flag = $0e0; + pattern_break_flag = $0f0; + +const + def_vibtrem_speed_factor: Byte = 1; + def_vibtrem_table_size: Byte = 32; + def_vibtrem_table: array[0..255] of Byte = ( + 0,24,49,74,97,120,141,161,180,197,212,224,235,244,250,253,255, + 253,250,244,235,224,212,197,180,161,141,120,97,74,49,24, + 0,24,49,74,97,120,141,161,180,197,212,224,235,244,250,253,255, + 253,250,244,235,224,212,197,180,161,141,120,97,74,49,24, + 0,24,49,74,97,120,141,161,180,197,212,224,235,244,250,253,255, + 253,250,244,235,224,212,197,180,161,141,120,97,74,49,24, + 0,24,49,74,97,120,141,161,180,197,212,224,235,244,250,253,255, + 253,250,244,235,224,212,197,180,161,141,120,97,74,49,24, + 0,24,49,74,97,120,141,161,180,197,212,224,235,244,250,253,255, + 253,250,244,235,224,212,197,180,161,141,120,97,74,49,24, + 0,24,49,74,97,120,141,161,180,197,212,224,235,244,250,253,255, + 253,250,244,235,224,212,197,180,161,141,120,97,74,49,24, + 0,24,49,74,97,120,141,161,180,197,212,224,235,244,250,253,255, + 253,250,244,235,224,212,197,180,161,141,120,97,74,49,24, + 0,24,49,74,97,120,141,161,180,197,212,224,235,244,250,253,255, + 253,250,244,235,224,212,197,180,161,141,120,97,74,49,24); + +var + vibtrem_speed_factor: Byte; + vibtrem_table_size: Byte; + vibtrem_table: array[0..255] of Byte; + +var + fmpar_table: array[1..20] of tFM_PARAMETER_TABLE; + volume_lock: array[1..20] of Boolean; + volume_table: array[1..20] of Word; + vscale_table: array[1..20] of Word; + peak_lock: array[1..20] of Boolean; + pan_lock: array[1..20] of Boolean; + event_table: array[1..20] of tADTRACK2_EVENT; + voice_table: array[1..20] of Byte; + modulator_vol: array[1..20] of Byte; + carrier_vol: array[1..20] of Byte; + freq_table: array[1..20] of Word; + effect_table: array[1..20] of Word; + effect_table2: array[1..20] of Word; + fslide_table: array[1..20] of Byte; + fslide_table2: array[1..20] of Byte; + glfsld_table: array[1..20] of Word; + glfsld_table2: array[1..20] of Word; + porta_table: array[1..20] of Record freq: Word; speed: Byte; end; + porta_table2: array[1..20] of Record freq: Word; speed: Byte; end; + arpgg_table: array[1..20] of Record state,note,add1,add2: Byte; end; + arpgg_table2: array[1..20] of Record state,note,add1,add2: Byte; end; + vibr_table: array[1..20] of Record pos,speed,depth: Byte; fine: Boolean; end; + vibr_table2: array[1..20] of Record pos,speed,depth: Byte; fine: Boolean; end; + trem_table: array[1..20] of Record pos,speed,depth: Byte; fine: Boolean; end; + trem_table2: array[1..20] of Record pos,speed,depth: Byte; fine: Boolean; end; + retrig_table: array[1..20] of Byte; + retrig_table2: array[1..20] of Byte; + tremor_table: array[1..20] of Record pos: Integer; volume: Word; end; + tremor_table2: array[1..20] of Record pos: Integer; volume: Word; end; + panning_table: array[1..20] of Byte; + last_effect: array[1..20] of Word; + last_effect2: array[1..20] of Word; + volslide_type: array[1..20] of Byte; + event_new: array[1..20] of Boolean; + notedel_table: array[1..20] of Byte; + notecut_table: array[1..20] of Byte; + ftune_table: array[1..20] of Shortint; + keyoff_loop: array[1..20] of Boolean; + macro_table: array[1..20] of Record + fmreg_pos,arpg_pos,vib_pos: Word; + fmreg_count,fmreg_duration,arpg_count, + vib_count,vib_delay: Byte; + vib_paused: Boolean; + fmreg_table,arpg_table,vib_table: Byte; + arpg_note: Byte; + vib_freq: Word; + end; + + loopbck_table: array[1..20] of Byte; + loop_table: array[1..20,0..255] of Byte; + misc_register: Byte; + +const + current_tremolo_depth: Byte = 0; + current_vibrato_depth: Byte = 0; + +var + speed_update,lockvol,panlock,lockVP: Boolean; + tremolo_depth,vibrato_depth: Byte; + volume_scaling,percussion_mode: Boolean; + last_order: Byte; + reset_chan: array[1..20] of Boolean; + +procedure opl2out(reg,data: Word); assembler; +asm + mov ax,reg + mov dx,word ptr [opl3port] + or ah,ah + jz @@1 + add dx,2 +@@1: out dx,al + mov ecx,6 +@@2: in al,dx + loop @@2 + inc dl + mov ax,data + out dx,al + dec dl + mov ecx,36 +@@3: in al,dx + loop @@3 +end; + +procedure opl3out(reg,data: Word); assembler; +asm + mov ax,reg + mov dx,word ptr [opl3port] + or ah,ah + jz @@1 + add dx,2 +@@1: out dx,al + inc dl + mov ax,data + out dx,al + dec dl + mov ecx,26 +@@2: in al,dx + loop @@2 +end; + +procedure opl3exp(data: Word); assembler; +asm + mov ax,data + mov dx,word ptr [opl3port] + add dx,2 + out dx,al + mov ecx,6 +@@1: in al,dx + loop @@1 + inc dl + mov al,ah + out dx,al + mov ecx,36 +@@2: in al,dx + loop @@2 +end; + +const + FreqStart = $156; + FreqEnd = $2ae; + FreqRange = FreqEnd-FreqStart; + +function nFreq(note: Byte): Word; assembler; + +const + Fnum: array[0..11] of Word = ( + $157,$16b,$181,$198,$1b0,$1ca,$1e5,$202,$220,$241,$263,$287); + +asm + push ebx + push ecx + xor ebx,ebx + mov al,[note] + xor ah,ah + cmp ax,12*8 + jae @@1 + push eax + mov bl,12 + div bl + mov bl,ah + xor bh,bh + shl bx,1 + pop eax + mov cl,12 + div cl + xor ah,ah + shl ax,10 + add ax,word ptr [Fnum+ebx] + jmp @@2 +@@1: mov ax,7 + shl ax,10 + add ax,FreqEnd +@@2: pop ecx + pop ebx +end; + +function calc_freq_shift_up(freq,shift: Word): Word; assembler; +asm + push ebx + push ecx + push edx + mov cx,freq + mov ax,shift + mov bx,cx + and bx,0000001111111111b + mov dx,cx + and dx,0001110000000000b + add bx,ax + and cx,1110000000000000b + shr dx,10 + cmp bx,FreqEnd + jb @@2 + cmp dx,7 + jnz @@1 + mov bx,FreqEnd + jmp @@2 +@@1: sub bx,FreqRange + inc dx +@@2: mov ax,cx + shl dx,10 + add ax,dx + add ax,bx + pop edx + pop ecx + pop ebx +end; + +function calc_freq_shift_down(freq,shift: Word): Word; assembler; +asm + push ebx + push ecx + push edx + mov cx,freq + mov ax,shift + mov bx,cx + and bx,0000001111111111b + mov dx,cx + and dx,0001110000000000b + sub bx,ax + and cx,1110000000000000b + shr dx,10 + cmp bx,FreqStart + ja @@2 + or dx,dx + jnz @@1 + mov bx,FreqStart + jmp @@2 +@@1: add bx,FreqRange + dec dx +@@2: mov ax,cx + shl dx,10 + add ax,dx + add ax,bx + pop edx + pop ecx + pop ebx +end; + +function calc_vibtrem_shift(depth,position: Byte; + var direction: Byte): Word; assembler; +asm + push ebx + push ecx + push edx + push edi + xor ebx,ebx + mov al,depth + xor ah,ah + mov bl,position + xor bh,bh + mov dh,bl + mov cl,vibtrem_table_size + dec cl + and bl,cl + lea edi,[vibtrem_table] + add edi,ebx + mov dl,byte ptr [edi] + mul dl + rol ax,1 + xchg ah,al + and ah,1 + mov ebx,[direction] + mov cl,1 + mov [ebx],cl + mov dl,vibtrem_table_size + test dh,dl + jne @@1 + mov cl,0 + mov [ebx],cl +@@1: pop edi + pop edx + pop ecx + pop ebx +end; + +procedure change_freq(chan: Byte; freq: Word); assembler; +asm + push ebx + push edx + xor ebx,ebx + mov bl,chan + dec ebx + shl ebx,1 + mov ax,freq + and ax,1fffh + mov dx,word ptr [freq_table+ebx] + and dx,NOT 1fffh + add ax,dx + mov word ptr [freq_table+ebx],ax + xor edx,edx + mov dx,word ptr [_chan_n+ebx] + add dx,0a0h + push edx + xor edx,edx + mov dl,al + push edx + mov dx,word ptr [_chan_n+ebx] + add dx,0b0h + push edx + xor edx,edx + mov dl,ah + push edx + call opl3out + call opl3out + pop edx + pop ebx +end; + +function ins_parameter(ins,param: Byte): Byte; assembler; +asm + push ebx + push esi + xor ebx,ebx + lea esi,[songdata.instr_data] + mov bl,ins + dec ebx + mov eax,INSTRUMENT_SIZE + mul ebx + add esi,eax + mov bl,param + add esi,ebx + lodsb + pop esi + pop ebx +end; + +function min(value: Word; minimum: Word): Word; assembler; +asm + mov ax,value + cmp ax,minimum + jae @@1 + mov ax,minimum +@@1: +end; + +function max(value: Word; maximum: Word): Word; assembler; +asm + mov ax,value + cmp ax,maximum + jbe @@1 + mov ax,maximum +@@1: +end; + +function asciiz_string(str: String): String; +begin + If (Pos(#0,str) <> 0) then asciiz_string := Copy(str,1,Pos(#0,str)-1) + else asciiz_string := ''; +end; + +function concw(lo,hi: Byte): Word; +begin + concw := lo+(hi SHL 8); +end; + +procedure synchronize_song_timer; +begin + song_timer := TRUNC(time_playing); + song_timer_tenths := TRUNC(time_playing*100) MOD 100; + timer_temp := song_timer_tenths; +end; + +procedure change_frequency(chan: Byte; freq: Word); +begin + macro_table[chan].vib_paused := TRUE; + change_freq(chan,freq); + macro_table[chan].vib_count := 1; + macro_table[chan].vib_pos := 0; + macro_table[chan].vib_freq := freq; + macro_table[chan].vib_paused := FALSE; +end; + +function _macro_speedup: Word; assembler; +asm + mov ax,macro_speedup + or ax,ax + jnz @@1 + inc ax +@@1: +end; + +procedure update_timer(Hz: Longint); +begin + _debug_str_ := 'A2PLAYER.PAS:update_timer'; + If (Hz = 0) then begin TimerSetup(18); EXIT end + else tempo := Hz; + If (tempo = 18) and timer_fix then IRQ_freq := TRUNC((tempo+0.2)*20) + else IRQ_freq := 250; + While (IRQ_freq MOD (tempo*_macro_speedup) <> 0) do Inc(IRQ_freq); + If (IRQ_freq > MAX_IRQ_FREQ) then IRQ_freq := MAX_IRQ_FREQ; + TimerSetup(IRQ_freq); +end; + +procedure key_off(chan: Byte); +begin + freq_table[chan] := LO(freq_table[chan])+ + (HI(freq_table[chan]) AND NOT $20) SHL 8; + change_freq(chan,freq_table[chan]); + event_table[chan].note := event_table[chan].note OR keyoff_flag; +end; + +procedure release_sustaining_sound(chan: Byte); +begin + opl3out(_instr[02]+_chan_m[chan],63); + opl3out(_instr[03]+_chan_c[chan],63); + + FillChar(fmpar_table[chan].adsrw_car, + SizeOf(fmpar_table[chan].adsrw_car),0); + FillChar(fmpar_table[chan].adsrw_mod, + SizeOf(fmpar_table[chan].adsrw_mod),0); + + opl3out($0b0+_chan_n[chan],0); + opl3out(_instr[04]+_chan_m[chan],BYTE_NULL); + opl3out(_instr[05]+_chan_c[chan],BYTE_NULL); + opl3out(_instr[06]+_chan_m[chan],BYTE_NULL); + opl3out(_instr[07]+_chan_c[chan],BYTE_NULL); + + key_off(chan); + event_table[chan].instr_def := 0; + reset_chan[chan] := TRUE; +end; + +function scale_volume(volume,scale_factor: Byte): Byte; +begin + scale_volume := 63-Round((63-volume)/63* + (63-scale_factor)); +end; + +procedure set_ins_volume(modulator,carrier,chan: Byte); + +var + temp: Byte; + +begin +{$IFNDEF __TMT__} + // ** OPL3 emulation workaround ** + // force muted instrument volume with missing ADSR instrument data + // when there is additionally no FM-reg macro defined for the instrument + If is_ins_adsr_data_empty(voice_table[chan]) and + NOT (songdata.instr_macros[voice_table[chan]].length <> 0) and + NOT replay_forbidden then + begin + modulator := 63; + carrier := 63; + end; +{$ENDIF} + + If (modulator <> BYTE_NULL) then + begin + temp := modulator; + If volume_scaling then + If (ins_parameter(voice_table[chan],10) AND 1 = 1) or + (percussion_mode and (chan in [17..20])) then + modulator := scale_volume(ins_parameter(voice_table[chan],2) AND $3f,modulator); + If (ins_parameter(voice_table[chan],10) AND 1 = 1) or + (percussion_mode and (chan in [17..20])) then + opl3out(_instr[02]+_chan_m[chan], + scale_volume(scale_volume(modulator,63-global_volume),63-overall_volume)+LO(vscale_table[chan])) + else + opl3out(_instr[02]+_chan_m[chan], + temp+LO(vscale_table[chan])); + volume_table[chan] := concw(temp,HI(volume_table[chan])); + If (ins_parameter(voice_table[chan],10) AND 1 = 1) or + (percussion_mode and (chan in [17..20])) then + modulator_vol[chan] := 63-scale_volume(modulator,63-global_volume) + else modulator_vol[chan] := 63-modulator; + end; + + If (carrier <> BYTE_NULL) then + begin + temp := carrier; + If volume_scaling then + carrier := scale_volume(ins_parameter(voice_table[chan],3) AND $3f,carrier); + opl3out(_instr[03]+_chan_c[chan], + scale_volume(scale_volume(carrier,63-global_volume),63-overall_volume)+HI(vscale_table[chan])); + volume_table[chan] := concw(LO(volume_table[chan]),temp); + carrier_vol[chan] := 63-scale_volume(carrier,63-global_volume); + end; +end; + +procedure reset_ins_volume(chan: Byte); +begin + If NOT volume_scaling then + set_ins_volume(ins_parameter(voice_table[chan],2) AND $3f, + ins_parameter(voice_table[chan],3) AND $3f,chan) + else If (ins_parameter(voice_table[chan],10) AND 1 = 0) then + set_ins_volume(ins_parameter(voice_table[chan],2) AND $3f,0,chan) + else set_ins_volume(0,0,chan); +end; + +procedure set_global_volume; + +var + chan: Byte; + +begin + For chan := 1 to songdata.nm_tracks do + If NOT ((carrier_vol[chan] = 0) and + (modulator_vol[chan] = 0)) then + If (ins_parameter(voice_table[chan],10) AND 1 = 0) then + set_ins_volume(BYTE_NULL,HI(volume_table[chan]),chan) + else set_ins_volume(LO(volume_table[chan]),HI(volume_table[chan]),chan); +end; + +procedure set_overall_volume(level: Byte); +begin + overall_volume := max(level,63); + set_global_volume; +end; + +procedure init_macro_table(chan,note,ins: Byte; freq: Word); +begin + macro_table[chan].fmreg_count := 1; + macro_table[chan].fmreg_pos := 0; + macro_table[chan].fmreg_duration := 0; + macro_table[chan].fmreg_table := ins; + macro_table[chan].arpg_count := 1; + macro_table[chan].arpg_pos := 0; + macro_table[chan].arpg_table := songdata.instr_macros[ins].arpeggio_table; + macro_table[chan].arpg_note := note; + macro_table[chan].vib_count := 1; + macro_table[chan].vib_paused := FALSE; + macro_table[chan].vib_pos := 0; + macro_table[chan].vib_table := songdata.instr_macros[ins].vibrato_table; + macro_table[chan].vib_freq := freq; + macro_table[chan].vib_delay := songdata.macro_table[macro_table[chan].vib_table].vibrato.delay; +end; + +procedure set_ins_data(ins,chan: Byte); + +var + old_ins: Byte; + +begin + If (ins <> event_table[chan].instr_def) or reset_chan[chan] then + begin + opl3out(_instr[02]+_chan_m[chan],63); + opl3out(_instr[03]+_chan_c[chan],63); + + If NOT pan_lock[chan] then + panning_table[chan] := ins_parameter(ins,11) + else panning_table[chan] := songdata.lock_flags[chan] AND 3; + + opl3out(_instr[00]+_chan_m[chan],ins_parameter(ins,0)); + opl3out(_instr[01]+_chan_c[chan],ins_parameter(ins,1)); + opl3out(_instr[04]+_chan_m[chan],ins_parameter(ins,4)); + opl3out(_instr[05]+_chan_c[chan],ins_parameter(ins,5)); + opl3out(_instr[06]+_chan_m[chan],ins_parameter(ins,6)); + opl3out(_instr[07]+_chan_c[chan],ins_parameter(ins,7)); + opl3out(_instr[08]+_chan_m[chan],ins_parameter(ins,8)); + opl3out(_instr[09]+_chan_c[chan],ins_parameter(ins,9)); + opl3out(_instr[10]+_chan_n[chan],ins_parameter(ins,10) OR _panning[panning_table[chan]]); + + fmpar_table[chan].connect := ins_parameter(ins,10) AND 1; + fmpar_table[chan].feedb := ins_parameter(ins,10) SHR 1 AND 7; + fmpar_table[chan].multipM := ins_parameter(ins,0) AND $0f; + fmpar_table[chan].kslM := ins_parameter(ins,2) SHR 6; + fmpar_table[chan].tremM := ins_parameter(ins,0) SHR 7; + fmpar_table[chan].vibrM := ins_parameter(ins,0) SHR 6 AND 1; + fmpar_table[chan].ksrM := ins_parameter(ins,0) SHR 4 AND 1; + fmpar_table[chan].sustM := ins_parameter(ins,0) SHR 5 AND 1; + fmpar_table[chan].multipC := ins_parameter(ins,1) AND $0f; + fmpar_table[chan].kslC := ins_parameter(ins,3) SHR 6; + fmpar_table[chan].tremC := ins_parameter(ins,1) SHR 7; + fmpar_table[chan].vibrC := ins_parameter(ins,1) SHR 6 AND 1; + fmpar_table[chan].ksrC := ins_parameter(ins,1) SHR 4 AND 1; + fmpar_table[chan].sustC := ins_parameter(ins,1) SHR 5 AND 1; + + fmpar_table[chan].adsrw_car.attck := ins_parameter(ins,5) SHR 4; + fmpar_table[chan].adsrw_mod.attck := ins_parameter(ins,4) SHR 4; + fmpar_table[chan].adsrw_car.dec := ins_parameter(ins,5) AND $0f; + fmpar_table[chan].adsrw_mod.dec := ins_parameter(ins,4) AND $0f; + fmpar_table[chan].adsrw_car.sustn := ins_parameter(ins,7) SHR 4; + fmpar_table[chan].adsrw_mod.sustn := ins_parameter(ins,6) SHR 4; + fmpar_table[chan].adsrw_car.rel := ins_parameter(ins,7) AND $0f; + fmpar_table[chan].adsrw_mod.rel := ins_parameter(ins,6) AND $0f; + fmpar_table[chan].adsrw_car.wform := ins_parameter(ins,9) AND $07; + fmpar_table[chan].adsrw_mod.wform := ins_parameter(ins,8) AND $07; + + If NOT reset_chan[chan] then + keyoff_loop[chan] := FALSE; + + If reset_chan[chan] then + begin + voice_table[chan] := ins; + reset_ins_volume(chan); + reset_chan[chan] := FALSE; + end; + + If (event_table[chan].note AND $7f in [1..12*8+1]) then + init_macro_table(chan,event_table[chan].note AND $7f,ins,freq_table[chan]) + else init_macro_table(chan,0,ins,freq_table[chan]); + end; + + vscale_table[chan] := concw(fmpar_table[chan].kslM SHL 6, + fmpar_table[chan].kslC SHL 6); + voice_table[chan] := ins; + old_ins := event_table[chan].instr_def; + event_table[chan].instr_def := ins; + + If NOT volume_lock[chan] or + (ins <> old_ins) then reset_ins_volume(chan); +end; + +procedure update_modulator_adsrw(chan: Byte); +begin + opl3out(_instr[04]+_chan_m[chan], + fmpar_table[chan].adsrw_mod.attck SHL 4+ + fmpar_table[chan].adsrw_mod.dec); + opl3out(_instr[06]+_chan_m[chan], + fmpar_table[chan].adsrw_mod.sustn SHL 4+ + fmpar_table[chan].adsrw_mod.rel); + opl3out(_instr[08]+_chan_m[chan], + fmpar_table[chan].adsrw_mod.wform); +end; + +procedure update_carrier_adsrw(chan: Byte); +begin + opl3out(_instr[05]+_chan_c[chan], + fmpar_table[chan].adsrw_car.attck SHL 4+ + fmpar_table[chan].adsrw_car.dec); + opl3out(_instr[07]+_chan_c[chan], + fmpar_table[chan].adsrw_car.sustn SHL 4+ + fmpar_table[chan].adsrw_car.rel); + opl3out(_instr[09]+_chan_c[chan], + fmpar_table[chan].adsrw_car.wform); +end; + +procedure update_fmpar(chan: Byte); +begin + opl3out(_instr[00]+_chan_m[chan],fmpar_table[chan].multipM+ + fmpar_table[chan].ksrM SHL 4+ + fmpar_table[chan].sustM SHL 5+ + fmpar_table[chan].vibrM SHL 6+ + fmpar_table[chan].tremM SHL 7); + opl3out(_instr[01]+_chan_c[chan],fmpar_table[chan].multipC+ + fmpar_table[chan].ksrC SHL 4+ + fmpar_table[chan].sustC SHL 5+ + fmpar_table[chan].vibrC SHL 6+ + fmpar_table[chan].tremC SHL 7); + + opl3out(_instr[10]+_chan_n[chan],(fmpar_table[chan].connect+ + fmpar_table[chan].feedb SHL 1) OR + _panning[panning_table[chan]]); + + vscale_table[chan] := concw(fmpar_table[chan].kslM SHL 6, + fmpar_table[chan].kslC SHL 6); + set_ins_volume(LO(volume_table[chan]), + HI(volume_table[chan]),chan); +end; + +function is_4op_chan(chan: Byte): Boolean; assembler; +asm + mov al,byte ptr [songdata.flag_4op] + mov ah,chan + test al,1 + jz @@1 + cmp ah,1 + jb @@1 + cmp ah,2 + ja @@1 + mov al,TRUE + jmp @@7 +@@1: test al,2 + jz @@2 + cmp ah,3 + jb @@2 + cmp ah,4 + ja @@2 + mov al,TRUE + jmp @@7 +@@2: test al,4 + jz @@3 + cmp ah,5 + jb @@3 + cmp ah,6 + ja @@3 + mov al,TRUE + jmp @@7 +@@3: test al,8 + jz @@4 + cmp ah,10 + jb @@4 + cmp ah,11 + ja @@4 + mov al,TRUE + jmp @@7 +@@4: test al,10h + jz @@5 + cmp ah,12 + jb @@5 + cmp ah,13 + ja @@5 + mov al,TRUE + jmp @@7 +@@5: test al,20h + jz @@6 + cmp ah,14 + jb @@6 + cmp ah,15 + ja @@6 + mov al,TRUE + jmp @@7 +@@6: mov al,FALSE +@@7: +end; + +procedure output_note(note,ins,chan: Byte; restart_macro: Boolean); + +var + pos: Byte; + freq: Word; + +begin + If (note = 0) and (ftune_table[chan] = 0) then EXIT; + If NOT (note in [1..12*8+1]) then freq := freq_table[chan] + else begin + freq := nFreq(note-1)+SHORTINT(ins_parameter(ins,12)); + If NOT (is_4op_chan(chan) and (chan in [1,3,5,10,12,14])) then + opl3out($0b0+_chan_n[chan],0); + + freq_table[chan] := concw(LO(freq_table[chan]), + HI(freq_table[chan]) OR $20); + + pos := Round(25/(12*8+1)*note); + If (decay_bar[pos].lvl <> 0) then + If (pos > 1) and + (decay_bar[pos-1].dir <> 1) then + Dec(pos) + else If (pos < 25) and + (decay_bar[pos+1].lvl <> 1) then + Inc(pos); + + If is_4op_chan(chan) then + If (chan in [2,4,6,11,13,15]) then + begin + decay_bar[pos].dir := 1; + If (ins_parameter(voice_table[chan],10) AND 1 = 0) then + decay_bar[pos].max_lvl := + (carrier_vol[PRED(chan)]+carrier_vol[chan]) DIV 2 + else decay_bar[pos].max_lvl := + (carrier_vol[PRED(chan)]+modulator_vol[PRED(chan)]+ + carrier_vol[chan]+modulator_vol[chan]) DIV 4; + end + else + else + begin + decay_bar[pos].dir := 1; + If (ins_parameter(voice_table[chan],10) AND 1 = 0) then + decay_bar[pos].max_lvl := + carrier_vol[chan] + else decay_bar[pos].max_lvl := + (carrier_vol[chan]+modulator_vol[chan]) DIV 2; + end; + end; + + If (ftune_table[chan] = -127) then ftune_table[chan] := 0; + freq := freq+ftune_table[chan]; + + If NOT (is_4op_chan(chan) and (chan in [1,3,5,10,12,14])) then + change_frequency(chan,freq); + + If (note <> 0) then + begin + event_table[chan].note := note; + If restart_macro then + With event_table[chan] do + If NOT (((effect_def = ef_Extended) and + (effect DIV 16 = ef_ex_ExtendedCmd) and + (effect MOD 16 = ef_ex_cmd_NoRestart)) or + ((effect_def2 = ef_Extended) and + (effect2 DIV 16 = ef_ex_ExtendedCmd) and + (effect2 MOD 16 = ef_ex_cmd_NoRestart))) then + init_macro_table(chan,note,ins,freq) + else macro_table[chan].arpg_note := note; + end; +end; + +procedure output_note_NR(note,ins,chan: Byte; restart_macro: Boolean); + +var + pos: Byte; + freq: Word; + +begin + If (note = 0) and (ftune_table[chan] = 0) then EXIT; + If NOT (note in [1..12*8+1]) then freq := freq_table[chan] + else begin + freq := nFreq(note-1)+SHORTINT(ins_parameter(ins,12)); + freq_table[chan] := concw(LO(freq_table[chan]), + HI(freq_table[chan]) OR $20); + + pos := Round(25/(12*8+1)*note); + If (decay_bar[pos].lvl <> 0) then + If (pos > 1) and + (decay_bar[pos-1].dir <> 1) then + Dec(pos) + else If (pos < 25) and + (decay_bar[pos+1].lvl <> 1) then + Inc(pos); + + If is_4op_chan(chan) then + If (chan in [2,4,6,11,13,15]) then + begin + decay_bar[pos].dir := 1; + If (ins_parameter(voice_table[chan],10) AND 1 = 0) then + decay_bar[pos].max_lvl := + (carrier_vol[PRED(chan)]+carrier_vol[chan]) DIV 2 + else decay_bar[pos].max_lvl := + (carrier_vol[PRED(chan)]+modulator_vol[PRED(chan)]+ + carrier_vol[chan]+modulator_vol[chan]) DIV 4; + end + else + else + begin + decay_bar[pos].dir := 1; + If (ins_parameter(voice_table[chan],10) AND 1 = 0) then + decay_bar[pos].max_lvl := + carrier_vol[chan] + else decay_bar[pos].max_lvl := + (carrier_vol[chan]+modulator_vol[chan]) DIV 2; + end; + end; + + If (ftune_table[chan] = -127) then ftune_table[chan] := 0; + freq := freq+ftune_table[chan]; + + If NOT (is_4op_chan(chan) and (chan in [1,3,5,10,12,14])) then + change_frequency(chan,freq); + + If (note <> 0) then + begin + event_table[chan].note := note; + If restart_macro then + With event_table[chan] do + If NOT (((effect_def = ef_Extended) and + (effect DIV 16 = ef_ex_ExtendedCmd) and + (effect MOD 16 = ef_ex_cmd_NoRestart)) or + ((effect_def2 = ef_Extended) and + (effect2 DIV 16 = ef_ex_ExtendedCmd) and + (effect2 MOD 16 = ef_ex_cmd_NoRestart))) then + init_macro_table(chan,note,ins,freq) + else macro_table[chan].arpg_note := note; + end; +end; + +procedure generate_custom_vibrato(value: Byte); + +const + vibtab_size: array[0..15] of Byte = ( + 16,16,16,16,32,32,32,32,64,64,64,64,128,128,128,128); + +var + mul_r: Real; + mul_b: Byte; + idx,idx2: Byte; + +function min0(value: Longint): Longint; +begin + If (value >= 0) then min0 := value + else min0 := 0; +end; + +begin + Case value of + // set default speed table + 0: begin + vibtrem_table_size := def_vibtrem_table_size; + Move(def_vibtrem_table,vibtrem_table,SizeOf(vibtrem_table)); + end; + + // set custom speed table (fixed size = 32) + 1..239: + begin + vibtrem_table_size := def_vibtrem_table_size; + mul_r := value/16; + For idx2 := 0 to 7 do + begin + vibtrem_table[idx2*32] := 0; + For idx := 1 to 16 do + vibtrem_table[idx2*32+idx] := ROUND(idx*mul_r); + For idx := 17 to 31 do + vibtrem_table[idx2*32+idx] := ROUND((32-idx)*mul_r); + end; + end; + + // set custom speed table (speed factor = 1-4) + 240..255: + begin + vibtrem_speed_factor := SUCC((value-240) MOD 4); + vibtrem_table_size := 2*vibtab_size[value-240]; + mul_b := 256 DIV (vibtab_size[value-240]); + For idx2 := 0 to PRED(128 DIV vibtab_size[value-240]) do + begin + vibtrem_table[2*vibtab_size[value-240]*idx2] := 0; + For idx := 1 to vibtab_size[value-240] do + vibtrem_table[2*vibtab_size[value-240]*idx2+idx] := + min0(idx*mul_b-1); + For idx := vibtab_size[value-240]+1 to + 2*vibtab_size[value-240]-1 do + vibtrem_table[2*vibtab_size[value-240]*idx2+idx] := + min0((2*vibtab_size[value-240]-idx)*mul_b-1); + end; + end; + end; +end; + +procedure update_fine_effects(chan: Byte); forward; +procedure play_line; + +var + chan,idx: Byte; + event: array[1..20] of tCHUNK; + eLo,eHi,eLo2,eHi2: array[1..20] of Byte; + +function no_loop(current_chan,current_line: Byte): Boolean; + +var + result: Boolean; + chan: Byte; + +begin + result := TRUE; + For chan := 1 to PRED(current_chan) do + If (loop_table[chan][current_line] <> 0) and + (loop_table[chan][current_line] <> BYTE_NULL) then + begin + result := FALSE; + BREAK; + end; + no_loop := result; +end; + +function get_event(pattern,line,channel: Byte): tCHUNK; +begin + asm + mov esi,[pattdata] + mov edi,@result + mov al,pattern + inc al + cmp al,max_patterns + jbe @@1 + mov ecx,CHUNK_SIZE + xor al,al + rep stosb + jmp @@2 +@@1: xor eax,eax + mov al,line + mov ebx,CHUNK_SIZE + mul ebx + mov ecx,eax + xor eax,eax + mov al,channel + dec eax + mov ebx,256*CHUNK_SIZE + mul ebx + add ecx,eax + xor eax,eax + mov al,pattern + mov ebx,8 + div ebx + push eax + mov eax,edx + mov ebx,20*256*CHUNK_SIZE + mul ebx + add ecx,eax + pop eax + mov ebx,8*20*256*CHUNK_SIZE + mul ebx + add ecx,eax + add esi,ecx + mov ecx,CHUNK_SIZE + rep movsb +@@2: + end; +end; + +begin + _debug_str_ := 'A2PLAYER.PAS:play_line'; + If (current_line = 0) and + (current_order = calc_following_order(0)) then + time_playing := 0; + + If NOT (pattern_break and (next_line AND $0f0 = pattern_loop_flag)) and + (current_order <> last_order) then + begin + FillChar(loopbck_table,SizeOf(loopbck_table),BYTE_NULL); + FillChar(loop_table,SizeOf(loop_table),BYTE_NULL); + last_order := current_order; + end; + + For chan := 1 to songdata.nm_tracks do + begin + event[chan] := get_event(current_pattern,current_line,chan); + If (effect_table[chan] <> 0) then last_effect[chan] := effect_table[chan]; + If (glfsld_table[chan] <> 0) then effect_table[chan] := glfsld_table[chan] + else effect_table[chan] := effect_table[chan] AND $0ff00; + If (effect_table2[chan] <> 0) then last_effect2[chan] := effect_table2[chan]; + If (glfsld_table2[chan] <> 0) then effect_table2[chan] := glfsld_table2[chan] + else effect_table2[chan] := effect_table2[chan] AND $0ff00; + ftune_table[chan] := 0; + + If (event[chan].note = BYTE_NULL) then + event[chan].note := event_table[chan].note OR keyoff_flag + else If (event[chan].note in [fixed_note_flag+1..fixed_note_flag+12*8+1]) then + event[chan].note := event[chan].note-fixed_note_flag; + + If (event[chan].note <> 0) or + (event[chan].effect_def <> 0) or + (event[chan].effect_def2 <> 0) or + ((event[chan].effect_def = 0) and (event[chan].effect <> 0)) or + ((event[chan].effect_def2 = 0) and (event[chan].effect2 <> 0)) then + event_new[chan] := TRUE + else event_new[chan] := FALSE; + + If (event[chan].note <> 0) or + (event[chan].instr_def <> 0) or + (event[chan].effect_def+event[chan].effect <> 0) or + (event[chan].effect_def2+event[chan].effect2 <> 0) then + begin + event_table[chan].effect_def := event[chan].effect_def; + event_table[chan].effect := event[chan].effect; + event_table[chan].effect_def2 := event[chan].effect_def2; + event_table[chan].effect2 := event[chan].effect2; + end; + + If (event[chan].instr_def <> 0) then + If NOT Empty(songdata.instr_data[event[chan].instr_def], + INSTRUMENT_SIZE) then + set_ins_data(event[chan].instr_def,chan) + else begin + release_sustaining_sound(chan); + set_ins_data(event[chan].instr_def,chan); + end; + + If NOT (event[chan].effect_def in [ef_Vibrato,ef_ExtraFineVibrato, + ef_VibratoVolSlide,ef_VibratoVSlideFine]) then + FillChar(vibr_table[chan],SizeOf(vibr_table[chan]),0); + + If NOT (event[chan].effect_def2 in [ef_Vibrato,ef_ExtraFineVibrato, + ef_VibratoVolSlide,ef_VibratoVSlideFine]) then + FillChar(vibr_table2[chan],SizeOf(vibr_table2[chan]),0); + + If NOT (event[chan].effect_def in [ef_RetrigNote,ef_MultiRetrigNote]) then + FillChar(retrig_table[chan],SizeOf(retrig_table[chan]),0); + + If NOT (event[chan].effect_def2 in [ef_RetrigNote,ef_MultiRetrigNote]) then + FillChar(retrig_table2[chan],SizeOf(retrig_table2[chan]),0); + + If NOT (event[chan].effect_def in [ef_Tremolo,ef_ExtraFineTremolo]) then + FillChar(trem_table[chan],SizeOf(trem_table[chan]),0); + + If NOT (event[chan].effect_def2 in [ef_Tremolo,ef_ExtraFineTremolo]) then + FillChar(trem_table2[chan],SizeOf(trem_table2[chan]),0); + + If NOT (((event[chan].effect_def = ef_Arpeggio) and (event[chan].effect <> 0)) or + (event[chan].effect_def = ef_ExtraFineArpeggio)) and + + + + + + (arpgg_table[chan].note <> 0) and (arpgg_table[chan].state <> 1) then + begin + arpgg_table[chan].state := 1; + change_frequency(chan,nFreq(arpgg_table[chan].note-1)+ + SHORTINT(ins_parameter(event_table[chan].instr_def,12))); + end + else If NOT (((event[chan].effect_def2 = ef_Arpeggio) and (event[chan].effect2 <> 0)) or + (event[chan].effect_def2 = ef_ExtraFineArpeggio)) and + (arpgg_table2[chan].note <> 0) and (arpgg_table2[chan].state <> 1) then + begin + arpgg_table2[chan].state := 1; + change_frequency(chan,nFreq(arpgg_table2[chan].note-1)+ + SHORTINT(ins_parameter(event_table[chan].instr_def,12))); + end; + end; + + For chan := 1 to songdata.nm_tracks do + begin + If (tremor_table[chan].pos <> 0) and + (event[chan].effect_def <> ef_Tremor) then + begin + tremor_table[chan].pos := 0; + set_ins_volume(LO(tremor_table[chan].volume), + HI(tremor_table[chan].volume),chan); + end; + + If (tremor_table2[chan].pos <> 0) and + (event[chan].effect_def2 <> ef_Tremor) then + begin + tremor_table2[chan].pos := 0; + set_ins_volume(LO(tremor_table2[chan].volume), + HI(tremor_table2[chan].volume),chan); + end; + + eLo[chan] := LO(last_effect[chan]); + eHi[chan] := HI(last_effect[chan]); + eLo2[chan] := LO(last_effect2[chan]); + eHi2[chan] := HI(last_effect2[chan]); + end; + + For chan := 1 to songdata.nm_tracks do + Case event[chan].effect_def of + + ef_Arpeggio, + ef_ExtraFineArpeggio, + ef_ArpggVSlide, + ef_ArpggVSlideFine: + If (event[chan].effect_def <> ef_Arpeggio) or + (event[chan].effect <> 0) then + begin + Case event[chan].effect_def of + ef_Arpeggio: + effect_table[chan] := concw(ef_Arpeggio+ef_fix1,event[chan].effect); + + ef_ExtraFineArpeggio: + effect_table[chan] := concw(ef_ExtraFineArpeggio,event[chan].effect); + + ef_ArpggVSlide, + ef_ArpggVSlideFine: + If (event[chan].effect <> 0) then + effect_table[chan] := concw(event[chan].effect_def,event[chan].effect) + else If (eLo[chan] in [ef_ArpggVSlide,ef_ArpggVSlideFine]) and + (eHi[chan] <> 0) then + effect_table[chan] := concw(event[chan].effect_def,eHi[chan]) + else effect_table[chan] := effect_table[chan] AND $0ff00; + end; + + If (event[chan].note AND $7f in [1..12*8+1]) then + begin + arpgg_table[chan].state := 0; + arpgg_table[chan].note := event[chan].note AND $7f; + If (event[chan].effect_def in [ef_Arpeggio,ef_ExtraFineArpeggio]) then + begin + arpgg_table[chan].add1 := event[chan].effect DIV 16; + arpgg_table[chan].add2 := event[chan].effect MOD 16; + end; + end + else If (event[chan].note = 0) and + (event_table[chan].note AND $7f in [1..12*8+1]) then + begin + If NOT (eLo[chan] in [ef_Arpeggio+ef_fix1,ef_ExtraFineArpeggio, + ef_ArpggVSlide,ef_ArpggVSlideFine]) then + arpgg_table[chan].state := 0; + + arpgg_table[chan].note := event_table[chan].note AND $7f; + If (event[chan].effect_def in [ef_Arpeggio,ef_ExtraFineArpeggio]) then + begin + arpgg_table[chan].add1 := event[chan].effect DIV 16; + arpgg_table[chan].add2 := event[chan].effect MOD 16; + end; + end + else effect_table[chan] := 0; + end; + + ef_FSlideUp, + ef_FSlideDown, + ef_FSlideUpFine, + ef_FSlideDownFine: + begin + effect_table[chan] := concw(event[chan].effect_def,event[chan].effect); + fslide_table[chan] := event[chan].effect; + end; + + ef_GlobalFSlideUp, + ef_GlobalFSlideDown: + begin + If (event[chan].effect_def = ef_GlobalFSlideUp) then + begin + If (event[chan].effect_def2 = ef_Extended) and + (event[chan].effect2 = ef_ex_ExtendedCmd*16+ef_ex_cmd_FTrm_XFGFS) then + effect_table[chan] := concw(ef_extended2+ef_fix2+ef_ex2_FreqSlideUpXF, + event[chan].effect) + else If (event[chan].effect_def2 = ef_Extended) and + (event[chan].effect2 = ef_ex_ExtendedCmd*16+ef_ex_cmd_FVib_FGFS) then + effect_table[chan] := concw(ef_FSlideUpFine,event[chan].effect) + else effect_table[chan] := concw(ef_FSlideUp,event[chan].effect); + end + else + begin + If (event[chan].effect_def2 = ef_Extended) and + (event[chan].effect2 = ef_ex_ExtendedCmd*16+ef_ex_cmd_FTrm_XFGFS) then + effect_table[chan] := concw(ef_extended2+ef_fix2+ef_ex2_FreqSlideDnXF, + event[chan].effect) + else If (event[chan].effect_def2 = ef_Extended) and + (event[chan].effect2 = ef_ex_ExtendedCmd*16+ef_ex_cmd_FVib_FGFS) then + effect_table[chan] := concw(ef_FSlideDownFine,event[chan].effect) + else effect_table[chan] := concw(ef_FSlideDown,event[chan].effect); + end; + For idx := chan to songdata.nm_tracks do + begin + fslide_table[idx] := event[chan].effect; + glfsld_table[idx] := effect_table[chan]; + end; + end; + + ef_FSlideUpVSlide, + ef_FSlUpVSlF, + ef_FSlideDownVSlide, + ef_FSlDownVSlF, + ef_FSlUpFineVSlide, + ef_FSlUpFineVSlF, + ef_FSlDownFineVSlide, + ef_FSlDownFineVSlF: + If (event[chan].effect <> 0) then + effect_table[chan] := concw(event[chan].effect_def,event[chan].effect) + else If (eLo[chan] in [ef_FSlideUpVSlide,ef_FSlUpVSlF,ef_FSlideDownVSlide, + ef_FSlDownVSlF,ef_FSlUpFineVSlide,ef_FSlUpFineVSlF, + ef_FSlDownFineVSlide,ef_FSlDownFineVSlF]) and + (eHi[chan] <> 0) then + effect_table[chan] := concw(event[chan].effect_def,eHi[chan]) + else effect_table[chan] := effect_table[chan] AND $0ff00; + + ef_TonePortamento: + If (event[chan].note in [1..12*8+1]) then + begin + If (event[chan].effect <> 0) then + effect_table[chan] := concw(ef_TonePortamento,event[chan].effect) + else If (eLo[chan] = ef_TonePortamento) and + (eHi[chan] <> 0) then + effect_table[chan] := concw(ef_TonePortamento,eHi[chan]) + else effect_table[chan] := ef_TonePortamento; + + porta_table[chan].speed := HI(effect_table[chan]); + porta_table[chan].freq := nFreq(event[chan].note-1)+ + SHORTINT(ins_parameter(event_table[chan].instr_def,12)); + end + else If (eLo[chan] = ef_TonePortamento) then + begin + If (event[chan].effect <> 0) then + effect_table[chan] := concw(ef_TonePortamento,event[chan].effect) + else If (eLo[chan] = ef_TonePortamento) and + (eHi[chan] <> 0) then + effect_table[chan] := concw(ef_TonePortamento,eHi[chan]) + else effect_table[chan] := ef_TonePortamento; + porta_table[chan].speed := HI(effect_table[chan]); + end; + + ef_TPortamVolSlide, + ef_TPortamVSlideFine: + If (event[chan].effect <> 0) then + effect_table[chan] := concw(event[chan].effect_def,event[chan].effect) + else If (eLo[chan] in [ef_TPortamVolSlide,ef_TPortamVSlideFine]) and + (eHi[chan] <> 0) then + effect_table[chan] := concw(event[chan].effect_def,eHi[chan]) + else effect_table[chan] := effect_table[chan] AND $0ff00; + + ef_Vibrato, + ef_ExtraFineVibrato: + begin + If (event[chan].effect <> 0) then + effect_table[chan] := concw(event[chan].effect_def,event[chan].effect) + else If (eLo[chan] in [ef_Vibrato,ef_ExtraFineVibrato]) and + (eHi[chan] <> 0) then + effect_table[chan] := concw(event[chan].effect_def,eHi[chan]) + else effect_table[chan] := event[chan].effect_def; + + If (event[chan].effect_def2 = ef_Extended) and + (event[chan].effect2 = ef_ex_ExtendedCmd*16+ef_ex_cmd_FVib_FGFS) then + vibr_table[chan].fine := TRUE; + + vibr_table[chan].speed := HI(effect_table[chan]) DIV 16; + vibr_table[chan].depth := HI(effect_table[chan]) MOD 16; + end; + + ef_Tremolo, + ef_ExtraFineTremolo: + begin + If (event[chan].effect <> 0) then + effect_table[chan] := concw(event[chan].effect_def,event[chan].effect) + else If (eLo[chan] in [ef_Tremolo,ef_ExtraFineTremolo]) and + (eHi[chan] <> 0) then + effect_table[chan] := concw(event[chan].effect_def,eHi[chan]) + else effect_table[chan] := event[chan].effect_def; + + If (event[chan].effect_def2 = ef_Extended) and + (event[chan].effect2 = ef_ex_ExtendedCmd*16+ef_ex_cmd_FTrm_XFGFS) then + trem_table[chan].fine := TRUE; + + trem_table[chan].speed := HI(effect_table[chan]) DIV 16; + trem_table[chan].depth := HI(effect_table[chan]) MOD 16; + end; + + ef_VibratoVolSlide, + ef_VibratoVSlideFine: + begin + If (event[chan].effect <> 0) then + effect_table[chan] := concw(event[chan].effect_def,event[chan].effect) + else If (eLo[chan] in [ef_VibratoVolSlide,ef_VibratoVSlideFine]) and + (HI(effect_table[chan]) <> 0) then + effect_table[chan] := concw(event[chan].effect_def,HI(effect_table[chan])) + else effect_table[chan] := effect_table[chan] AND $0ff00; + + If (event[chan].effect_def2 = ef_Extended) and + (event[chan].effect2 = ef_ex_ExtendedCmd*16+ef_ex_cmd_FVib_FGFS) then + vibr_table[chan].fine := TRUE; + end; + + ef_SetCarrierVol: + set_ins_volume(BYTE_NULL,63-event[chan].effect,chan); + + ef_SetModulatorVol: + set_ins_volume(63-event[chan].effect,BYTE_NULL,chan); + + ef_SetInsVolume: + If percussion_mode and (chan in [17..20]) then + set_ins_volume(63-event[chan].effect,BYTE_NULL,chan) + else If (ins_parameter(voice_table[chan],10) AND 1 = 0) then + set_ins_volume(BYTE_NULL,63-event[chan].effect,chan) + else set_ins_volume(63-event[chan].effect,63-event[chan].effect,chan); + + ef_ForceInsVolume: + If percussion_mode and (chan in [17..20]) then + set_ins_volume(63-event[chan].effect,BYTE_NULL,chan) + else If (ins_parameter(voice_table[chan],10) AND 1 = 0) then + set_ins_volume(scale_volume(ins_parameter(voice_table[chan],2) AND $3f,63-event[chan].effect),63-event[chan].effect,chan) + else set_ins_volume(63-event[chan].effect,63-event[chan].effect,chan); + + ef_PositionJump: + If no_loop(chan,current_line) then + begin + pattern_break := TRUE; + next_line := pattern_break_flag+chan; + end; + + ef_PatternBreak: + If no_loop(chan,current_line) then + begin + pattern_break := TRUE; + next_line := max(event[chan].effect,PRED(songdata.patt_len)); + end; + + ef_SetSpeed: + speed := event[chan].effect; + + ef_SetTempo: + update_timer(event[chan].effect); + + ef_SetWaveform: + begin + If (event[chan].effect DIV 16 in [0..7]) then + begin + fmpar_table[chan].adsrw_car.wform := event[chan].effect DIV 16; + update_carrier_adsrw(chan); + end; + + If (event[chan].effect MOD 16 in [0..7]) then + begin + fmpar_table[chan].adsrw_mod.wform := event[chan].effect MOD 16; + update_modulator_adsrw(chan); + end; + end; + + ef_VolSlide: + effect_table[chan] := concw(ef_VolSlide,event[chan].effect); + + ef_VolSlideFine: + effect_table[chan] := concw(ef_VolSlideFine,event[chan].effect); + + ef_RetrigNote: + If (event[chan].effect <> 0) then + begin + If NOT (eLo[chan] in [ef_RetrigNote,ef_MultiRetrigNote]) then + retrig_table[chan] := 1; + effect_table[chan] := concw(ef_RetrigNote,event[chan].effect); + end; + + ef_SetGlobalVolume: + begin + global_volume := event[chan].effect; + set_global_volume; + end; + + ef_MultiRetrigNote: + If (event[chan].effect DIV 16 <> 0) then + begin + If NOT (eLo[chan] in [ef_RetrigNote,ef_MultiRetrigNote]) then + retrig_table[chan] := 1; + effect_table[chan] := concw(ef_MultiRetrigNote,event[chan].effect); + end; + + ef_Tremor: + If (event[chan].effect DIV 16 <> 0) and + (event[chan].effect MOD 16 <> 0) then + begin + If (eLo[chan] <> ef_Tremor) then + begin + tremor_table[chan].pos := 0; + tremor_table[chan].volume := volume_table[chan]; + end; + effect_table[chan] := concw(ef_Tremor,event[chan].effect); + end; + + ef_Extended: + Case (event[chan].effect DIV 16) of + ef_ex_SetTremDepth: + Case (event[chan].effect MOD 16) of + 0: begin + opl3out(_instr[11],misc_register AND $07f); + current_tremolo_depth := 0; + end; + + 1: begin + opl3out(_instr[11],misc_register OR $080); + current_tremolo_depth := 1; + end; + end; + + ef_ex_SetVibDepth: + Case (event[chan].effect MOD 16) of + 0: begin + opl3out(_instr[11],misc_register AND $0bf); + current_vibrato_depth := 0; + end; + + 1: begin + opl3out(_instr[11],misc_register OR $040); + current_vibrato_depth := 1; + end; + end; + + ef_ex_SetAttckRateM: + begin + fmpar_table[chan].adsrw_mod.attck := event[chan].effect MOD 16; + update_modulator_adsrw(chan); + end; + + ef_ex_SetDecayRateM: + begin + fmpar_table[chan].adsrw_mod.dec := event[chan].effect MOD 16; + update_modulator_adsrw(chan); + end; + + ef_ex_SetSustnLevelM: + begin + fmpar_table[chan].adsrw_mod.sustn := event[chan].effect MOD 16; + update_modulator_adsrw(chan); + end; + + ef_ex_SetRelRateM: + begin + fmpar_table[chan].adsrw_mod.rel := event[chan].effect MOD 16; + update_modulator_adsrw(chan); + end; + + ef_ex_SetAttckRateC: + begin + fmpar_table[chan].adsrw_car.attck := event[chan].effect MOD 16; + update_carrier_adsrw(chan); + end; + + ef_ex_SetDecayRateC: + begin + fmpar_table[chan].adsrw_car.dec := event[chan].effect MOD 16; + update_carrier_adsrw(chan); + end; + + ef_ex_SetSustnLevelC: + begin + fmpar_table[chan].adsrw_car.sustn := event[chan].effect MOD 16; + update_carrier_adsrw(chan); + end; + + ef_ex_SetRelRateC: + begin + fmpar_table[chan].adsrw_car.rel := event[chan].effect MOD 16; + update_carrier_adsrw(chan); + end; + + ef_ex_SetFeedback: + begin + fmpar_table[chan].feedb := event[chan].effect MOD 16; + update_fmpar(chan); + end; + + ef_ex_SetPanningPos: + begin + panning_table[chan] := event[chan].effect MOD 16; + update_fmpar(chan); + end; + + ef_ex_PatternLoop, + ef_ex_PatternLoopRec: + If (event[chan].effect MOD 16 = 0) then + loopbck_table[chan] := current_line + else If (loopbck_table[chan] <> BYTE_NULL) then + begin + If (loop_table[chan][current_line] = BYTE_NULL) then + loop_table[chan][current_line] := event[chan].effect MOD 16; + If (loop_table[chan][current_line] <> 0) then + begin + pattern_break := TRUE; + next_line := pattern_loop_flag+chan; + end + else If (event[chan].effect DIV 16 = ef_ex_PatternLoopRec) then + loop_table[chan][current_line] := BYTE_NULL; + end; + + ef_ex_MacroKOffLoop: + If (event[chan].effect MOD 16 <> 0) then + keyoff_loop[chan] := TRUE + else keyoff_loop[chan] := FALSE; + + ef_ex_ExtendedCmd: + Case (event[chan].effect MOD 16) of + ef_ex_cmd_RSS: release_sustaining_sound(chan); + ef_ex_cmd_ResetVol: reset_ins_volume(chan); + ef_ex_cmd_LockVol: volume_lock [chan] := TRUE; + ef_ex_cmd_UnlockVol: volume_lock [chan] := FALSE; + ef_ex_cmd_LockVP: peak_lock [chan] := TRUE; + ef_ex_cmd_UnlockVP: peak_lock [chan] := FALSE; + ef_ex_cmd_VSlide_def: volslide_type[chan] := 0; + ef_ex_cmd_LockPan: pan_lock [chan] := TRUE; + ef_ex_cmd_UnlockPan: pan_lock [chan] := FALSE; + ef_ex_cmd_VibrOff: change_frequency(chan,freq_table[chan]); + ef_ex_cmd_TremOff: set_ins_volume(LO(volume_table[chan]), + HI(volume_table[chan]),chan); + ef_ex_cmd_VSlide_car: + If (event[chan].effect_def2 = ef_Extended) and + (event[chan].effect2 = ef_ex_ExtendedCmd*16+ + ef_ex_cmd_VSlide_mod) then + volslide_type[chan] := 3 + else volslide_type[chan] := 1; + + ef_ex_cmd_VSlide_mod: + If (event[chan].effect_def2 = ef_Extended) and + (event[chan].effect2 = ef_ex_ExtendedCmd*16+ + ef_ex_cmd_VSlide_car) then + volslide_type[chan] := 3 + else volslide_type[chan] := 2; + end; + end; + + ef_Extended2: + Case (event[chan].effect DIV 16) of + ef_ex2_PatDelayFrame, + ef_ex2_PatDelayRow: + begin + pattern_delay := TRUE; + If (event[chan].effect DIV 16 = ef_ex2_PatDelayFrame) then + tickD := (event[chan].effect MOD 16) + else tickD := speed*(event[chan].effect MOD 16); + end; + + ef_ex2_NoteDelay: + begin + effect_table[chan] := concw(ef_extended2+ef_fix2+ef_ex2_NoteDelay,0); + notedel_table[chan] := event[chan].effect MOD 16; + end; + + ef_ex2_NoteCut: + begin + effect_table[chan] := concw(ef_extended2+ef_fix2+ef_ex2_NoteCut,0); + notecut_table[chan] := event[chan].effect MOD 16; + end; + + ef_ex2_FineTuneUp: + Inc(ftune_table[chan],event[chan].effect MOD 16); + + ef_ex2_FineTuneDown: + Dec(ftune_table[chan],event[chan].effect MOD 16); + + ef_ex2_GlVolSlideUp: + effect_table[chan] := concw(ef_extended2+ef_fix2+ef_ex2_GlVolSlideUp, + event[chan].effect MOD 16); + ef_ex2_GlVolSlideDn: + effect_table[chan] := concw(ef_extended2+ef_fix2+ef_ex2_GlVolSlideDn, + event[chan].effect MOD 16); + ef_ex2_GlVolSlideUpF: + effect_table[chan] := concw(ef_extended2+ef_fix2+ef_ex2_GlVolSlideUpF, + event[chan].effect MOD 16); + ef_ex2_GlVolSlideDnF: + effect_table[chan] := concw(ef_extended2+ef_fix2+ef_ex2_GlVolSlideDnF, + event[chan].effect MOD 16); + ef_ex2_GlVolSldUpXF: + effect_table[chan] := concw(ef_extended2+ef_fix2+ef_ex2_GlVolSldUpXF, + event[chan].effect MOD 16); + ef_ex2_GlVolSldDnXF: + effect_table[chan] := concw(ef_extended2+ef_fix2+ef_ex2_GlVolSldDnXF, + event[chan].effect MOD 16); + ef_ex2_VolSlideUpXF: + effect_table[chan] := concw(ef_extended2+ef_fix2+ef_ex2_VolSlideUpXF, + event[chan].effect MOD 16); + ef_ex2_VolSlideDnXF: + effect_table[chan] := concw(ef_extended2+ef_fix2+ef_ex2_VolSlideDnXF, + event[chan].effect MOD 16); + ef_ex2_FreqSlideUpXF: + effect_table[chan] := concw(ef_extended2+ef_fix2+ef_ex2_FreqSlideUpXF, + event[chan].effect MOD 16); + ef_ex2_FreqSlideDnXF: + effect_table[chan] := concw(ef_extended2+ef_fix2+ef_ex2_FreqSlideDnXF, + event[chan].effect MOD 16); + end; + + ef_Extended3: + Case (event[chan].effect DIV 16) of + ef_ex3_SetConnection: + begin + fmpar_table[chan].connect := event[chan].effect MOD 16; + update_fmpar(chan); + end; + + ef_ex3_SetMultipM: + begin + fmpar_table[chan].multipM := event[chan].effect MOD 16; + update_fmpar(chan); + end; + + ef_ex3_SetKslM: + begin + fmpar_table[chan].kslM := event[chan].effect MOD 16; + update_fmpar(chan); + end; + + ef_ex3_SetTremoloM: + begin + fmpar_table[chan].tremM := event[chan].effect MOD 16; + update_fmpar(chan); + end; + + ef_ex3_SetVibratoM: + begin + fmpar_table[chan].vibrM := event[chan].effect MOD 16; + update_fmpar(chan); + end; + + ef_ex3_SetKsrM: + begin + fmpar_table[chan].ksrM := event[chan].effect MOD 16; + update_fmpar(chan); + end; + + ef_ex3_SetSustainM: + begin + fmpar_table[chan].sustM := event[chan].effect MOD 16; + update_fmpar(chan); + end; + + ef_ex3_SetMultipC: + begin + fmpar_table[chan].multipC := event[chan].effect MOD 16; + update_fmpar(chan); + end; + + ef_ex3_SetKslC: + begin + fmpar_table[chan].kslC := event[chan].effect MOD 16; + update_fmpar(chan); + end; + + ef_ex3_SetTremoloC: + begin + fmpar_table[chan].tremC := event[chan].effect MOD 16; + update_fmpar(chan); + end; + + ef_ex3_SetVibratoC: + begin + fmpar_table[chan].vibrC := event[chan].effect MOD 16; + update_fmpar(chan); + end; + + ef_ex3_SetKsrC: + begin + fmpar_table[chan].ksrC := event[chan].effect MOD 16; + update_fmpar(chan); + end; + + ef_ex3_SetSustainC: + begin + fmpar_table[chan].sustC := event[chan].effect MOD 16; + update_fmpar(chan); + end; + end; + end; + + For chan := 1 to songdata.nm_tracks do + Case event[chan].effect_def2 of + ef_Arpeggio, + ef_ExtraFineArpeggio, + ef_ArpggVSlide, + ef_ArpggVSlideFine: + If (event[chan].effect_def2 <> ef_Arpeggio) or + (event[chan].effect2 <> 0) then + begin + Case event[chan].effect_def2 of + ef_Arpeggio: + effect_table2[chan] := concw(ef_Arpeggio+ef_fix1,event[chan].effect2); + + ef_ExtraFineArpeggio: + effect_table2[chan] := concw(ef_ExtraFineArpeggio,event[chan].effect2); + + ef_ArpggVSlide, + ef_ArpggVSlideFine: + If (event[chan].effect2 <> 0) then + effect_table2[chan] := concw(event[chan].effect_def2,event[chan].effect2) + else If (eLo2[chan] in [ef_ArpggVSlide,ef_ArpggVSlideFine]) and + (eHi2[chan] <> 0) then + effect_table2[chan] := concw(event[chan].effect_def2,eHi2[chan]) + else effect_table2[chan] := effect_table2[chan] AND $0ff00; + end; + + If (event[chan].note AND $7f in [1..12*8+1]) then + begin + arpgg_table2[chan].state := 0; + arpgg_table2[chan].note := event[chan].note AND $7f; + If (event[chan].effect_def2 in [ef_Arpeggio,ef_ExtraFineArpeggio]) then + begin + arpgg_table2[chan].add1 := event[chan].effect2 DIV 16; + arpgg_table2[chan].add2 := event[chan].effect2 MOD 16; + end; + end + else If (event[chan].note = 0) and + (event_table[chan].note AND $7f in [1..12*8+1]) then + begin + If NOT (eLo2[chan] in [ef_Arpeggio+ef_fix1,ef_ExtraFineArpeggio, + ef_ArpggVSlide,ef_ArpggVSlideFine]) then + arpgg_table2[chan].state := 0; + + arpgg_table2[chan].note := event_table[chan].note AND $7f; + If (event[chan].effect_def2 in [ef_Arpeggio,ef_ExtraFineArpeggio]) then + begin + arpgg_table2[chan].add1 := event[chan].effect2 DIV 16; + arpgg_table2[chan].add2 := event[chan].effect2 MOD 16; + end; + end + else effect_table2[chan] := 0; + end; + + ef_FSlideUp, + ef_FSlideDown, + ef_FSlideUpFine, + ef_FSlideDownFine: + begin + effect_table2[chan] := concw(event[chan].effect_def2,event[chan].effect2); + fslide_table2[chan] := event[chan].effect2; + end; + + ef_GlobalFSlideUp, + ef_GlobalFSlideDown: + begin + If (event[chan].effect_def2 = ef_GlobalFSlideUp) then + begin + If (event[chan].effect_def = ef_Extended) and + (event[chan].effect = ef_ex_ExtendedCmd*16+ef_ex_cmd_FTrm_XFGFS) then + effect_table2[chan] := concw(ef_extended2+ef_fix2+ef_ex2_FreqSlideUpXF, + event[chan].effect2) + else If (event[chan].effect_def = ef_Extended) and + (event[chan].effect = ef_ex_ExtendedCmd*16+ef_ex_cmd_FVib_FGFS) then + effect_table2[chan] := concw(ef_FSlideUpFine,event[chan].effect2) + else effect_table2[chan] := concw(ef_FSlideUp,event[chan].effect2); + end + else + begin + If (event[chan].effect_def = ef_Extended) and + (event[chan].effect = ef_ex_ExtendedCmd*16+ef_ex_cmd_FTrm_XFGFS) then + effect_table2[chan] := concw(ef_extended2+ef_fix2+ef_ex2_FreqSlideDnXF, + event[chan].effect2) + else If (event[chan].effect_def = ef_Extended) and + (event[chan].effect = ef_ex_ExtendedCmd*16+ef_ex_cmd_FVib_FGFS) then + effect_table2[chan] := concw(ef_FSlideDownFine,event[chan].effect2) + else effect_table2[chan] := concw(ef_FSlideDown,event[chan].effect2); + end; + For idx := chan to songdata.nm_tracks do + begin + fslide_table2[idx] := event[chan].effect2; + glfsld_table2[idx] := effect_table2[chan]; + end; + end; + + ef_FSlideUpVSlide, + ef_FSlUpVSlF, + ef_FSlideDownVSlide, + ef_FSlDownVSlF, + ef_FSlUpFineVSlide, + ef_FSlUpFineVSlF, + ef_FSlDownFineVSlide, + ef_FSlDownFineVSlF: + If (event[chan].effect2 <> 0) then + effect_table2[chan] := concw(event[chan].effect_def2,event[chan].effect2) + else If (eLo2[chan] in [ef_FSlideUpVSlide,ef_FSlUpVSlF,ef_FSlideDownVSlide, + ef_FSlDownVSlF,ef_FSlUpFineVSlide,ef_FSlUpFineVSlF, + ef_FSlDownFineVSlide,ef_FSlDownFineVSlF]) and + (eHi2[chan] <> 0) then + effect_table2[chan] := concw(event[chan].effect_def2,eHi2[chan]) + else effect_table2[chan] := effect_table2[chan] AND $0ff00; + + ef_TonePortamento: + If (event[chan].note in [1..12*8+1]) then + begin + If (event[chan].effect2 <> 0) then + effect_table2[chan] := concw(ef_TonePortamento,event[chan].effect2) + else If (eLo2[chan] = ef_TonePortamento) and + (eHi2[chan] <> 0) then + effect_table2[chan] := concw(ef_TonePortamento,eHi2[chan]) + else effect_table2[chan] := ef_TonePortamento; + + porta_table2[chan].speed := HI(effect_table2[chan]); + porta_table2[chan].freq := nFreq(event[chan].note-1)+ + SHORTINT(ins_parameter(event_table[chan].instr_def,12)); + end + else If (eLo2[chan] = ef_TonePortamento) then + begin + If (event[chan].effect2 <> 0) then + effect_table2[chan] := concw(ef_TonePortamento,event[chan].effect2) + else If (eLo2[chan] = ef_TonePortamento) and + (eHi2[chan] <> 0) then + effect_table2[chan] := concw(ef_TonePortamento,eHi2[chan]) + else effect_table2[chan] := ef_TonePortamento; + porta_table2[chan].speed := HI(effect_table2[chan]); + end; + + ef_TPortamVolSlide, + ef_TPortamVSlideFine: + If (event[chan].effect2 <> 0) then + effect_table2[chan] := concw(event[chan].effect_def2,event[chan].effect2) + else If (eLo2[chan] in [ef_TPortamVolSlide,ef_TPortamVSlideFine]) and + (eHi2[chan] <> 0) then + effect_table2[chan] := concw(event[chan].effect_def2,eHi2[chan]) + else effect_table2[chan] := effect_table2[chan] AND $0ff00; + + ef_Vibrato, + ef_ExtraFineVibrato: + begin + If (event[chan].effect2 <> 0) then + effect_table2[chan] := concw(event[chan].effect_def2,event[chan].effect2) + else If (eLo2[chan] in [ef_Vibrato,ef_ExtraFineVibrato]) and + (eHi2[chan] <> 0) then + effect_table2[chan] := concw(event[chan].effect_def2,eHi2[chan]) + else effect_table2[chan] := event[chan].effect_def2; + + If (event[chan].effect_def = ef_Extended) and + (event[chan].effect = ef_ex_ExtendedCmd*16+ef_ex_cmd_FVib_FGFS) then + vibr_table2[chan].fine := TRUE; + + vibr_table2[chan].speed := HI(effect_table2[chan]) DIV 16; + vibr_table2[chan].depth := HI(effect_table2[chan]) MOD 16; + end; + + ef_Tremolo, + ef_ExtraFineTremolo: + begin + If (event[chan].effect2 <> 0) then + effect_table2[chan] := concw(event[chan].effect_def2,event[chan].effect2) + else If (eLo2[chan] in [ef_Tremolo,ef_ExtraFineTremolo]) and + (eHi2[chan] <> 0) then + effect_table2[chan] := concw(event[chan].effect_def2,eHi2[chan]) + else effect_table2[chan] := event[chan].effect_def2; + + If (event[chan].effect_def = ef_Extended) and + (event[chan].effect = ef_ex_ExtendedCmd*16+ef_ex_cmd_FTrm_XFGFS) then + trem_table2[chan].fine := TRUE; + + trem_table2[chan].speed := HI(effect_table2[chan]) DIV 16; + trem_table2[chan].depth := HI(effect_table2[chan]) MOD 16; + end; + + ef_VibratoVolSlide, + ef_VibratoVSlideFine: + begin + If (event[chan].effect2 <> 0) then + effect_table2[chan] := concw(event[chan].effect_def2,event[chan].effect2) + else If (eLo2[chan] in [ef_VibratoVolSlide,ef_VibratoVSlideFine]) and + (HI(effect_table2[chan]) <> 0) then + effect_table2[chan] := concw(event[chan].effect_def2,HI(effect_table2[chan])) + else effect_table2[chan] := effect_table2[chan] AND $0ff00; + + If (event[chan].effect_def = ef_Extended) and + (event[chan].effect = ef_ex_ExtendedCmd*16+ef_ex_cmd_FVib_FGFS) then + vibr_table2[chan].fine := TRUE; + end; + + ef_SetCarrierVol: + set_ins_volume(BYTE_NULL,63-event[chan].effect2,chan); + + ef_SetModulatorVol: + set_ins_volume(63-event[chan].effect2,BYTE_NULL,chan); + + ef_SetInsVolume: + If percussion_mode and (chan in [17..20]) then + set_ins_volume(63-event[chan].effect2,BYTE_NULL,chan) + else If (ins_parameter(voice_table[chan],10) AND 1 = 0) then + set_ins_volume(BYTE_NULL,63-event[chan].effect2,chan) + else set_ins_volume(63-event[chan].effect2,63-event[chan].effect2,chan); + + ef_ForceInsVolume: + If percussion_mode and (chan in [17..20]) then + set_ins_volume(63-event[chan].effect2,BYTE_NULL,chan) + else If (ins_parameter(voice_table[chan],10) AND 1 = 0) then + set_ins_volume(scale_volume(ins_parameter(voice_table[chan],2) AND $3f,63-event[chan].effect2),63-event[chan].effect2,chan) + else set_ins_volume(63-event[chan].effect2,63-event[chan].effect2,chan); + + ef_PositionJump: + If no_loop(chan,current_line) then + begin + pattern_break := TRUE; + next_line := pattern_break_flag+chan; + end; + + ef_PatternBreak: + If no_loop(chan,current_line) then + begin + pattern_break := TRUE; + next_line := max(event[chan].effect2,PRED(songdata.patt_len)); + end; + + ef_SetSpeed: + speed := event[chan].effect2; + + ef_SetTempo: + update_timer(event[chan].effect2); + + ef_SetWaveform: + begin + If (event[chan].effect2 DIV 16 in [0..7]) then + begin + fmpar_table[chan].adsrw_car.wform := event[chan].effect2 DIV 16; + update_carrier_adsrw(chan); + end; + + If (event[chan].effect2 MOD 16 in [0..7]) then + begin + fmpar_table[chan].adsrw_mod.wform := event[chan].effect2 MOD 16; + update_modulator_adsrw(chan); + end; + end; + + ef_VolSlide: + effect_table2[chan] := concw(ef_VolSlide,event[chan].effect2); + + ef_VolSlideFine: + effect_table2[chan] := concw(ef_VolSlideFine,event[chan].effect2); + + ef_RetrigNote: + If (event[chan].effect2 <> 0) then + begin + If NOT (eLo2[chan] in [ef_RetrigNote,ef_MultiRetrigNote]) then + retrig_table2[chan] := 1; + effect_table2[chan] := concw(ef_RetrigNote,event[chan].effect2); + end; + + ef_SetGlobalVolume: + begin + global_volume := event[chan].effect2; + set_global_volume; + end; + + ef_MultiRetrigNote: + If (event[chan].effect2 DIV 16 <> 0) then + begin + If NOT (eLo2[chan] in [ef_RetrigNote,ef_MultiRetrigNote]) then + retrig_table2[chan] := 1; + effect_table2[chan] := concw(ef_MultiRetrigNote,event[chan].effect2); + end; + + ef_Tremor: + If (event[chan].effect2 DIV 16 <> 0) and + (event[chan].effect2 MOD 16 <> 0) then + begin + If (eLo2[chan] <> ef_Tremor) then + begin + tremor_table2[chan].pos := 0; + tremor_table2[chan].volume := volume_table[chan]; + end; + effect_table2[chan] := concw(ef_Tremor,event[chan].effect2); + end; + + ef_Extended: + Case (event[chan].effect2 DIV 16) of + ef_ex_SetTremDepth: + Case (event[chan].effect2 MOD 16) of + 0: begin + opl3out(_instr[11],misc_register AND $07f); + current_tremolo_depth := 0; + end; + + 1: begin + opl3out(_instr[11],misc_register OR $080); + current_tremolo_depth := 1; + end; + end; + + ef_ex_SetVibDepth: + Case (event[chan].effect2 MOD 16) of + 0: begin + opl3out(_instr[11],misc_register AND $0bf); + current_vibrato_depth := 0; + end; + + 1: begin + opl3out(_instr[11],misc_register OR $040); + current_vibrato_depth := 1; + end; + end; + + ef_ex_SetAttckRateM: + begin + fmpar_table[chan].adsrw_mod.attck := event[chan].effect2 MOD 16; + update_modulator_adsrw(chan); + end; + + ef_ex_SetDecayRateM: + begin + fmpar_table[chan].adsrw_mod.dec := event[chan].effect2 MOD 16; + update_modulator_adsrw(chan); + end; + + ef_ex_SetSustnLevelM: + begin + fmpar_table[chan].adsrw_mod.sustn := event[chan].effect2 MOD 16; + update_modulator_adsrw(chan); + end; + + ef_ex_SetRelRateM: + begin + fmpar_table[chan].adsrw_mod.rel := event[chan].effect2 MOD 16; + update_modulator_adsrw(chan); + end; + + ef_ex_SetAttckRateC: + begin + fmpar_table[chan].adsrw_car.attck := event[chan].effect2 MOD 16; + update_carrier_adsrw(chan); + end; + + ef_ex_SetDecayRateC: + begin + fmpar_table[chan].adsrw_car.dec := event[chan].effect2 MOD 16; + update_carrier_adsrw(chan); + end; + + ef_ex_SetSustnLevelC: + begin + fmpar_table[chan].adsrw_car.sustn := event[chan].effect2 MOD 16; + update_carrier_adsrw(chan); + end; + + ef_ex_SetRelRateC: + begin + fmpar_table[chan].adsrw_car.rel := event[chan].effect2 MOD 16; + update_carrier_adsrw(chan); + end; + + ef_ex_SetFeedback: + begin + fmpar_table[chan].feedb := event[chan].effect2 MOD 16; + update_fmpar(chan); + end; + + ef_ex_SetPanningPos: + begin + panning_table[chan] := event[chan].effect2 MOD 16; + update_fmpar(chan); + end; + + ef_ex_PatternLoop, + ef_ex_PatternLoopRec: + If (event[chan].effect2 MOD 16 = 0) then + loopbck_table[chan] := current_line + else If (loopbck_table[chan] <> BYTE_NULL) then + begin + If (loop_table[chan][current_line] = BYTE_NULL) then + loop_table[chan][current_line] := event[chan].effect2 MOD 16; + If (loop_table[chan][current_line] <> 0) then + begin + pattern_break := TRUE; + next_line := pattern_loop_flag+chan; + end + else If (event[chan].effect2 DIV 16 = ef_ex_PatternLoopRec) then + loop_table[chan][current_line] := BYTE_NULL; + end; + + ef_ex_MacroKOffLoop: + If (event[chan].effect2 MOD 16 <> 0) then + keyoff_loop[chan] := TRUE + else keyoff_loop[chan] := FALSE; + + ef_ex_ExtendedCmd: + Case (event[chan].effect2 MOD 16) of + ef_ex_cmd_RSS: release_sustaining_sound(chan); + ef_ex_cmd_ResetVol: reset_ins_volume(chan); + ef_ex_cmd_LockVol: volume_lock [chan] := TRUE; + ef_ex_cmd_UnlockVol: volume_lock [chan] := FALSE; + ef_ex_cmd_LockVP: peak_lock [chan] := TRUE; + ef_ex_cmd_UnlockVP: peak_lock [chan] := FALSE; + ef_ex_cmd_VSlide_def: volslide_type[chan] := 0; + ef_ex_cmd_LockPan: pan_lock [chan] := TRUE; + ef_ex_cmd_UnlockPan: pan_lock [chan] := FALSE; + ef_ex_cmd_VibrOff: change_frequency(chan,freq_table[chan]); + ef_ex_cmd_TremOff: set_ins_volume(LO(volume_table[chan]), + HI(volume_table[chan]),chan); + ef_ex_cmd_VSlide_car: + If NOT ((event[chan].effect_def = ef_Extended) and + (event[chan].effect = ef_ex_ExtendedCmd*16+ + ef_ex_cmd_VSlide_mod)) then + volslide_type[chan] := 1; + + ef_ex_cmd_VSlide_mod: + If NOT ((event[chan].effect_def = ef_Extended) and + (event[chan].effect = ef_ex_ExtendedCmd*16+ + ef_ex_cmd_VSlide_car)) then + volslide_type[chan] := 2; + end; + end; + + ef_Extended2: + Case (event[chan].effect2 DIV 16) of + ef_ex2_PatDelayFrame, + ef_ex2_PatDelayRow: + begin + pattern_delay := TRUE; + If (event[chan].effect2 DIV 16 = ef_ex2_PatDelayFrame) then + tickD := (event[chan].effect2 MOD 16) + else tickD := speed*(event[chan].effect2 MOD 16); + end; + + ef_ex2_NoteDelay: + begin + effect_table2[chan] := concw(ef_extended2+ef_fix2+ef_ex2_NoteDelay,0); + notedel_table[chan] := event[chan].effect2 MOD 16; + end; + + ef_ex2_NoteCut: + begin + effect_table2[chan] := concw(ef_extended2+ef_fix2+ef_ex2_NoteCut,0); + notecut_table[chan] := event[chan].effect2 MOD 16; + end; + + ef_ex2_FineTuneUp: + Inc(ftune_table[chan],event[chan].effect2 MOD 16); + + ef_ex2_FineTuneDown: + Dec(ftune_table[chan],event[chan].effect2 MOD 16); + + ef_ex2_GlVolSlideUp: + effect_table2[chan] := concw(ef_extended2+ef_fix2+ef_ex2_GlVolSlideUp, + event[chan].effect2 MOD 16); + ef_ex2_GlVolSlideDn: + effect_table2[chan] := concw(ef_extended2+ef_fix2+ef_ex2_GlVolSlideDn, + event[chan].effect2 MOD 16); + ef_ex2_GlVolSlideUpF: + effect_table2[chan] := concw(ef_extended2+ef_fix2+ef_ex2_GlVolSlideUpF, + event[chan].effect2 MOD 16); + ef_ex2_GlVolSlideDnF: + effect_table2[chan] := concw(ef_extended2+ef_fix2+ef_ex2_GlVolSlideDnF, + event[chan].effect2 MOD 16); + ef_ex2_GlVolSldUpXF: + effect_table2[chan] := concw(ef_extended2+ef_fix2+ef_ex2_GlVolSldUpXF, + event[chan].effect2 MOD 16); + ef_ex2_GlVolSldDnXF: + effect_table2[chan] := concw(ef_extended2+ef_fix2+ef_ex2_GlVolSldDnXF, + event[chan].effect2 MOD 16); + ef_ex2_VolSlideUpXF: + effect_table2[chan] := concw(ef_extended2+ef_fix2+ef_ex2_VolSlideUpXF, + event[chan].effect2 MOD 16); + ef_ex2_VolSlideDnXF: + effect_table2[chan] := concw(ef_extended2+ef_fix2+ef_ex2_VolSlideDnXF, + event[chan].effect2 MOD 16); + ef_ex2_FreqSlideUpXF: + effect_table2[chan] := concw(ef_extended2+ef_fix2+ef_ex2_FreqSlideUpXF, + event[chan].effect2 MOD 16); + ef_ex2_FreqSlideDnXF: + effect_table2[chan] := concw(ef_extended2+ef_fix2+ef_ex2_FreqSlideDnXF, + event[chan].effect2 MOD 16); + end; + + ef_Extended3: + Case (event[chan].effect2 DIV 16) of + ef_ex3_SetConnection: + begin + fmpar_table[chan].connect := event[chan].effect2 MOD 16; + update_fmpar(chan); + end; + + ef_ex3_SetMultipM: + begin + fmpar_table[chan].multipM := event[chan].effect2 MOD 16; + update_fmpar(chan); + end; + + ef_ex3_SetKslM: + begin + fmpar_table[chan].kslM := event[chan].effect2 MOD 16; + update_fmpar(chan); + end; + + ef_ex3_SetTremoloM: + begin + fmpar_table[chan].tremM := event[chan].effect2 MOD 16; + update_fmpar(chan); + end; + + ef_ex3_SetVibratoM: + begin + fmpar_table[chan].vibrM := event[chan].effect2 MOD 16; + update_fmpar(chan); + end; + + ef_ex3_SetKsrM: + begin + fmpar_table[chan].ksrM := event[chan].effect2 MOD 16; + update_fmpar(chan); + end; + + ef_ex3_SetSustainM: + begin + fmpar_table[chan].sustM := event[chan].effect2 MOD 16; + update_fmpar(chan); + end; + + ef_ex3_SetMultipC: + begin + fmpar_table[chan].multipC := event[chan].effect2 MOD 16; + update_fmpar(chan); + end; + + ef_ex3_SetKslC: + begin + fmpar_table[chan].kslC := event[chan].effect2 MOD 16; + update_fmpar(chan); + end; + + ef_ex3_SetTremoloC: + begin + fmpar_table[chan].tremC := event[chan].effect2 MOD 16; + update_fmpar(chan); + end; + + ef_ex3_SetVibratoC: + begin + fmpar_table[chan].vibrC := event[chan].effect2 MOD 16; + update_fmpar(chan); + end; + + ef_ex3_SetKsrC: + begin + fmpar_table[chan].ksrC := event[chan].effect2 MOD 16; + update_fmpar(chan); + end; + + ef_ex3_SetSustainC: + begin + fmpar_table[chan].sustC := event[chan].effect2 MOD 16; + update_fmpar(chan); + end; + end; + end; + + For chan := 1 to songdata.nm_tracks do + begin + If (event[chan].effect_def+event[chan].effect = 0) then + If (glfsld_table[chan] = 0) then effect_table[chan] := 0 + else begin + event_table[chan].effect_def := event[chan].effect_def; + event_table[chan].effect := event[chan].effect; + end; + + If (event[chan].effect_def2+event[chan].effect2 = 0) then + If (glfsld_table2[chan] = 0) then effect_table2[chan] := 0 + else begin + event_table[chan].effect_def2 := event[chan].effect_def2; + event_table[chan].effect2 := event[chan].effect2; + end; + + If (event[chan].note = event[chan].note OR keyoff_flag) then key_off(chan) + else If NOT (LO(effect_table[chan]) in [ef_TonePortamento, + ef_TPortamVolSlide, + ef_TPortamVSlideFine, + ef_extended2+ef_fix2+ef_ex2_NoteDelay]) and + NOT (LO(effect_table2[chan]) in [ef_TonePortamento, + ef_TPortamVolSlide, + ef_TPortamVSlideFine, + ef_extended2+ef_fix2+ef_ex2_NoteDelay]) then + If NOT (((event[chan].effect_def2 = ef_SwapArpeggio) or + (event[chan].effect_def2 = ef_SwapVibrato)) and + (event[chan].effect_def = ef_Extended) and + (event[chan].effect DIV 16 = ef_ex_ExtendedCmd) and + (event[chan].effect MOD 16 = ef_ex_cmd_NoRestart)) and + NOT (((event[chan].effect_def = ef_SwapArpeggio) or + (event[chan].effect_def = ef_SwapVibrato)) and + (event[chan].effect_def2 = ef_Extended) and + (event[chan].effect2 DIV 16 = ef_ex_ExtendedCmd) and + (event[chan].effect2 MOD 16 = ef_ex_cmd_NoRestart)) then + output_note(event[chan].note,voice_table[chan],chan,TRUE) + else output_note_NR(event[chan].note,voice_table[chan],chan,TRUE) + else If (event[chan].note <> 0) and + (event_table[chan].note = event_table[chan].note OR keyoff_flag) and + ((event[chan].effect_def in [ef_TonePortamento, + ef_TPortamVolSlide, + ef_TPortamVSlideFine]) or + (event[chan].effect_def2 in [ef_TonePortamento, + ef_TPortamVolSlide, + ef_TPortamVSlideFine])) then + output_note(event_table[chan].note AND NOT keyoff_flag,voice_table[chan],chan,FALSE) + else If (event[chan].note <> 0) then + event_table[chan].note := event[chan].note; + + Case event[chan].effect_def of + ef_SwapArpeggio: + begin + If (event[chan].effect_def2 = ef_Extended) and + (event[chan].effect2 DIV 16 = ef_ex_ExtendedCmd) and + (event[chan].effect2 MOD 16 = ef_ex_cmd_NoRestart) then + begin + If (macro_table[chan].arpg_pos > + songdata.macro_table[event[chan].effect].arpeggio.length) then + macro_table[chan].arpg_pos := + songdata.macro_table[event[chan].effect].arpeggio.length; + macro_table[chan].arpg_table := event[chan].effect; + end + else begin + macro_table[chan].arpg_count := 1; + macro_table[chan].arpg_pos := 0; + macro_table[chan].arpg_table := event[chan].effect; + macro_table[chan].arpg_note := event_table[chan].note; + end; + end; + + ef_SwapVibrato: + begin + If (event[chan].effect_def2 = ef_Extended) and + (event[chan].effect2 DIV 16 = ef_ex_ExtendedCmd) and + (event[chan].effect2 MOD 16 = ef_ex_cmd_NoRestart) then + begin + If (macro_table[chan].vib_table > + songdata.macro_table[event[chan].effect].vibrato.length) then + macro_table[chan].vib_pos := + songdata.macro_table[event[chan].effect].vibrato.length; + macro_table[chan].vib_table := event[chan].effect; + end + else begin + macro_table[chan].vib_count := 1; + macro_table[chan].vib_pos := 0; + macro_table[chan].vib_table := event[chan].effect; + macro_table[chan].vib_delay := songdata.macro_table[macro_table[chan].vib_table].vibrato.delay; + end; + end; + + ef_SetCustomSpeedTab: + generate_custom_vibrato(event[chan].effect); + end; + + Case event[chan].effect_def2 of + ef_SwapArpeggio: + begin + If (event[chan].effect_def = ef_Extended) and + (event[chan].effect DIV 16 = ef_ex_ExtendedCmd) and + (event[chan].effect MOD 16 = ef_ex_cmd_NoRestart) then + begin + If (macro_table[chan].arpg_pos > + songdata.macro_table[event[chan].effect2].arpeggio.length) then + macro_table[chan].arpg_pos := + songdata.macro_table[event[chan].effect2].arpeggio.length; + macro_table[chan].arpg_table := event[chan].effect2; + end + else begin + macro_table[chan].arpg_count := 1; + macro_table[chan].arpg_pos := 0; + macro_table[chan].arpg_table := event[chan].effect2; + macro_table[chan].arpg_note := event_table[chan].note; + end; + end; + + ef_SwapVibrato: + begin + If (event[chan].effect_def = ef_Extended) and + (event[chan].effect DIV 16 = ef_ex_ExtendedCmd) and + (event[chan].effect MOD 16 = ef_ex_cmd_NoRestart) then + begin + If (macro_table[chan].vib_table > + songdata.macro_table[event[chan].effect2].vibrato.length) then + macro_table[chan].vib_pos := + songdata.macro_table[event[chan].effect2].vibrato.length; + macro_table[chan].vib_table := event[chan].effect2; + end + else begin + macro_table[chan].vib_count := 1; + macro_table[chan].vib_pos := 0; + macro_table[chan].vib_table := event[chan].effect2; + macro_table[chan].vib_delay := songdata.macro_table[macro_table[chan].vib_table].vibrato.delay; + end; + end; + + ef_SetCustomSpeedTab: + generate_custom_vibrato(event[chan].effect2); + end; + + update_fine_effects(chan); + end; + + If pattern_delay then + begin + time_playing := time_playing+1/tempo*tickD; + If (time_playing > 3600-1) then time_playing := 0; + end + else begin + time_playing := time_playing+1/tempo*speed; + If (time_playing > 3600-1) then time_playing := 0; + end; +end; + +procedure portamento_up(chan: Byte; slide: Word; limit: Word); + +var + freq: Word; + +begin + freq := calc_freq_shift_up(freq_table[chan] AND $1fff,slide); + If (freq <= limit) then change_frequency(chan,freq) + else change_frequency(chan,limit); +end; + +procedure portamento_down(chan: Byte; slide: Word; limit: Word); + +var + freq: Word; + +begin + freq := calc_freq_shift_down(freq_table[chan] AND $1fff,slide); + If (freq >= limit) then change_frequency(chan,freq) + else change_frequency(chan,limit); +end; + +procedure macro_vibrato__porta_up(chan: Byte; depth: Byte); + +var + freq: Word; + +begin + freq := calc_freq_shift_up(macro_table[chan].vib_freq AND $1fff,depth); + If (freq <= nFreq(12*8+1)) then change_freq(chan,freq) + else change_freq(chan,nFreq(12*8+1)); +end; + +procedure macro_vibrato__porta_down(chan: Byte; depth: Byte); + +var + freq: Word; + +begin + freq := calc_freq_shift_down(macro_table[chan].vib_freq AND $1fff,depth); + If (freq >= nFreq(0)) then change_freq(chan,freq) + else change_freq(chan,nFreq(0)); +end; + +procedure tone_portamento(chan: Byte); +begin + If (freq_table[chan] AND $1fff > porta_table[chan].freq) then + portamento_down(chan,porta_table[chan].speed,porta_table[chan].freq) + else If (freq_table[chan] AND $1fff < porta_table[chan].freq) then + portamento_up(chan,porta_table[chan].speed,porta_table[chan].freq); +end; + +procedure tone_portamento2(chan: Byte); +begin + If (freq_table[chan] AND $1fff > porta_table2[chan].freq) then + portamento_down(chan,porta_table2[chan].speed,porta_table2[chan].freq) + else If (freq_table[chan] AND $1fff < porta_table2[chan].freq) then + portamento_up(chan,porta_table2[chan].speed,porta_table2[chan].freq); +end; + +procedure slide_volume_up(chan,slide: Byte); + +var + temp: Word; + limit1,limit2,vLo,vHi: Byte; + +procedure slide_carrier_volume_up; +begin + vLo := LO(temp); + vHi := HI(temp); + If (vHi-slide >= limit1) then temp := concw(vLo,vHi-slide) + else temp := concw(vLo,limit1); + set_ins_volume(BYTE_NULL,HI(temp),chan); + volume_table[chan] := temp; +end; + +procedure slide_modulator_volume_up; +begin + vLo := LO(temp); + vHi := HI(temp); + If (vLo-slide >= limit2) then temp := concw(vLo-slide,vHi) + else temp := concw(limit2,vHi); + set_ins_volume(LO(temp),BYTE_NULL,chan); + volume_table[chan] := temp; +end; + +begin + If NOT peak_lock[chan] then limit1 := 0 + else limit1 := ins_parameter(event_table[chan].instr_def,3) AND $3f; + + If NOT peak_lock[chan] then limit2 := 0 + else limit2 := ins_parameter(event_table[chan].instr_def,2) AND $3f; + temp := volume_table[chan]; + + Case volslide_type[chan] of + 0: begin + slide_carrier_volume_up; + If (ins_parameter(voice_table[chan],10) AND 1 = 1) or + (percussion_mode and (chan in [17..20])) then + slide_modulator_volume_up; + end; + 1: slide_carrier_volume_up; + 2: slide_modulator_volume_up; + 3: begin + slide_carrier_volume_up; + slide_modulator_volume_up; + end; + end; +end; + +procedure slide_volume_down(chan,slide: Byte); + +var + temp: Word; + vLo,vHi: Byte; + +procedure slide_carrier_volume_down; +begin + vLo := LO(temp); + vHi := HI(temp); + If (vHi+slide <= 63) then temp := concw(vLo,vHi+slide) + else temp := concw(vLo,63); + set_ins_volume(BYTE_NULL,HI(temp),chan); + volume_table[chan] := temp; +end; + +procedure slide_modulator_volume_down; +begin + vLo := LO(temp); + vHi := HI(temp); + If (vLo+slide <= 63) then temp := concw(vLo+slide,vHi) + else temp := concw(63,vHi); + set_ins_volume(LO(temp),BYTE_NULL,chan); + volume_table[chan] := temp; +end; + +begin + temp := volume_table[chan]; + Case volslide_type[chan] of + 0: begin + slide_carrier_volume_down; + If (ins_parameter(voice_table[chan],10) AND 1 = 1) or + (percussion_mode and (chan in [17..20])) then + slide_modulator_volume_down; + end; + 1: slide_carrier_volume_down; + 2: slide_modulator_volume_down; + 3: begin + slide_carrier_volume_down; + slide_modulator_volume_down; + end; + end; +end; + +procedure volume_slide(chan,up_speed,down_speed: Byte); +begin + If (up_speed <> 0) then slide_volume_up(chan,up_speed) + else If (down_speed <> 0) then slide_volume_down(chan,down_speed); +end; + +procedure global_volume_slide(up_speed,down_speed: Byte); +begin + If (up_speed <> BYTE_NULL) then + global_volume := max(global_volume+up_speed,63); + If (down_speed <> BYTE_NULL) then + If (global_volume >= down_speed) then Dec(global_volume,down_speed) + else global_volume := 0; + set_global_volume; +end; + +procedure arpeggio(chan: Byte); + +const + arpgg_state: array[0..2] of Byte = (1,2,0); + +var + freq: Word; + +begin + Case arpgg_table[chan].state of + 0: freq := nFreq(arpgg_table[chan].note-1); + 1: freq := nFreq(arpgg_table[chan].note-1 +arpgg_table[chan].add1); + 2: freq := nFreq(arpgg_table[chan].note-1 +arpgg_table[chan].add2); + end; + + arpgg_table[chan].state := arpgg_state[arpgg_table[chan].state]; + change_frequency(chan,freq+ + SHORTINT(ins_parameter(event_table[chan].instr_def,12))); +end; + +procedure arpeggio2(chan: Byte); + +const + arpgg_state: array[0..2] of Byte = (1,2,0); + +var + freq: Word; + +begin + Case arpgg_table2[chan].state of + 0: freq := nFreq(arpgg_table2[chan].note-1); + 1: freq := nFreq(arpgg_table2[chan].note-1 +arpgg_table2[chan].add1); + 2: freq := nFreq(arpgg_table2[chan].note-1 +arpgg_table2[chan].add2); + end; + + arpgg_table2[chan].state := arpgg_state[arpgg_table2[chan].state]; + change_frequency(chan,freq+ + SHORTINT(ins_parameter(event_table[chan].instr_def,12))); +end; + +procedure vibrato(chan: Byte); + +var + freq,old_freq: Word; + direction: Byte; + +begin + Inc(vibr_table[chan].pos,vibr_table[chan].speed*vibtrem_speed_factor); + freq := calc_vibtrem_shift(vibr_table[chan].depth, + vibr_table[chan].pos,direction); + old_freq := freq_table[chan]; + If (direction = 0) then portamento_down(chan,freq,nFreq(0)) + else portamento_up(chan,freq,nFreq(12*8+1)); + freq_table[chan] := old_freq; +end; + +procedure vibrato2(chan: Byte); + +var + freq,old_freq: Word; + direction: Byte; + +begin + Inc(vibr_table2[chan].pos,vibr_table2[chan].speed*vibtrem_speed_factor); + freq := calc_vibtrem_shift(vibr_table2[chan].depth, + vibr_table2[chan].pos,direction); + old_freq := freq_table[chan]; + If (direction = 0) then portamento_down(chan,freq,nFreq(0)) + else portamento_up(chan,freq,nFreq(12*8+1)); + freq_table[chan] := old_freq; +end; + +procedure tremolo(chan: Byte); + +var + vol,old_vol: Word; + direction: Byte; + +begin + Inc(trem_table[chan].pos,trem_table[chan].speed*vibtrem_speed_factor); + vol := calc_vibtrem_shift(trem_table[chan].depth, + trem_table[chan].pos,direction); + old_vol := volume_table[chan]; + If (direction = 0) then slide_volume_down(chan,vol) + else slide_volume_up(chan,vol); + volume_table[chan] := old_vol; +end; + +procedure tremolo2(chan: Byte); + +var + vol,old_vol: Word; + direction: Byte; + +begin + Inc(trem_table2[chan].pos,trem_table2[chan].speed*vibtrem_speed_factor); + vol := calc_vibtrem_shift(trem_table2[chan].depth, + trem_table2[chan].pos,direction); + old_vol := volume_table[chan]; + If (direction = 0) then slide_volume_down(chan,vol) + else slide_volume_up(chan,vol); + volume_table[chan] := old_vol; +end; + +procedure update_effects; + +var + chan,eLo,eHi, + eLo2,eHi2: Byte; + +function chanvol(chan: Byte): Byte; +begin + If (ins_parameter(voice_table[chan],10) AND 1 = 0) then chanvol := 63-HI(volume_table[chan]) + else chanvol := 63-Round((LO(volume_table[chan])+HI(volume_table[chan]))/2); +end; + +begin + For chan := 1 to songdata.nm_tracks do + begin + eLo := LO(effect_table[chan]); + eHi := HI(effect_table[chan]); + eLo2 := LO(effect_table2[chan]); + eHi2 := HI(effect_table2[chan]); + + Case eLo of + ef_Arpeggio+ef_fix1: + arpeggio(chan); + + ef_ArpggVSlide: + begin + volume_slide(chan,eHi DIV 16,eHi MOD 16); + arpeggio(chan); + end; + + ef_ArpggVSlideFine: + arpeggio(chan); + + ef_FSlideUp: + portamento_up(chan,eHi,nFreq(12*8+1)); + + ef_FSlideDown: + portamento_down(chan,eHi,nFreq(0)); + + ef_FSlideUpVSlide: + begin + portamento_up(chan,fslide_table[chan],nFreq(12*8+1)); + volume_slide(chan,eHi DIV 16,eHi MOD 16); + end; + + ef_FSlUpVSlF: + portamento_up(chan,fslide_table[chan],nFreq(12*8+1)); + + ef_FSlideDownVSlide: + begin + portamento_down(chan,fslide_table[chan],nFreq(0)); + volume_slide(chan,eHi DIV 16,eHi MOD 16); + end; + + ef_FSlDownVSlF: + portamento_down(chan,fslide_table[chan],nFreq(0)); + + ef_FSlUpFineVSlide: + volume_slide(chan,eHi DIV 16,eHi MOD 16); + + ef_FSlDownFineVSlide: + volume_slide(chan,eHi DIV 16,eHi MOD 16); + + ef_TonePortamento: + tone_portamento(chan); + + ef_TPortamVolSlide: + begin + volume_slide(chan,eHi DIV 16,eHi MOD 16); + tone_portamento(chan); + end; + + ef_TPortamVSlideFine: + tone_portamento(chan); + + ef_Vibrato: + If NOT vibr_table[chan].fine then + vibrato(chan); + + ef_Tremolo: + If NOT trem_table[chan].fine then + tremolo(chan); + + ef_VibratoVolSlide: + begin + volume_slide(chan,eHi DIV 16,eHi MOD 16); + If NOT vibr_table[chan].fine then + vibrato(chan); + end; + + ef_VibratoVSlideFine: + If NOT vibr_table[chan].fine then + vibrato(chan); + + ef_VolSlide: + volume_slide(chan,eHi DIV 16,eHi MOD 16); + + ef_RetrigNote: + If (retrig_table[chan] >= eHi) then + begin + retrig_table[chan] := 0; + output_note(event_table[chan].note, + event_table[chan].instr_def,chan,TRUE); + end + else Inc(retrig_table[chan]); + + ef_MultiRetrigNote: + If (retrig_table[chan] >= eHi DIV 16) then + begin + Case eHi MOD 16 of + 0,8: ; + + 1: slide_volume_down(chan,1); + 2: slide_volume_down(chan,2); + 3: slide_volume_down(chan,4); + 4: slide_volume_down(chan,8); + 5: slide_volume_down(chan,16); + + 9: slide_volume_up(chan,1); + 10: slide_volume_up(chan,2); + 11: slide_volume_up(chan,4); + 12: slide_volume_up(chan,8); + 13: slide_volume_up(chan,16); + + + 6: slide_volume_down(chan,chanvol(chan)- + Round(chanvol(chan)*2/3)); + 7: slide_volume_down(chan,chanvol(chan)- + Round(chanvol(chan)*1/2)); + + 14: slide_volume_up(chan,max(Round(chanvol(chan)*3/2)- + chanvol(chan),63)); + 15: slide_volume_up(chan,max(Round(chanvol(chan)*2)- + chanvol(chan),63)); + end; + + retrig_table[chan] := 0; + output_note(event_table[chan].note, + event_table[chan].instr_def,chan,TRUE); + end + else Inc(retrig_table[chan]); + + ef_Tremor: + If (tremor_table[chan].pos >= 0) then + begin + If (SUCC(tremor_table[chan].pos) <= eHi DIV 16) then + Inc(tremor_table[chan].pos) + else begin + slide_volume_down(chan,63); + tremor_table[chan].pos := -1; + end; + end + else If (PRED(tremor_table[chan].pos) >= -(eHi MOD 16)) then + Dec(tremor_table[chan].pos) + else begin + set_ins_volume(LO(tremor_table[chan].volume), + HI(tremor_table[chan].volume),chan); + tremor_table[chan].pos := 1; + end; + + ef_extended2+ef_fix2+ef_ex2_NoteDelay: + If (notedel_table[chan] = 0) then + begin + notedel_table[chan] := BYTE_NULL; + output_note(event_table[chan].note, + event_table[chan].instr_def,chan,TRUE); + end + else Dec(notedel_table[chan]); + + ef_extended2+ef_fix2+ef_ex2_NoteCut: + If (notecut_table[chan] = 0) then + begin + notecut_table[chan] := BYTE_NULL; + key_off(chan); + end + else Dec(notecut_table[chan]); + + ef_extended2+ef_fix2+ef_ex2_GlVolSlideUp: + global_volume_slide(eHi,BYTE_NULL); + + ef_extended2+ef_fix2+ef_ex2_GlVolSlideDn: + global_volume_slide(BYTE_NULL,eHi); + end; + + Case eLo2 of + ef_Arpeggio+ef_fix1: + arpeggio2(chan); + + ef_ArpggVSlide: + begin + volume_slide(chan,eHi2 DIV 16,eHi2 MOD 16); + arpeggio2(chan); + end; + + ef_ArpggVSlideFine: + arpeggio2(chan); + + ef_FSlideUp: + portamento_up(chan,eHi2,nFreq(12*8+1)); + + ef_FSlideDown: + portamento_down(chan,eHi2,nFreq(0)); + + ef_FSlideUpVSlide: + begin + portamento_up(chan,fslide_table2[chan],nFreq(12*8+1)); + volume_slide(chan,eHi2 DIV 16,eHi2 MOD 16); + end; + + ef_FSlUpVSlF: + portamento_up(chan,fslide_table2[chan],nFreq(12*8+1)); + + ef_FSlideDownVSlide: + begin + portamento_down(chan,fslide_table2[chan],nFreq(0)); + volume_slide(chan,eHi2 DIV 16,eHi2 MOD 16); + end; + + ef_FSlDownVSlF: + portamento_down(chan,fslide_table2[chan],nFreq(0)); + + ef_FSlUpFineVSlide: + volume_slide(chan,eHi2 DIV 16,eHi2 MOD 16); + + ef_FSlDownFineVSlide: + volume_slide(chan,eHi2 DIV 16,eHi2 MOD 16); + + ef_TonePortamento: + tone_portamento2(chan); + + ef_TPortamVolSlide: + begin + volume_slide(chan,eHi2 DIV 16,eHi2 MOD 16); + tone_portamento2(chan); + end; + + ef_TPortamVSlideFine: + tone_portamento2(chan); + + ef_Vibrato: + If NOT vibr_table2[chan].fine then + vibrato2(chan); + + ef_Tremolo: + If NOT trem_table2[chan].fine then + tremolo2(chan); + + ef_VibratoVolSlide: + begin + volume_slide(chan,eHi2 DIV 16,eHi2 MOD 16); + If NOT vibr_table2[chan].fine then + vibrato2(chan); + end; + + ef_VibratoVSlideFine: + If NOT vibr_table2[chan].fine then + vibrato2(chan); + + ef_VolSlide: + volume_slide(chan,eHi2 DIV 16,eHi2 MOD 16); + + ef_RetrigNote: + If (retrig_table2[chan] >= eHi2) then + begin + retrig_table2[chan] := 0; + output_note(event_table[chan].note, + event_table[chan].instr_def,chan,TRUE); + end + else Inc(retrig_table2[chan]); + + ef_MultiRetrigNote: + If (retrig_table2[chan] >= eHi2 DIV 16) then + begin + Case eHi2 MOD 16 of + 0,8: ; + + 1: slide_volume_down(chan,1); + 2: slide_volume_down(chan,2); + 3: slide_volume_down(chan,4); + 4: slide_volume_down(chan,8); + 5: slide_volume_down(chan,16); + + 9: slide_volume_up(chan,1); + 10: slide_volume_up(chan,2); + 11: slide_volume_up(chan,4); + 12: slide_volume_up(chan,8); + 13: slide_volume_up(chan,16); + + + 6: slide_volume_down(chan,chanvol(chan)- + Round(chanvol(chan)*2/3)); + 7: slide_volume_down(chan,chanvol(chan)- + Round(chanvol(chan)*1/2)); + + 14: slide_volume_up(chan,max(Round(chanvol(chan)*3/2)- + chanvol(chan),63)); + 15: slide_volume_up(chan,max(Round(chanvol(chan)*2)- + chanvol(chan),63)); + end; + + retrig_table2[chan] := 0; + output_note(event_table[chan].note, + event_table[chan].instr_def,chan,TRUE); + end + else Inc(retrig_table2[chan]); + + ef_Tremor: + If (tremor_table2[chan].pos >= 0) then + begin + If (SUCC(tremor_table2[chan].pos) <= eHi2 DIV 16) then + Inc(tremor_table2[chan].pos) + else begin + slide_volume_down(chan,63); + tremor_table2[chan].pos := -1; + end; + end + else If (PRED(tremor_table2[chan].pos) >= -(eHi2 MOD 16)) then + Dec(tremor_table2[chan].pos) + else begin + set_ins_volume(LO(tremor_table2[chan].volume), + HI(tremor_table2[chan].volume),chan); + tremor_table2[chan].pos := 1; + end; + + ef_extended2+ef_fix2+ef_ex2_NoteDelay: + If (notedel_table[chan] = 0) then + begin + notedel_table[chan] := BYTE_NULL; + output_note(event_table[chan].note, + event_table[chan].instr_def,chan,TRUE); + end + else Dec(notedel_table[chan]); + + ef_extended2+ef_fix2+ef_ex2_NoteCut: + If (notecut_table[chan] = 0) then + begin + notecut_table[chan] := BYTE_NULL; + key_off(chan); + end + else Dec(notecut_table[chan]); + + ef_extended2+ef_fix2+ef_ex2_GlVolSlideUp: + global_volume_slide(eHi2,BYTE_NULL); + + ef_extended2+ef_fix2+ef_ex2_GlVolSlideDn: + global_volume_slide(BYTE_NULL,eHi2); + end; + end; +end; + +procedure update_fine_effects(chan: Byte); + +var + eLo,eHi, + eLo2,eHi2: Byte; + +begin + eLo := LO(effect_table[chan]); + eHi := HI(effect_table[chan]); + eLo2 := LO(effect_table2[chan]); + eHi2 := HI(effect_table2[chan]); + + Case eLo of + ef_ArpggVSlideFine: + volume_slide(chan,eHi DIV 16,eHi MOD 16); + + ef_FSlideUpFine: + portamento_up(chan,eHi,nFreq(12*8+1)); + + ef_FSlideDownFine: + portamento_down(chan,eHi,nFreq(0)); + + ef_FSlUpVSlF: + volume_slide(chan,eHi DIV 16,eHi MOD 16); + + ef_FSlDownVSlF: + volume_slide(chan,eHi DIV 16,eHi MOD 16); + + ef_FSlUpFineVSlide: + portamento_up(chan,fslide_table[chan],nFreq(12*8+1)); + + ef_FSlUpFineVSlF: + begin + portamento_up(chan,fslide_table[chan],nFreq(12*8+1)); + volume_slide(chan,eHi DIV 16,eHi MOD 16); + end; + + ef_FSlDownFineVSlide: + portamento_down(chan,fslide_table[chan],nFreq(0)); + + ef_FSlDownFineVSlF: + begin + portamento_down(chan,fslide_table[chan],nFreq(0)); + volume_slide(chan,eHi DIV 16,eHi MOD 16); + end; + + ef_TPortamVSlideFine: + volume_slide(chan,eHi DIV 16,eHi MOD 16); + + ef_Vibrato: + If vibr_table[chan].fine then + vibrato(chan); + + ef_Tremolo: + If trem_table[chan].fine then + tremolo(chan); + + ef_VibratoVolSlide: + If vibr_table[chan].fine then + vibrato(chan); + + ef_VibratoVSlideFine: + begin + volume_slide(chan,eHi DIV 16,eHi MOD 16); + If vibr_table[chan].fine then + vibrato(chan); + end; + + ef_VolSlideFine: + volume_slide(chan,eHi DIV 16,eHi MOD 16); + + ef_extended2+ef_fix2+ef_ex2_GlVolSlideUpF: + global_volume_slide(eHi,BYTE_NULL); + + ef_extended2+ef_fix2+ef_ex2_GlVolSlideDnF: + global_volume_slide(BYTE_NULL,eHi); + end; + + Case eLo2 of + ef_ArpggVSlideFine: + volume_slide(chan,eHi2 DIV 16,eHi2 MOD 16); + + ef_FSlideUpFine: + portamento_up(chan,eHi2,nFreq(12*8+1)); + + ef_FSlideDownFine: + portamento_down(chan,eHi2,nFreq(0)); + + ef_FSlUpVSlF: + volume_slide(chan,eHi2 DIV 16,eHi2 MOD 16); + + ef_FSlDownVSlF: + volume_slide(chan,eHi2 DIV 16,eHi2 MOD 16); + + ef_FSlUpFineVSlide: + portamento_up(chan,fslide_table2[chan],nFreq(12*8+1)); + + ef_FSlUpFineVSlF: + begin + portamento_up(chan,fslide_table2[chan],nFreq(12*8+1)); + volume_slide(chan,eHi2 DIV 16,eHi2 MOD 16); + end; + + ef_FSlDownFineVSlide: + portamento_down(chan,fslide_table2[chan],nFreq(0)); + + ef_FSlDownFineVSlF: + begin + portamento_down(chan,fslide_table2[chan],nFreq(0)); + volume_slide(chan,eHi2 DIV 16,eHi2 MOD 16); + end; + + ef_TPortamVSlideFine: + volume_slide(chan,eHi2 DIV 16,eHi2 MOD 16); + + ef_Vibrato: + If vibr_table2[chan].fine then + vibrato2(chan); + + ef_Tremolo: + If trem_table2[chan].fine then + tremolo2(chan); + + ef_VibratoVolSlide: + If vibr_table2[chan].fine then + vibrato2(chan); + + ef_VibratoVSlideFine: + begin + volume_slide(chan,eHi2 DIV 16,eHi2 MOD 16); + If vibr_table2[chan].fine then + vibrato2(chan); + end; + + ef_VolSlideFine: + volume_slide(chan,eHi2 DIV 16,eHi2 MOD 16); + + ef_extended2+ef_fix2+ef_ex2_GlVolSlideUpF: + global_volume_slide(eHi2,BYTE_NULL); + + ef_extended2+ef_fix2+ef_ex2_GlVolSlideDnF: + global_volume_slide(BYTE_NULL,eHi2); + end; +end; + +procedure update_extra_fine_effects; + +var + chan,eLo,eHi, + eLo2,eHi2: Byte; + +begin + For chan := 1 to songdata.nm_tracks do + begin + eLo := LO(effect_table[chan]); + eHi := HI(effect_table[chan]); + eLo2 := LO(effect_table2[chan]); + eHi2 := HI(effect_table2[chan]); + + Case eLo of + ef_extended2+ef_fix2+ef_ex2_GlVolSldUpXF: + global_volume_slide(eHi,BYTE_NULL); + + ef_extended2+ef_fix2+ef_ex2_GlVolSldDnXF: + global_volume_slide(BYTE_NULL,eHi); + + ef_extended2+ef_fix2+ef_ex2_VolSlideUpXF: + volume_slide(chan,eHi,0); + + ef_extended2+ef_fix2+ef_ex2_VolSlideDnXF: + volume_slide(chan,0,eHi); + + ef_extended2+ef_fix2+ef_ex2_FreqSlideUpXF: + portamento_up(chan,eHi,nFreq(12*8+1)); + + ef_extended2+ef_fix2+ef_ex2_FreqSlideDnXF: + portamento_down(chan,eHi,nFreq(0)); + + ef_ExtraFineArpeggio: + arpeggio(chan); + + ef_ExtraFineVibrato: + If NOT vibr_table[chan].fine then + vibrato(chan); + + ef_ExtraFineTremolo: + If NOT trem_table[chan].fine then + tremolo(chan); + end; + + Case eLo2 of + ef_extended2+ef_fix2+ef_ex2_GlVolSldUpXF: + global_volume_slide(eHi2,BYTE_NULL); + + ef_extended2+ef_fix2+ef_ex2_GlVolSldDnXF: + global_volume_slide(BYTE_NULL,eHi2); + + ef_extended2+ef_fix2+ef_ex2_VolSlideUpXF: + volume_slide(chan,eHi2,0); + + ef_extended2+ef_fix2+ef_ex2_VolSlideDnXF: + volume_slide(chan,0,eHi2); + + ef_extended2+ef_fix2+ef_ex2_FreqSlideUpXF: + portamento_up(chan,eHi2,nFreq(12*8+1)); + + ef_extended2+ef_fix2+ef_ex2_FreqSlideDnXF: + portamento_down(chan,eHi2,nFreq(0)); + + ef_ExtraFineArpeggio: + arpeggio2(chan); + + ef_ExtraFineVibrato: + If NOT vibr_table2[chan].fine then + vibrato2(chan); + + ef_ExtraFineTremolo: + If NOT trem_table2[chan].fine then + tremolo2(chan); + end; + end; +end; + +function calc_following_order(order: Byte): Integer; + +var + result: Integer; + index,jump_count: Byte; + +begin + _debug_str_ := 'A2PLAYER.PAS:calc_following_order'; + result := -1; + index := order; + jump_count := 0; + + Repeat + If (songdata.pattern_order[index] < $80) then result := index + else begin + index := songdata.pattern_order[index]-$80; + Inc(jump_count); + end; + until (jump_count > $7f) or + (result <> -1); + + calc_following_order := result; +end; + +function calc_order_jump: Integer; + +var + temp: Byte; + result: Integer; + +begin + _debug_str_ := 'A2PLAYER.PAS:calc_order_jump'; + result := 0; + temp := 0; + + Repeat + If (songdata.pattern_order[current_order] > $7f) then + current_order := songdata.pattern_order[current_order]-$80; + Inc(temp); + until (temp > $7f) or (songdata.pattern_order[current_order] < $80); + + If (temp > $7f) then begin stop_playing; result := -1; end; + calc_order_jump := result; +end; + +procedure update_song_position; + +var + temp: Byte; + +begin + _debug_str_ := 'A2PLAYER.PAS:update_song_position'; + If (current_line < PRED(songdata.patt_len)) and NOT pattern_break then Inc(current_line) + else begin + If NOT (pattern_break and (next_line AND $0f0 = pattern_loop_flag)) and + (current_order < $7f) then + begin + FillChar(loopbck_table,SizeOf(loopbck_table),BYTE_NULL); + FillChar(loop_table,SizeOf(loop_table),BYTE_NULL); + Inc(current_order); + end; + + If pattern_break and (next_line AND $0f0 = pattern_loop_flag) then + begin + temp := next_line-pattern_loop_flag; + next_line := loopbck_table[temp]; + If (loop_table[temp][current_line] <> 0) then + Dec(loop_table[temp][current_line]); + end + else If pattern_break and (next_line AND $0f0 = pattern_break_flag) then + begin + current_order := event_table[next_line-pattern_break_flag].effect; + pattern_break := FALSE; + end + else If (current_order > $7f) then + current_order := 0; + + If (songdata.pattern_order[current_order] > $7f) then + If (calc_order_jump = -1) then EXIT; + + current_pattern := songdata.pattern_order[current_order]; + If NOT pattern_break then current_line := 0 + else begin + pattern_break := FALSE; + current_line := next_line; + end; + end; + + For temp := 1 to songdata.nm_tracks do + begin + glfsld_table[temp] := 0; + glfsld_table2[temp] := 0; + end; + + If (current_line = 0) and + (current_order = calc_following_order(0)) and speed_update then + begin + tempo := songdata.tempo; + speed := songdata.speed; + update_timer(tempo); + end; +end; + +procedure poll_proc; + +var + temp: Byte; + +var + _debug_str_bak_: String; + +begin + _debug_str_bak_ := _debug_str_; + _debug_str_ := 'A2PLAYER.PAS:_poll_proc'; + + If (NOT pattern_delay and (ticks-tick0+1 >= speed)) or + fast_forward then + begin + If (songdata.pattern_order[current_order] > $7f) then + If (calc_order_jump = -1) then EXIT; + + current_pattern := songdata.pattern_order[current_order]; + play_line; + If NOT fast_forward then update_effects + else For temp := 1 to speed do + begin + update_effects; + If (temp MOD 4 = temp) then + update_extra_fine_effects; + Inc(ticks); + end; + + If fast_forward or NOT pattern_delay then + update_song_position; + + tick0 := ticks; + If fast_forward then + If NOT pattern_delay then synchronize_song_timer; + + If fast_forward and pattern_delay then + begin + tickD := 0; + pattern_delay := FALSE; + end; + + If fast_forward then fast_forward := FALSE; + end + else + begin + update_effects; + Inc(ticks); + If pattern_delay and (tickD > 1) then Dec(tickD) + else begin + If pattern_delay then + begin + tick0 := ticks; + update_song_position; + end; + pattern_delay := FALSE; + end; + end; + + Inc(tickXF); + If (tickXF MOD 4 = 0) then + begin + update_extra_fine_effects; + Dec(tickXF,4); + end; + _debug_str_ := _debug_str_bak_; +end; + +procedure macro_poll_proc; + +const + IDLE = $0fff; + FINISHED = $0ffff; + +var + chan: Byte; + finished_flag: Word; + +var + _debug_str_bak_: String; + +function _ins_adsr_data_empty(ins: Byte): Boolean; +begin + _ins_adsr_data_empty := + (ins_parameter(ins,5) SHR 4 = 0) and + (ins_parameter(ins,4) SHR 4 = 0) and + (ins_parameter(ins,5) AND $0f = 0) and + (ins_parameter(ins,4) AND $0f = 0) and + (ins_parameter(ins,7) SHR 4 = 0) and + (ins_parameter(ins,6) SHR 4 = 0) and + (ins_parameter(ins,7) AND $0f = 0) and + (ins_parameter(ins,6) AND $0f = 0); +end; + +begin + _debug_str_bak_ := _debug_str_; + _debug_str_ := 'ADT2UNIT.PAS:macro_poll_proc'; + For chan := 1 to songdata.nm_tracks do + begin + If NOT keyoff_loop[chan] then finished_flag := FINISHED + else finished_flag := IDLE; + + With macro_table[chan] do + begin + With songdata.instr_macros[fmreg_table] do + If (fmreg_table <> 0) and (speed <> 0) then + If (fmreg_duration > 1) then Dec(fmreg_duration) + else begin + fmreg_count := 1; + If (fmreg_pos <= length) then + If (loop_begin <> 0) and (loop_length <> 0) then + If (fmreg_pos = loop_begin+PRED(loop_length)) then + fmreg_pos := loop_begin + else If (fmreg_pos < length) then Inc(fmreg_pos) + else fmreg_pos := finished_flag + else If (fmreg_pos < length) then Inc(fmreg_pos) + else fmreg_pos := finished_flag + else fmreg_pos := finished_flag; + + If (freq_table[chan] OR $2000 = freq_table[chan]) and + (keyoff_pos <> 0) and + (fmreg_pos >= keyoff_pos) then + fmreg_pos := IDLE + else If (freq_table[chan] OR $2000 <> freq_table[chan]) and + (fmreg_pos <> 0) and (keyoff_pos <> 0) and + ((fmreg_pos < keyoff_pos) or (fmreg_pos = IDLE)) then + fmreg_pos := keyoff_pos; + + If (fmreg_pos <> 0) and + (fmreg_pos <> IDLE) and (fmreg_pos <> finished_flag) then + begin + fmreg_duration := data[fmreg_pos].duration; + If (fmreg_duration <> 0) then + With data[fmreg_pos] do + begin + // force KEY-ON with missing ADSR instrument data + force_macro_keyon := FALSE; + If (fmreg_pos = 1) then + If _ins_adsr_data_empty(voice_table[chan]) and + NOT (songdata.dis_fmreg_col[fmreg_table][0] and + songdata.dis_fmreg_col[fmreg_table][1] and + songdata.dis_fmreg_col[fmreg_table][2] and + songdata.dis_fmreg_col[fmreg_table][3] and + songdata.dis_fmreg_col[fmreg_table][12] and + songdata.dis_fmreg_col[fmreg_table][13] and + songdata.dis_fmreg_col[fmreg_table][14] and + songdata.dis_fmreg_col[fmreg_table][15]) then + force_macro_keyon := TRUE; + + If NOT songdata.dis_fmreg_col[fmreg_table][0] then + fmpar_table[chan].adsrw_mod.attck := fm_data.ATTCK_DEC_modulator SHR 4; + + If NOT songdata.dis_fmreg_col[fmreg_table][1] then + fmpar_table[chan].adsrw_mod.dec := fm_data.ATTCK_DEC_modulator AND $0f; + + If NOT songdata.dis_fmreg_col[fmreg_table][2] then + fmpar_table[chan].adsrw_mod.sustn := fm_data.SUSTN_REL_modulator SHR 4; + + If NOT songdata.dis_fmreg_col[fmreg_table][3] then + fmpar_table[chan].adsrw_mod.rel := fm_data.SUSTN_REL_modulator AND $0f; + + If NOT songdata.dis_fmreg_col[fmreg_table][4] then + fmpar_table[chan].adsrw_mod.wform := fm_data.WAVEFORM_modulator AND $07; + + If NOT songdata.dis_fmreg_col[fmreg_table][6] then + fmpar_table[chan].kslM := fm_data.KSL_VOLUM_modulator SHR 6; + + If NOT songdata.dis_fmreg_col[fmreg_table][7] then + fmpar_table[chan].multipM := fm_data.AM_VIB_EG_modulator AND $0f; + + If NOT songdata.dis_fmreg_col[fmreg_table][8] then + fmpar_table[chan].tremM := fm_data.AM_VIB_EG_modulator SHR 7; + + If NOT songdata.dis_fmreg_col[fmreg_table][9] then + fmpar_table[chan].vibrM := fm_data.AM_VIB_EG_modulator SHR 6 AND 1; + + If NOT songdata.dis_fmreg_col[fmreg_table][10] then + fmpar_table[chan].ksrM := fm_data.AM_VIB_EG_modulator SHR 4 AND 1; + + If NOT songdata.dis_fmreg_col[fmreg_table][11] then + fmpar_table[chan].sustM := fm_data.AM_VIB_EG_modulator SHR 5 AND 1; + + If NOT songdata.dis_fmreg_col[fmreg_table][12] then + fmpar_table[chan].adsrw_car.attck := fm_data.ATTCK_DEC_carrier SHR 4; + + If NOT songdata.dis_fmreg_col[fmreg_table][13] then + fmpar_table[chan].adsrw_car.dec := fm_data.ATTCK_DEC_carrier AND $0f; + + If NOT songdata.dis_fmreg_col[fmreg_table][14] then + fmpar_table[chan].adsrw_car.sustn := fm_data.SUSTN_REL_carrier SHR 4; + + If NOT songdata.dis_fmreg_col[fmreg_table][15] then + fmpar_table[chan].adsrw_car.rel := fm_data.SUSTN_REL_carrier AND $0f; + + If NOT songdata.dis_fmreg_col[fmreg_table][16] then + fmpar_table[chan].adsrw_car.wform := fm_data.WAVEFORM_carrier AND $07; + + If NOT songdata.dis_fmreg_col[fmreg_table][18] then + fmpar_table[chan].kslC := fm_data.KSL_VOLUM_carrier SHR 6; + + If NOT songdata.dis_fmreg_col[fmreg_table][19] then + fmpar_table[chan].multipC := fm_data.AM_VIB_EG_carrier AND $0f; + + If NOT songdata.dis_fmreg_col[fmreg_table][20] then + fmpar_table[chan].tremC := fm_data.AM_VIB_EG_carrier SHR 7; + + If NOT songdata.dis_fmreg_col[fmreg_table][21] then + fmpar_table[chan].vibrC := fm_data.AM_VIB_EG_carrier SHR 6 AND 1; + + If NOT songdata.dis_fmreg_col[fmreg_table][22] then + fmpar_table[chan].ksrC := fm_data.AM_VIB_EG_carrier SHR 4 AND 1; + + If NOT songdata.dis_fmreg_col[fmreg_table][23] then + fmpar_table[chan].sustC := fm_data.AM_VIB_EG_carrier SHR 5 AND 1; + + If NOT songdata.dis_fmreg_col[fmreg_table][24] then + fmpar_table[chan].connect := fm_data.FEEDBACK_FM AND 1; + + If NOT songdata.dis_fmreg_col[fmreg_table][25] then + fmpar_table[chan].feedb := fm_data.FEEDBACK_FM SHR 1 AND 7; + + If NOT songdata.dis_fmreg_col[fmreg_table][27] then + If NOT pan_lock[chan] then + panning_table[chan] := panning; + + If NOT songdata.dis_fmreg_col[fmreg_table][5] then + set_ins_volume(63-fm_data.KSL_VOLUM_modulator AND $3f, + BYTE_NULL,chan); + + If NOT songdata.dis_fmreg_col[fmreg_table][17] then + set_ins_volume(BYTE_NULL, + 63-fm_data.KSL_VOLUM_carrier AND $3f,chan); + + update_modulator_adsrw(chan); + update_carrier_adsrw(chan); + update_fmpar(chan); + + If force_macro_keyon or + NOT (fm_data.FEEDBACK_FM OR $80 <> fm_data.FEEDBACK_FM) then + output_note(event_table[chan].note, + event_table[chan].instr_def,chan,FALSE); + + If NOT songdata.dis_fmreg_col[fmreg_table][26] then + If (freq_slide > 0) then + portamento_up(chan,freq_slide,nFreq(12*8+1)) + else If (freq_slide < 0) then + portamento_down(chan,Abs(freq_slide),nFreq(0)); + end; + end; + end; + + With songdata.macro_table[arpg_table].arpeggio do + If (arpg_table <> 0) and (speed <> 0) then + If (arpg_count = speed) then + begin + arpg_count := 1; + If (arpg_pos <= length) then + If (loop_begin <> 0) and (loop_length <> 0) then + If (arpg_pos = loop_begin+PRED(loop_length)) then + arpg_pos := loop_begin + else If (arpg_pos < length) then Inc(arpg_pos) + else arpg_pos := finished_flag + else If (arpg_pos < length) then Inc(arpg_pos) + else arpg_pos := finished_flag + else arpg_pos := finished_flag; + + If (freq_table[chan] OR $2000 = freq_table[chan]) and + (keyoff_pos <> 0) and + (arpg_pos >= keyoff_pos) then + arpg_pos := IDLE + else If (freq_table[chan] OR $2000 <> freq_table[chan]) and + (keyoff_pos <> 0) and (keyoff_pos <> 0) and + ((arpg_pos < keyoff_pos) or (arpg_pos = IDLE)) then + arpg_pos := keyoff_pos; + + If (arpg_pos <> 0) and + (arpg_pos <> IDLE) and (arpg_pos <> finished_flag) then + Case data[arpg_pos] of + 0: change_frequency(chan, + nFreq(arpg_note-1)+ + SHORTINT(ins_parameter(event_table[chan].instr_def,12))); + + 1..96: + change_frequency(chan, + nFreq(max(arpg_note+data[arpg_pos],97)-1)+ + SHORTINT(ins_parameter(event_table[chan].instr_def,12))); + + $80..$80+12*8+1: + change_frequency(chan,nFreq(data[arpg_pos]-$80-1)+ + SHORTINT(ins_parameter(event_table[chan].instr_def,12))); + end; + end + else Inc(arpg_count); + + With songdata.macro_table[vib_table].vibrato do + If NOT vib_paused and + (vib_table <> 0) and (speed <> 0) then + If (vib_count = speed) then + If (vib_delay <> 0) then Dec(vib_delay) + else begin + vib_count := 1; + If (vib_pos <= length) then + If (loop_begin <> 0) and (loop_length <> 0) then + If (vib_pos = loop_begin+PRED(loop_length)) then + vib_pos := loop_begin + else If (vib_pos < length) then Inc(vib_pos) + else vib_pos := finished_flag + else If (vib_pos < length) then Inc(vib_pos) + else vib_pos := finished_flag + else vib_pos := finished_flag; + + If (freq_table[chan] OR $2000 = freq_table[chan]) and + (keyoff_pos <> 0) and + (vib_pos >= keyoff_pos) then + vib_pos := IDLE + else If (freq_table[chan] OR $2000 <> freq_table[chan]) and + (vib_pos <> 0) and (keyoff_pos <> 0) and + ((vib_pos < keyoff_pos) or (vib_pos = IDLE)) then + vib_pos := keyoff_pos; + + If (vib_pos <> 0) and + (vib_pos <> IDLE) and (vib_pos <> finished_flag) then + If (data[vib_pos] > 0) then + macro_vibrato__porta_up(chan,data[vib_pos]) + else If (data[vib_pos] < 0) then + macro_vibrato__porta_down(chan,Abs(data[vib_pos])) + else change_freq(chan,vib_freq); + end + else Inc(vib_count); + end; + end; + _debug_str_ := _debug_str_bak_; +end; + +var + ticklooper, + macro_ticklooper: Longint; + +procedure timer_poll_proc; + +var + _debug_str_bak_: String; + +begin + _debug_str_bak_ := _debug_str_; + _debug_str_ := 'A2PLAYER.PAS:timer_poll_proc'; + + If (timer_det < IRQ_freq DIV 200) then Inc(timer_det) + else begin + timer_det := 1; + Inc(_delay_counter); + end; + + If (current_order = 0) and (current_line = 0) and + (tick0 = ticks) then + begin + song_timer := 0; + timer_temp := 0; + song_timer_tenths := 0; + end; + + If (play_status = isPlaying) then + begin + song_timer_tenths := Trunc(100/IRQ_freq*timer_temp); + If (song_timer_tenths = 100) then song_timer_tenths := 0; + If (timer_temp < IRQ_freq) then Inc(timer_temp) + else begin + Inc(song_timer); + timer_temp := 1; + end; + end; + + If (song_timer > 3600-1) then + begin + song_timer := 0; + timer_temp := 0; + song_timer_tenths := 0; + end; + + If (ticklooper = 0) and NOT replay_forbidden then + poll_proc; + + If (macro_ticklooper = 0) then + macro_poll_proc; + + Inc(ticklooper); + If (ticklooper >= IRQ_freq DIV tempo) or fast_forward then + ticklooper := 0; + + Inc(macro_ticklooper); + If (macro_ticklooper >= IRQ_freq DIV (tempo*_macro_speedup)) then + macro_ticklooper := 0; + + _debug_str_ := _debug_str_bak_; +end; + +procedure newtimer; +begin + _debug_str_ := 'A2PLAYER.PAS:newtimer'; + If irq_mode then timer_poll_proc; + If (@external_irq_hook <> NIL) then external_irq_hook; +end; + +procedure init_irq; +begin + _debug_str_ := 'A2PLAYER.PAS:init_irq'; + If irq_initialized then EXIT; + irq_initialized := TRUE; + TimerInstallHandler(@newtimer); + TimerSetup(50); +end; + +procedure done_irq; +begin + _debug_str_ := 'A2PLAYER.PAS:done_irq'; + If NOT irq_initialized then EXIT; + irq_initialized := FALSE; + irq_mode := TRUE; + TimerDone; + TimerRemoveHandler; + irq_mode := FALSE; +end; + +function calc_pattern_pos(pattern: Byte): Byte; + +var + index: Integer; + jump_count,pattern_pos: Byte; + +begin + _debug_str_ := 'A2PLAYER.PAS:calc_pattern_pos'; + pattern_pos := BYTE_NULL; + jump_count := 0; + index := calc_following_order(0); + While (index <> -1) and (jump_count < $7f) do + If (songdata.pattern_order[index] <> pattern) then + If NOT (index < $7f) then BREAK + else begin + Inc(index); + index := calc_following_order(index); + Inc(jump_count); + end + else begin + pattern_pos := index; + BREAK; + end; + calc_pattern_pos := pattern_pos; +end; + +procedure init_buffers; + +var + temp: Byte; + +begin + _debug_str_ := 'A2PLAYER.PAS:init_buffers'; + FillChar(fmpar_table,SizeOf(fmpar_table),0); + FillChar(pan_lock,SizeOf(pan_lock),BYTE(panlock)); + FillChar(volume_table,SizeOf(volume_table),0); + FillChar(vscale_table,SizeOf(vscale_table),0); + FillChar(modulator_vol,SizeOf(modulator_vol),0); + FillChar(carrier_vol,SizeOf(carrier_vol),0); + FillChar(event_table,SizeOf(event_table),0); + FillChar(freq_table,SizeOf(freq_table),0); + FillChar(effect_table,SizeOf(effect_table),0); + FillChar(effect_table2,SizeOf(effect_table2),0); + FillChar(fslide_table,SizeOf(fslide_table),0); + FillChar(fslide_table2,SizeOf(fslide_table2),0); + FillChar(glfsld_table,SizeOf(glfsld_table),0); + FillChar(glfsld_table2,SizeOf(glfsld_table2),0); + FillChar(porta_table,SizeOf(porta_table),0); + FillChar(porta_table2,SizeOf(porta_table2),0); + FillChar(arpgg_table,SizeOf(arpgg_table),0); + FillChar(arpgg_table2,SizeOf(arpgg_table2),0); + FillChar(vibr_table,SizeOf(vibr_table),0); + FillChar(vibr_table2,SizeOf(vibr_table2),0); + FillChar(trem_table,SizeOf(trem_table),0); + FillChar(trem_table2,SizeOf(trem_table2),0); + FillChar(retrig_table,SizeOf(retrig_table),0); + FillChar(retrig_table2,SizeOf(retrig_table2),0); + FillChar(tremor_table,SizeOf(tremor_table),0); + FillChar(tremor_table2,SizeOf(tremor_table2),0); + FillChar(panning_table,SizeOf(panning_table),0); + FillChar(last_effect,SizeOf(last_effect),0); + FillChar(last_effect2,SizeOf(last_effect2),0); + FillChar(voice_table,SizeOf(voice_table),0); + FillChar(event_new,SizeOf(event_new),0); + FillChar(notedel_table,SizeOf(notedel_table),BYTE_NULL); + FillChar(notecut_table,SizeOf(notecut_table),BYTE_NULL); + FillChar(ftune_table,SizeOf(ftune_table),0); + FillChar(loopbck_table,SizeOf(loopbck_table),BYTE_NULL); + FillChar(loop_table,SizeOf(loop_table),BYTE_NULL); + FillChar(reset_chan,SizeOf(reset_chan),BYTE(FALSE)); + FillChar(keyoff_loop,SizeOf(keyoff_loop),BYTE(FALSE)); + FillChar(macro_table,SizeOf(macro_table),0); + + If NOT lockvol then FillChar(volume_lock,SizeOf(volume_lock),0) + else For temp := 1 to 20 do volume_lock[temp] := BOOLEAN(songdata.lock_flags[temp] SHR 4 AND 1); + + If NOT panlock then FillChar(panning_table,SizeOf(panning_table),0) + else For temp := 1 to 20 do panning_table[temp] := songdata.lock_flags[temp] AND 3; + + If NOT lockVP then FillChar(peak_lock,SizeOf(peak_lock),0) + else For temp := 1 to 20 do peak_lock[temp] := BOOLEAN(songdata.lock_flags[temp] SHR 5 AND 1); + + For temp := 1 to 20 do + volslide_type[temp] := songdata.lock_flags[temp] SHR 2 AND 3; +end; + +procedure init_player; + +var + temp: Byte; + +begin + _debug_str_ := 'A2PLAYER.PAS:init_player'; + opl2out($01,0); + + For temp := 1 to 18 do opl2out($0b0+_chan_n[temp],0); + For temp := $080 to $08d do opl2out(temp,BYTE_NULL); + For temp := $090 to $095 do opl2out(temp,BYTE_NULL); + + speed_update := BOOLEAN(songdata.common_flag AND 1); + lockvol := BOOLEAN(songdata.common_flag SHR 1 AND 1); + lockVP := BOOLEAN(songdata.common_flag SHR 2 AND 1); + tremolo_depth := songdata.common_flag SHR 3 AND 1; + vibrato_depth := songdata.common_flag SHR 4 AND 1; + panlock := BOOLEAN(songdata.common_flag SHR 5 AND 1); + percussion_mode := BOOLEAN(songdata.common_flag SHR 6 AND 1); + volume_scaling := BOOLEAN(songdata.common_flag SHR 7 AND 1); + + current_tremolo_depth := tremolo_depth; + current_vibrato_depth := vibrato_depth; + init_buffers; + + If NOT percussion_mode then + begin + _chan_n := _chmm_n; + _chan_m := _chmm_m; + _chan_c := _chmm_c; + end + else + begin + _chan_n := _chpm_n; + _chan_m := _chpm_m; + _chan_c := _chpm_c; + end; + + misc_register := tremolo_depth SHL 7+ + vibrato_depth SHL 6+ + BYTE(percussion_mode) SHL 5; + + opl2out($01,$20); + opl2out($08,$40); + opl3exp($0105); + opl3exp($04+songdata.flag_4op SHL 8); + + key_off(17); + key_off(18); + opl2out(_instr[11],misc_register); + + current_tremolo_depth := tremolo_depth; + current_vibrato_depth := vibrato_depth; + global_volume := 63; + vibtrem_speed_factor := def_vibtrem_speed_factor; + vibtrem_table_size := def_vibtrem_table_size; + Move(def_vibtrem_table,vibtrem_table,SizeOf(vibtrem_table)); + + For temp := 1 to 20 do + begin + arpgg_table[temp].state := 1; + voice_table[temp] := temp; + end; +end; + +procedure stop_playing; + +var + temp: Byte; + +begin + _debug_str_ := 'A2PLAYER.PAS:stop_playing'; + irq_mode := FALSE; + play_status := isStopped; + global_volume := 63; + current_tremolo_depth := tremolo_depth; + current_vibrato_depth := vibrato_depth; + pattern_break := FALSE; + current_order := 0; + current_pattern := 0; + current_line := 0; + song_timer := 0; + timer_temp := 0; + song_timer_tenths := 0; + + For temp := 1 to 20 do release_sustaining_sound(temp); + opl2out(_instr[11],0); + opl3exp($0004); + opl3exp($0005); + init_buffers; + + speed := songdata.speed; + update_timer(songdata.tempo); +end; + +procedure init_old_songdata; +begin + _debug_str_ := 'A2PLAYER.PAS:init_old_songdata'; + FillChar(old_songdata,SizeOf(old_songdata),0); + FillChar(old_songdata.pattern_order,SizeOf(old_songdata.pattern_order),$080); + FillChar(old_songdata.instr_data,SizeOf(old_songdata.instr_data),0); +end; + +procedure init_songdata; +begin + _debug_str_ := 'A2PLAYER.PAS:init_songdata'; + If (play_status <> isStopped) then stop_playing + else init_buffers; + + FillChar(songdata,SizeOf(songdata),0); + FillChar(songdata.pattern_order,SizeOf(songdata.pattern_order),$080); + FillChar(pattdata^,PATTERN_SIZE*max_patterns,0); + + songdata.patt_len := 64; + songdata.nm_tracks := 9; + songdata.tempo := tempo; + songdata.speed := speed; + songdata.macro_speedup := 1; + speed_update := FALSE; + lockvol := FALSE; + panlock := FALSE; + lockVP := FALSE; + tremolo_depth := 0; + vibrato_depth := 0; + volume_scaling := FALSE; + + If (songdata.nm_tracks <= 18) then + begin + percussion_mode := FALSE; + _chan_n := _chmm_n; + _chan_m := _chmm_m; + _chan_c := _chmm_c; + end + else + begin + percussion_mode := TRUE; + _chan_n := _chpm_n; + _chan_m := _chpm_m; + _chan_c := _chpm_c; + end; +end; + +procedure start_playing; +begin + _debug_str_ := 'A2PLAYER.PAS:start_playing'; + stop_playing; + If (error_code <> 0) then EXIT + else init_player; + + current_order := 0; + If (songdata.pattern_order[current_order] > $7f) then + If (calc_order_jump = -1) then EXIT; + + current_pattern := songdata.pattern_order[current_order]; + current_line := 0; + pattern_break := FALSE; + pattern_delay := FALSE; + tickXF := 0; + ticks := 0; + tick0 := 0; + next_line := 0; + song_timer := 0; + timer_temp := 0; + song_timer_tenths := 0; + irq_mode := TRUE; + replay_forbidden := FALSE; + play_status := isPlaying; + time_playing := 0; + ticklooper := 0; + macro_ticklooper := 0; + speed := songdata.speed; + macro_speedup := songdata.macro_speedup; + update_timer(songdata.tempo); +end; + +procedure get_chunk(pattern,line,channel: Byte; + var chunk: tADTRACK2_EVENT); assembler; +asm + mov esi,dword ptr [pattdata] + mov edi,[chunk] + mov al,pattern + inc al + cmp al,max_patterns + jbe @@1 + mov ecx,CHUNK_SIZE + xor al,al + rep stosb + jmp @@2 +@@1: xor eax,eax + mov al,line + mov ebx,CHUNK_SIZE + mul ebx + mov ecx,eax + xor eax,eax + mov al,channel + dec eax + mov ebx,256*CHUNK_SIZE + mul ebx + add ecx,eax + xor eax,eax + mov al,pattern + mov ebx,8 + div ebx + push eax + mov eax,edx + mov ebx,20*256*CHUNK_SIZE + mul ebx + add ecx,eax + pop eax + mov ebx,8*20*256*CHUNK_SIZE + mul ebx + add ecx,eax + add esi,ecx + mov ecx,CHUNK_SIZE + rep movsb +@@2: +end; + +procedure put_chunk(pattern,line,channel: Byte; + chunk: tADTRACK2_EVENT); assembler; +asm + mov esi,[chunk] + mov edi,dword ptr [pattdata] + mov al,pattern + inc al + cmp al,max_patterns + jbe @@1 + mov limit_exceeded,TRUE + jmp @@2 +@@1: xor eax,eax + mov al,line + mov ebx,CHUNK_SIZE + mul ebx + mov ecx,eax + xor eax,eax + mov al,channel + dec eax + mov ebx,256*CHUNK_SIZE + mul ebx + add ecx,eax + xor eax,eax + mov al,pattern + mov ebx,8 + div ebx + push eax + mov eax,edx + mov ebx,20*256*CHUNK_SIZE + mul ebx + add ecx,eax + pop eax + mov ebx,8*20*256*CHUNK_SIZE + mul ebx + add ecx,eax + add edi,ecx + mov ecx,CHUNK_SIZE + rep movsb +@@2: +end; + +procedure count_order(var entries: Byte); + +var + index, + index2: Byte; + +begin + _debug_str_ := 'A2PLAYER.PAS:count_order'; + index := 0; + index2 := 0; + + Repeat + If (songdata.pattern_order[index] <> $80) then + begin + If (songdata.pattern_order[index] > $80) then + If (songdata.pattern_order[index]-$80 <> index2) then + begin + index := songdata.pattern_order[index]-$80; + index2 := index; + end + else BREAK; + end + else BREAK; + If (index < $80) then Inc(index); + until (index > $7f); + + entries := index; +end; + +var + old_exit_proc: Pointer; + temp: Byte; + +procedure new_exit_proc; +begin + _debug_str_ := 'A2PLAYER.PAS:new_exit_proc'; + stop_playing; + done_irq; + FreeMem(pattdata,PATTERN_SIZE*max_patterns); +end; + +begin + old_exit_proc := ExitProc; + ExitProc := @new_exit_proc; + + error_code := 0; + temp := $80; + Repeat + If (MemAvail > PATTERN_SIZE*temp) then + begin + max_patterns := temp; + BREAK; + end + else If (temp-$10 >= $10) then Dec(temp,$10) + else begin + error_code := -2; + BREAK; + end; + until FALSE; + + If (error_code <> -2) then + GetMem(pattdata,PATTERN_SIZE*max_patterns); + + FillChar(decay_bar,SizeOf(decay_bar),0); + play_status := isStopped; + init_songdata; + init_irq; + timer_det := 1; +end. diff --git a/16/ADT2PLAY/adt2play.c b/16/ADT2PLAY/adt2play.c new file mode 100644 index 00000000..4501276e --- /dev/null +++ b/16/ADT2PLAY/adt2play.c @@ -0,0 +1,179 @@ +/* Output from p2c 1.21alpha-07.Dec.93, the Pascal-to-C translator */ +/* From input file "adt2play.pas" */ + + +#include +/* p2c: adt2play.pas, line 2: Warning: Could not find module DPMI [271] */ + + +#include "dpmi.h" +/* p2c: typconst.inc, line 4: Warning: Mismatched '$' signs [241] */ +/* p2c: typconst.inc, line 4: + * Warning: Expected a semicolon, found 'ffffffff' [227] */ + +#ifndef A2PLAYER_H +#include "a2player.h" +#endif + +#ifndef TIMERINT_H +#include "timerint.h" +#endif + +#ifndef PARSERIO_H +#include "parserio.h" +#endif +/* p2c: adt2play.pas, line 3: + * Warning: Could not find module STRINGIO [271] */ + +#include "stringio.h" +/* p2c: adt2play.pas, line 3: + * Warning: Could not find module TXTSCRIO [271] */ +#include "txtscrio.h" +/* p2c: unpk_lib.pas, line 1: + * Warning: Unrecognized character 015 in file [247] */ +/* p2c: unpk_lib.pas, line 2: + * Warning: Unrecognized character 015 in file [247] */ +/* p2c: unpk_lib.pas, line 3: + * Warning: Unrecognized character 015 in file [247] */ +/* p2c: unpk_lib.pas, line 4: + * Warning: Expected IMPLEMENTATION, found a '/' [227] */ +#ifndef UNPK_LIB_H +#include "unpk_lib.h" +#endif + + +#define _timer_xpos 198 +#define _timer_ypos 5 +#define _timer_color 1 +#define _decay_bar_xpos 10 +#define _decay_bar_ypos 140 +#define _decay_bar_palette_start 250 +#define _progress_xpos 8 +#define _progress_ypos 155 +#define _progress_color 251 +#define _fname_xpos 8 +#define _fname_ypos 170 +#define _fname_color 255 +#define _pos_str_xpos 8 +#define _pos_str_ypos 186 +#define _pos_str_color 252 +/* p2c: adt2play.pas, line 30: Note: Characters >= 128 encountered [281] */ +/* p2c: adt2play.pas, line 31: Note: Characters >= 128 encountered [281] */ +/* p2c: adt2play.pas, line 32: Note: Characters >= 128 encountered [281] */ +/* p2c: adt2play.pas, line 33: Note: Characters >= 128 encountered [281] */ +/* p2c: adt2play.pas, line 39: Note: Characters >= 128 encountered [281] */ + + + +#define kBkSPC 0xe08 +#define kESC 0x11b +#define kENTER 0x1c0d + + +Static double decay_bar_rise = 10.0, decay_bar_fall = 0.50; +Static boolean adjust_tracks = true, accurate_conv = true, + fix_c_note_bug = true; +Static uchar window_top = 8; + +Static Char modname[15][40] = { + "/\264DLiB TR/\264CK3R ][ module", "/\264DLiB TR/\264CK3R ][ G3 module", + "/\264DLiB TR/\264CK3R ][ tiny module", + "/\264DLiB TR/\264CK3R ][ G3 tiny module", "Amusic module", + "XMS-Tracker module", "BoomTracker 4.0 module", "Digital-FM module", + "HSC AdLib Composer / HSC-Tracker module", "MPU-401 tr\222kk\356r module", + "Reality ADlib Tracker module", "Scream Tracker 3.x module", + "FM-Kingtracker module", "Surprise! AdLib Tracker module", + "Surprise! AdLib Tracker 2.0 module" +}; + +Static Char songdata_source[256]; +Static Char songdata_title[256]; +Static uchar load_flag; +Static unsigned short fkey; +Static uchar index_, last_order; +Static SearchRec dirinfo; + +Static uchar buf1[sizeof(tVARIABLE_DATA)]; +Static uchar buf2[65535L]; +Static uchar buf3[65535L]; +Static uchar buf4[65535L]; +Static uchar temp_screen[8192]; +Static short correction; +Static uchar entries, entries2, temp, temp2; +Static unsigned short dos_memavail; +Static Char _ParamStr[256][256]; +Static boolean jukebox = false; + + +Static Void ResetF(f) +FILE **f; +{ + unsigned short fattr; + + strcpy(_debug_str_, "ADT2PLAY.PAS:ResetF_RW"); + GetFAttr(*f, fattr); +/* p2c: adt2play.pas, line 81: + * Warning: Symbol 'GETFATTR' is not defined [221] */ + if ((fattr & ReadOnly) == ReadOnly) { + FileMode = 0; +/* p2c: adt2play.pas, line 82: + * Warning: Symbol 'FILEMODE' is not defined [221] */ + } +/* p2c: adt2play.pas, line 84: + * Note: Can't interpret name argument in RESET [180] */ + rewind(*f); +} + + +Static Void BlockReadF(f, data, size, bytes_read) +FILE **f; +Anyptr data; +long size, *bytes_read; +{ + strcpy(_debug_str_, "ADT2PLAY.PAS:BlockReadF"); + *bytes_read = fread(data, 1, size, *f); + P_ioresult = 0; + if (false) + *bytes_read = 0; +} + + +Static Void SeekF(f, fpos) +FILE **f; +long fpos; +{ + strcpy(_debug_str_, "ADT2PLAY.PAS:SeekF"); + _SETIO(fseek(*f, fpos, 0) == 0, EndOfFile); +} + + +Static Void CloseF(f) +FILE **f; +{ + strcpy(_debug_str_, "ADT2PLAY.PAS:CloseF"); + if (*f != NULL) + fclose(*f); + *f = NULL; +} +/* p2c: adt2play.pas, line 114: + * Warning: Expected BEGIN, found 'assembler' [227] */ + + +extern unsigned short min PP((int value, int minimum)); + +main(argc, argv) +int argc; +Char *argv[]; +{ + PASCAL_MAIN(argc, argv); +/* p2c: adt2play.pas, line 115: + * Warning: Expected BEGIN, found 'asm' [227] */ + exit(EXIT_SUCCESS); +} +/* p2c: adt2play.pas, line 123: + * Warning: Junk at end of input file ignored [277] */ + + + + +/* End. */ diff --git a/16/ADT2PLAY/adt2play.pas b/16/ADT2PLAY/adt2play.pas new file mode 100644 index 00000000..01d66f6a --- /dev/null +++ b/16/ADT2PLAY/adt2play.pas @@ -0,0 +1,998 @@ +uses + DOS,DPMI, + A2player,TimerInt,ParserIO,StringIO,TxtScrIO, + UNPK_LIB; + +const + _timer_xpos = 198; + _timer_ypos = 5; + _timer_color = 1; + _decay_bar_xpos = 10; + _decay_bar_ypos = 140; + _decay_bar_palette_start = 250; + _progress_xpos = 8; + _progress_ypos = 155; + _progress_color = 251; + _fname_xpos = 8; + _fname_ypos = 170; + _fname_color = 255; + _pos_str_xpos = 8; + _pos_str_ypos = 186; + _pos_str_color = 252; + +const + decay_bar_rise: Real = 10.0; + decay_bar_fall: Real = 0.50; + adjust_tracks: Boolean = TRUE; + accurate_conv: Boolean = TRUE; + fix_c_note_bug: Boolean = TRUE; + window_top: Byte = 8; + modname: array[1..15] of String[39] = ('/´DLiB TR/´CK3R ][ module', + '/´DLiB TR/´CK3R ][ G3 module', + '/´DLiB TR/´CK3R ][ tiny module', + '/´DLiB TR/´CK3R ][ G3 tiny module', + 'Amusic module', + 'XMS-Tracker module', + 'BoomTracker 4.0 module', + 'Digital-FM module', + 'HSC AdLib Composer / HSC-Tracker module', + 'MPU-401 tr’kkîr module', + 'Reality ADlib Tracker module', + 'Scream Tracker 3.x module', + 'FM-Kingtracker module', + 'Surprise! AdLib Tracker module', + 'Surprise! AdLib Tracker 2.0 module'); +var + songdata_source: String; + songdata_title: String; + load_flag: Byte; + fkey: Word; + index,last_order: Byte; + dirinfo: SearchRec; + +var + buf1: array[0..PRED(SizeOf(tVARIABLE_DATA))] of Byte; + buf2: array[0..PRED(65535)] of Byte; + buf3: array[0..PRED(65535)] of Byte; + buf4: array[0..PRED(65535)] of Byte; + temp_screen: array[0..PRED(8192)] of Byte; + correction: Integer; + entries, + entries2: Byte; + temp,temp2: Byte; + dos_memavail: Word; + _ParamStr: array[0..255] of String; + +const + jukebox: Boolean = FALSE; + +const + kBkSPC = $0e08; + kESC = $011b; + kENTER = $1c0d; + +procedure ResetF(var f: File); + +var + fattr: Word; + +begin + _debug_str_:= 'ADT2PLAY.PAS:ResetF_RW'; + GetFAttr(f,fattr); + If (fattr AND ReadOnly = ReadOnly) then FileMode := 0; + {$i-} + Reset(f,1); + {$i+} +end; + +procedure BlockReadF(var f: File; var data; size: Longint; var bytes_read: Longint); +begin + _debug_str_:= 'ADT2PLAY.PAS:BlockReadF'; + {$i-} + BlockRead(f,data,size,bytes_read); + {$i+} + If (IOresult <> 0) then bytes_read := 0; +end; + +procedure SeekF(var f: File; fpos: Longint); +begin + _debug_str_:= 'ADT2PLAY.PAS:SeekF'; + {$i-} + Seek(f,fpos); + {$i+} +end; + +procedure CloseF(var f: File); +begin + _debug_str_:= 'ADT2PLAY.PAS:CloseF'; + {$i-} + Close(f); + {$i+} + If (IOresult <> 0) then ; +end; + +function min(value: Word; minimum: Word): Word; assembler; +asm + mov ax,value + cmp ax,minimum + jae @@1 + mov ax,minimum +@@1: +end; + +function max(value: Word; maximum: Word): Word; assembler; +asm + mov ax,value + cmp ax,maximum + jbe @@1 + mov ax,maximum +@@1: +end; + +function concw(lo,hi: Byte): Word; assembler; +asm + mov al,lo + mov ah,hi +end; + +function keypressed: Boolean; assembler; +asm + mov ah,01h + int 16h + mov al,TRUE + jnz @@1 + mov al,FALSE +@@1: +end; + +function is_4op_mode: Boolean; assembler; +asm + mov al,byte ptr [songdata.flag_4op] + or al,al + jz @@1 + mov al,TRUE +@@1: +end; + +function is_4op_chan(chan: Byte): Boolean; assembler; +asm + mov al,byte ptr [songdata.flag_4op] + mov ah,chan + test al,1 + jz @@1 + cmp ah,1 + jb @@1 + cmp ah,2 + ja @@1 + mov al,TRUE + jmp @@7 +@@1: test al,2 + jz @@2 + cmp ah,3 + jb @@2 + cmp ah,4 + ja @@2 + mov al,TRUE + jmp @@7 +@@2: test al,4 + jz @@3 + cmp ah,5 + jb @@3 + cmp ah,6 + ja @@3 + mov al,TRUE + jmp @@7 +@@3: test al,8 + jz @@4 + cmp ah,10 + jb @@4 + cmp ah,11 + ja @@4 + mov al,TRUE + jmp @@7 +@@4: test al,10h + jz @@5 + cmp ah,12 + jb @@5 + cmp ah,13 + ja @@5 + mov al,TRUE + jmp @@7 +@@5: test al,20h + jz @@6 + cmp ah,14 + jb @@6 + cmp ah,15 + ja @@6 + mov al,TRUE + jmp @@7 +@@6: mov al,FALSE +@@7: +end; + +{$i structrs.inc} +{$i iloaders.inc} + +const + _picture_mode: Boolean = FALSE; + +var + vmem: array[0..PRED(320*200)] of Byte; + fade_buf,fade_buf2: tFADE_BUF; + vstate: tVIDEO_STATE; + +procedure _refresh_decay_bar(xpos,ypos: Word; height,width,level: Byte); assembler; +asm + mov edi,0a0000h + lea edx,dword ptr [_picture_palette] + add edx,6 + lea esi,dword ptr [_picture_bitmap] + add esi,6 + movzx eax,ypos + mov ebx,320 + mul ebx + movzx ebx,xpos + add eax,ebx + add edi,eax + cmp level,BYTE_NULL + jnz @@1 + mov level,0 + jmp @@2 +@@1: cmp level,2 + jae @@2 + mov level,2 +@@2: movzx ecx,width + jecxz @@10 +@@3: push ecx + push edi + movzx ecx,height + jecxz @@9 +@@4: movzx ebx,height + sub ebx,ecx + movzx eax,level + cmp ebx,eax + jnae @@5 + mov ebx,edi + sub ebx,0a0000h + add ebx,esi + movzx eax,byte ptr [ebx] + jmp @@8 +@@5: movzx eax,height + push edx + xor edx,edx + sub eax,ecx + mov ebx,5 + div ebx + mov eax,edx + pop edx + cmp eax,3 + jbe @@6 + mov ebx,edi + sub ebx,0a0000h + add ebx,esi + movzx eax,byte ptr [ebx] + jmp @@8 +@@6: or eax,eax + jnz @@7 + xor eax,eax + jmp @@8 +@@7: add eax,_decay_bar_palette_start + cmp level,2 + jnbe @@8 + mov eax,250 +@@8: mov byte ptr [edi],al + sub edi,320 + loop @@4 +@@9: pop edi + pop ecx + inc edi + loop @@3 +@@10: +end; + +const + _decay_bars_initialized: Boolean = FALSE; + _decay_bars_nm_tracks: Byte = 0; + +var + _old_decay_bar_value: array[1..25] of Byte; + +procedure decay_bars_refresh; + +var + temp: Byte; + +begin + _debug_str_:= 'ADT2PLAY.PAS:decay_bars_refresh'; + If NOT _decay_bars_initialized then + For temp := 1 to 25 do + _old_decay_bar_value[temp] := BYTE_NULL; + + For temp := 1 to 25 do + begin + If (decay_bar[temp].dir = 1) then + decay_bar[temp].lvl := decay_bar[temp].lvl+ + decay_bar[temp].dir*(decay_bar_rise/IRQ_freq*100) + else + decay_bar[temp].lvl := decay_bar[temp].lvl+ + decay_bar[temp].dir*(decay_bar_fall/IRQ_freq*100); + + If (decay_bar[temp].lvl < 0) then decay_bar[temp].lvl := 0; + If (decay_bar[temp].lvl > decay_bar[temp].max_lvl) then + begin + decay_bar[temp].dir := -1; + If (decay_bar[temp].lvl > 63) then + decay_bar[temp].lvl := 63; + end; + + If (_old_decay_bar_value[temp] <> Round(decay_bar[temp].lvl*4/3)) then + begin + _refresh_decay_bar(_decay_bar_xpos+PRED(temp)*12,_decay_bar_ypos, + Round(63*4/3),10, + Round(decay_bar[temp].lvl*4/3)); + _old_decay_bar_value[temp] := Round(decay_bar[temp].lvl*4/3); + end; + end; +end; + +procedure toggle_picture_mode; + +var + index: Byte; + +begin + _debug_str_:= 'ADT2PLAY.PAS:toggle_picture_mode'; + If NOT _picture_mode then + begin + _picture_mode := NOT _picture_mode; + GetVideoState(vstate); + fade_speed := 16; + fade_buf.action := first; + VgaFade(fade_buf,fadeOut,delayed); + For index := 1 to 20 do WaitRetrace; + asm mov ax,13h; int 10h end; + + For index := 1 to 20 do WaitRetrace; + For index := 0 to 255 do + SetRGBitem(index,tRGB_PALETTE(MEM[Ofs(_picture_palette)+6])[index].r, + tRGB_PALETTE(MEM[Ofs(_picture_palette)+6])[index].g, + tRGB_PALETTE(MEM[Ofs(_picture_palette)+6])[index].b); + fade_speed := 16; + fade_buf.action := first; + VgaFade(fade_buf2,fadeOut,fast); + + Move(MEM[Ofs(_picture_bitmap)+6],MEM[$0a0000],320*200); + VgaFade(fade_buf2,fadeIn,delayed); + external_irq_hook := decay_bars_refresh; + end + else begin + external_irq_hook := NIL; + _picture_mode := NOT _picture_mode; + _decay_bars_initialized := FALSE; + VgaFade(fade_buf2,fadeOut,delayed); + + SetVideoState(vstate,FALSE); + VgaFade(fade_buf2,fadeOut,fast); + For index := 1 to 20 do WaitRetrace; + Move(vstate.screen,MEM[$0b8000],SizeOf(vstate.screen)); + + For index := 1 to 20 do WaitRetrace; + VgaFade(fade_buf,fadeIn,delayed); + end; +end; + +procedure wtext(xstart,ystart: Word; txt: String; color: Byte); + +var + x,y: Word; + temp,i,j,b: Word; + +begin + _debug_str_:= 'ADT2PLAY.PAS:wtext'; + If NOT _picture_mode then EXIT; + Move(MEM[Ofs(_picture_bitmap)+6+320*ystart],vmem[320*ystart],(8+1)*320); + x := xstart+1; + y := ystart+1; + + For temp := 1 to Length(txt) do + begin + For j := 0 to 7 do + begin + b := tCHAR8x8(MEM[Ofs(_font8x8)+6])[txt[temp]][j]; + For i := 7 downto 0 do + If (b OR (1 SHL i) = b) then + vmem[x+7-i+(y+j)*320] := 0 + end; + Inc(x,8); + end; + + x := xstart; + y := ystart; + + For temp := 1 to Length(txt) do + begin + For j := 0 to 7 do + begin + b := tCHAR8x8(MEM[Ofs(_font8x8)+6])[txt[temp]][j]; + For i := 7 downto 0 do + If (b OR (1 SHL i) = b) then + vmem[x+7-i+(y+j)*320] := color; + end; + Inc(x,8); + end; + + Move(vmem[320*ystart],MEM[$0a0000+320*ystart],(8+1)*320); +end; + +procedure wtext2(xstart,ystart: Word; txt: String; color: Byte); + +const + _double: array[0..15] of Byte = (0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7); + +var + x,y: Word; + temp,i,j,b: Word; + +begin + _debug_str_:= 'ADT2PLAY.PAS:wtext2'; + If NOT _picture_mode then EXIT; + Move(MEM[Ofs(_picture_bitmap)+6+320*ystart],vmem[320*ystart],(16+1)*320); + x := xstart+1; + y := ystart+1; + + For temp := 1 to Length(txt) do + begin + For j := 0 to 15 do + begin + b := tCHAR8x16(MEM[Ofs(_font8x16)+6])[txt[temp]][j]; + For i := 15 downto 0 do + If (b OR (1 SHL _double[i]) = b) then + vmem[x+15-i+(y+j)*320] := 0 + end; + Inc(x,16); + end; + + x := xstart; + y := ystart; + + For temp := 1 to Length(txt) do + begin + For j := 0 to 15 do + begin + b := tCHAR8x16(MEM[Ofs(_font8x16)+6])[txt[temp]][j]; + For i := 15 downto 0 do + If (b OR (1 SHL _double[i]) = b) then + vmem[x+15-i+(y+j)*320] := color; + end; + Inc(x,16); + end; + + Move(vmem[320*ystart],MEM[$0a0000+320*ystart],(16+1)*320); +end; + +procedure C3Write(str: String; atr1,atr2,atr3: Byte); +begin + _debug_str_:= 'ADT2PLAY.PAS:CWrite'; + If _picture_mode then EXIT; + ShowC3Str(MEM[$0b8000],WhereX,WhereY,str,atr1,atr2,atr3); + GotoXY(1,WhereY); +end; + +procedure C3WriteLn(str: String; atr1,atr2,atr3: Byte); +begin + _debug_str_:= 'ADT2PLAY.PAS:C3WriteLn'; + ShowC3Str(Ptr(v_seg,v_ofs)^,WhereX,WhereY, + str, + atr1,atr2,atr3); + WriteLn; +end; + +procedure CWriteLn(str: String; atr1,atr2: Byte); + +var + temp: Word; + attr,posx,posy: Byte; + color2: Boolean; + +begin + _debug_str_:= 'ADT2PLAY.PAS:CWriteLn'; + If _picture_mode then EXIT; + color2 := FALSE; + attr := atr1; + posx := WhereX; + posy := WhereY; + + For temp := 1 to Length(str) do + If (str[temp] <> '~') then + begin + MEM[$0b8000+(posx-1+(posy-1)*MaxCol) SHL 1] := BYTE(str[temp]); + MEM[$0b8000+(posx-1+(posy-1)*MaxCol) SHL 1+1] := attr; + If (posx < MaxCol) then Inc(posx) + else begin + posx := 1; + Inc(posy); + If (posy > MaxLn) then + begin + asm + mov ah,06h + mov al,1 + mov bh,07h + mov ch,window_top + mov cl,1 + mov dh,MaxLn + mov dl,MaxCol + dec ch + dec cl + dec dh + dec dl + int 10h + end; + Dec(posy); + end; + end; + end + else begin + color2 := NOT color2; + If color2 then attr := atr2 else attr := atr1; + end; + + Inc(posy); + If (posy > MaxLn) then + begin + asm + mov ah,06h + mov al,1 + mov bh,07h + mov ch,window_top + mov cl,1 + mov dh,MaxLn + mov dl,MaxCol + dec ch + dec cl + dec dh + dec dl + int 10h + end; + Dec(posy); + end; + + posx := 1; + GotoXY(posx,posy); +end; + +function __progress_str(value: Byte): String; + +var + result: String; + +begin + result := ''; + Repeat + If (value > 4) then + begin + result := result+#4; + Dec(value,4); + end; + If (value <= 4) and (value <> 0) then + result := result+CHR(0+value) + until (value <= 4); + __progress_str := result; +end; + +function _progress_str: String; +begin + If (songdata.patt_len = 0) then EXIT; + If (entries <> 0) then + _progress_str := + ExpStrR(__progress_str( + Round(4*38/entries*(current_order-correction+ + 1/songdata.patt_len*(current_line+1)))),38,#0) + else _progress_str := ExpStrR('',38,#0); +end; + +function _timer_str: String; +begin + _timer_str := ExpStrL(Num2str(song_timer DIV 60,10),2,'0')+':'+ + ExpStrL(Num2str(song_timer MOD 60,10),2,'0')+'.'+ + Num2str(song_timer_tenths DIV 10,10); +end; + +function _position_str: String; +begin + If (songdata.patt_len = 0) then EXIT; + If (entries <> 0) then + _position_str := + 'Order '+ExpStrL(Num2str(current_order,10),3,'0')+'/'+ + ExpStrL(Num2str(PRED(entries2),10),3,'0')+', '+ + 'pattern '+ExpStrL(Num2str(current_pattern,10),3,'0')+', '+ + 'row '+ExpStrL(Num2str(current_line,10),3,'0')+' '+ + '['+ExpStrL(Num2str(Round(100/entries*(current_order-correction+ + 1/songdata.patt_len*(current_line+1))),10),3,'0')+'%] '+ + '['+_timer_str+']'+' ' + else _position_str := + 'Order '+ExpStrL(Num2str(current_order,10),3,'0')+'/'+ + ExpStrL(Num2str(PRED(entries2),10),3,'0')+', '+ + 'pattern '+ExpStrL(Num2str(current_pattern,10),3,'0')+', '+ + 'row '+ExpStrL(Num2str(current_line,10),3,'0')+' '+ + '['+ExpStrL('',3,'0')+'%] '+ + '['+_timer_str+']'+' '; +end; + +function _position_str2: String; +begin + _position_str2 := + 'Order '+ExpStrL(Num2str(current_order,10),3,'0')+'/'+ + ExpStrL(Num2str(PRED(entries2),10),3,'0')+', '+ + 'pattern '+ExpStrL(Num2str(current_pattern,10),3,'0')+', '+ + 'row '+ExpStrL(Num2str(current_line,10),3,'0')+' '; +end; + +procedure fade_out; + +var + temp: Byte; + +begin + _debug_str_:= 'ADT2PLAY.PAS:fade_out'; + For temp := overall_volume downto 0 do + begin + set_overall_volume(temp); + _delay_counter := 0; + While (_delay_counter < overall_volume DIV 10) do + begin + wtext2(_timer_xpos,_timer_ypos,_timer_str,_timer_color); + wtext(_progress_xpos,_progress_ypos,_progress_str,_progress_color); + wtext(_pos_str_xpos,_pos_str_ypos,_position_str2+'',_pos_str_color); + C3Write(DietStr(_position_str+'',PRED(MaxCol)),$0f,0,0); + MEMW[0:$041c] := MEMW[0:$041a]; + end; + end; +end; + +function _gfx_mode: Boolean; + +var + result: Boolean; + temp: Byte; + +begin + result := FALSE; + For temp := 1 to ParamCount do + If (Lower(_ParamStr[temp]) = '/gfx') then + begin + result := TRUE; + BREAK; + end; + _gfx_mode := result; +end; + +procedure _list_title; +begin + If iVGA then + begin + CWriteLn('',$07,0); + CWriteLn(' subz3ro''s',$09,0); + CWriteLn(' ÄÂÄ ÄÄ',$09,0); + CWriteLn(' /´DLiB³R/´CK3R ³³ G3 PLAYER',$09,0); + CWriteLn(' ³ ³ ÄÄ 0.43',$09,0); + CWriteLn('',$07,0); + end + else begin + WriteLn; + WriteLn(' subz3ro''s'); + WriteLn(' ÄÂÄ ÄÄ'); + WriteLn(' /´DLiB³R/´CK3R ³³ G3 PLAYER'); + WriteLn(' ³ ³ ÄÄ 0.43'); + WriteLn; + end; +end; + +var + old_exit_proc: procedure; + +procedure new_exit_proc; +begin + If (ErrorAddr <> NIL) then + begin + stop_playing; + TimerDone; + opl3exp($0004); + opl3exp($0005); + FreeMem(pattdata,PATTERN_SIZE*max_patterns); + + asm + mov ax,03h + xor bh,bh + int 10h + mov MaxCol,80 + mov MaxLn,25 + end; + + WriteLn('ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ'); + WriteLn('Û ABNORMAL PROGRAM TERMiNATiON Û'); + WriteLn('ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß'); + WriteLn('ERROR_ID #'+Num2str(ExitCode,10)+' at '+ExpStrL(Num2str(LONGINT(ErrorAddr),16),8,'0')); + WriteLn(_debug_str_); + WriteLn; + WriteLn('Please send this information with brief description'); + WriteLn('what you were doing with the program when this error was encountered'); + WriteLn('to following email address:'); + WriteLn; + WriteLn('subz3ro@hotmail.com'); + + ErrorAddr := NIL; + HALT(ExitCode); + end + else + ExitProc := @old_exit_proc; +end; + +begin + For temp := 0 to 255 do + _ParamStr[temp] := ParamStr(temp); + + If NOT _gfx_mode then + begin + If iVGA then CleanScreen(MEM[$0b8000]); + GotoXY(1,1); + _list_title; + end; + + asm + mov bx,0ffffh + mov ah,48h + int 21h + mov dos_memavail,bx + end; + + If (dos_memavail*16 DIV 1024 < 120) then + begin + If _gfx_mode then _list_title; + WriteLn('ERROR(1) - Insufficient DOS memory!'); + HALT(1); + end; + + If NOT iVGA then + begin + WriteLn('ERROR(2) - Insufficient video equipment!'); + HALT(2); + end; + + For temp := 1 to ParamCount do + If (Lower(_ParamStr[temp]) = '/jukebox') then + jukebox := TRUE; + + index := 0; + If (ParamCount = 0) then + begin + If _gfx_mode then _list_title; + CWriteLn('Syntax: '+BaseNameOnly(_ParamStr[0])+' files|wildcards [files|wildcards{...}]',$07,0); + CWriteLn('',$07,0); + CWriteLn('Command-line options:',$07,0); + CWriteLn(' /jukebox play modules w/ no repeat',$07,0); + CWriteLn(' /gfx graphical interface',$07,0); + HALT; + end; + + @old_exit_proc := ExitProc; + ExitProc := @new_exit_proc; + + If _gfx_mode then + toggle_picture_mode; + + Repeat + If NOT (index <> 0) then + begin + CWriteLn(FilterStr(DietStr('úù-Ä--ùú úù-ÄÄÄÄÄÄÄÄÄÄÄÄÄÄ--ùú úù-ÄÄÄ--ùú úù-ÄÄ-Äùú', + PRED(MaxCol)), + '.',' '),$01,0); + CWriteLn( ' ~[~SPACE~]~ Fast-Forward ~[~Ä~]~ Restart ~[~ÄÙ~]~ Next ~[~ESC~]~ Quit',$09,$01); + CWriteLn(FilterStr(DietStr('úù-ÄÄÄÄÄÄÄÄÄÄ--ùú úù-ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ-Äùú', + PRED(MaxCol)), + '.',' '),$01,0); + + CWriteLn('',$07,0); + window_top := WhereY; + end; + + Inc(index); + If (_ParamStr[index][1] <> '/') then + begin + FindFirst(_ParamStr[index],AnyFile-VolumeID-Directory,dirinfo); + If (DosError <> 0) then + begin + CWriteLn(DietStr('ERROR(2) - No such file "'+ + Lower(_ParamStr[index])+'"', + PRED(MaxCol)),$07,0); + CWriteLn('',$07,0); + FindNext(dirinfo); + CONTINUE; + end; + + While NOT (DosError <> 0) do + begin + If (PathOnly(_ParamStr[index]) <> '') then + songdata_source := Upper(PathOnly(_ParamStr[index])+dirinfo.name) + else songdata_source := Upper(dirinfo.name); + + wtext2(_timer_xpos,_timer_ypos,_timer_str,_timer_color); + wtext(_progress_xpos,_progress_ypos,_progress_str,_progress_color); + wtext(_pos_str_xpos,_pos_str_ypos,_position_str2+' ',_pos_str_color); + wtext2(_fname_xpos,_fname_ypos,NameOnly(songdata_source),_fname_color); + wtext(_pos_str_xpos,_pos_str_ypos,'Loading...',_pos_str_color); + + C3Write(DietStr('Loading "'+songdata_source+'" (please wait)', + PRED(MaxCol)),$07,0,0); + For temp := 1 to 10 do WaitRetrace; + + limit_exceeded := FALSE; + load_flag := BYTE_NULL; + + _decay_bars_initialized := FALSE; + a2m_file_loader; + If (load_flag = BYTE_NULL) then a2t_file_loader; + If (load_flag = BYTE_NULL) then amd_file_loader; + If (load_flag = BYTE_NULL) then cff_file_loader; + If (load_flag = BYTE_NULL) then dfm_file_loader; + If (load_flag = BYTE_NULL) then mtk_file_loader; + If (load_flag = BYTE_NULL) then rad_file_loader; + If (load_flag = BYTE_NULL) then s3m_file_loader; + If (load_flag = BYTE_NULL) then fmk_file_loader; + If (load_flag = BYTE_NULL) then sat_file_loader; + If (load_flag = BYTE_NULL) then sa2_file_loader; + If (load_flag = BYTE_NULL) then hsc_file_loader; + If (load_flag = BYTE_NULL) or + (load_flag = $7f) then + begin + CWriteLn(DietStr(ExpStrR('ERROR(3) - Invalid module ('+songdata_source+')', + PRED(MaxCol),' '), + PRED(MaxCol)),$07,0); + CWriteLn('',$07,0); + FindNext(dirinfo); + CONTINUE; + end; + + last_order := 0; + entries := 0; + If limit_exceeded then + begin + CWriteLn(DietStr(ExpStrR('ERROR(1) - Insufficient memory!', + PRED(MaxCol),' '), + PRED(MaxCol)),$07,0); + CWriteLn('',$07,0); + FindNext(dirinfo); + CONTINUE; + end; + + count_order(entries); + correction := calc_following_order(0); + entries2 := entries; + If (correction <> -1) then Dec(entries,correction) + else entries := 0; + CWriteLn(DietStr(ExpStrR('Playing '+modname[load_flag]+' "'+ + songdata_source+'"', + PRED(MaxCol),' '), + PRED(MaxCol)),$07,0); + temp2 := PRED(WhereY); + + If (entries = 0) then + begin + If NOT _picture_mode then GotoXY(1,temp2); + CWriteLn(DietStr(ExpStrR('Playing '+modname[load_flag]+' "'+ + songdata_source+'"', + PRED(MaxCol),' '), + PRED(MaxCol)),$08,0); + CWriteLn(DietStr(ExpStrR(''+NameOnly(songdata_source)+' [stopped] ['+ + ExpStrL(Num2str(TRUNC(time_playing) DIV 60,10),2,'0')+ + ':'+ExpStrL(Num2str(TRUNC(time_playing) MOD 60,10),2,'0')+']', + PRED(MaxCol),' '), + PRED(MaxCol)),$07,0); + CWriteLn('',$07,0); + FindNext(dirinfo); + CONTINUE; + end; + + start_playing; + set_overall_volume(63); + _decay_bars_nm_tracks := songdata.nm_tracks; + _decay_bars_initialized := TRUE; + + Repeat + If (overall_volume = 63) then + begin + wtext2(_timer_xpos,_timer_ypos,_timer_str,_timer_color); + wtext(_progress_xpos,_progress_ypos,_progress_str,_progress_color); + wtext(_pos_str_xpos,_pos_str_ypos,_position_str2+' ',_pos_str_color); + C3Write(DietStr(_position_str+' ',PRED(MaxCol)),$0f,0,0); + end; + + If (PORT[$60] = $39) { SPACE pressed } then + begin + If (overall_volume > 32) then + For temp := 63 downto 32 do + begin + set_overall_volume(temp); + _delay_counter := 0; + While (_delay_counter < overall_volume DIV 20) do + begin + wtext2(_timer_xpos,_timer_ypos,_timer_str,_timer_color); + wtext(_progress_xpos,_progress_ypos,_progress_str,_progress_color); + wtext(_pos_str_xpos,_pos_str_ypos,_position_str2+'',_pos_str_color); + MEMW[0:$041c] := MEMW[0:$041a]; + C3Write(DietStr(_position_str+'',PRED(MaxCol)),$0f,0,0); + end; + end + else begin + wtext2(_timer_xpos,_timer_ypos,_timer_str,_timer_color); + wtext(_progress_xpos,_progress_ypos,_progress_str,_progress_color); + wtext(_pos_str_xpos,_pos_str_ypos,_position_str2+'',_pos_str_color); + C3Write(DietStr(_position_str+'',PRED(MaxCol)),$0f,0,0); + MEMW[0:$041c] := MEMW[0:$041a]; + end; + fast_forward := TRUE; + end + else If (PORT[$60] = $0b9) { SPACE released } then + begin + fast_forward := FALSE; + If (overall_volume < 63) then + For temp := 32 to 63 do + begin + set_overall_volume(temp); + _delay_counter := 0; + While (_delay_counter < overall_volume DIV 20) do + begin + wtext2(_timer_xpos,_timer_ypos,_timer_str,_timer_color); + wtext(_progress_xpos,_progress_ypos,_progress_str,_progress_color); + wtext(_pos_str_xpos,_pos_str_ypos,_position_str2+' ',_pos_str_color); + C3Write(DietStr(_position_str+' ',PRED(MaxCol)),$0f,0,0); + MEMW[0:$041c] := MEMW[0:$041a]; + end; + end; + end; + + If keypressed then asm xor ax,ax; int 16h; mov fkey,ax end + else fkey := $0ffff; + MEMW[0:$041c] := MEMW[0:$041a]; + + If jukebox and (last_order <> current_order) then + begin + If (last_order > current_order) and + (last_order = PRED(entries2)) then BREAK + else last_order := current_order; + end; + + If (fkey = kBkSPC) then + begin + fade_out; + stop_playing; + set_overall_volume(63); + start_playing; + end; + until (fkey = kENTER) or + (fkey = kESC); + + fade_out; + stop_playing; + If NOT _picture_mode then GotoXY(1,temp2); + CWriteLn(DietStr(ExpStrR('Playing '+modname[load_flag]+' "'+ + songdata_source+'"', + PRED(MaxCol),' '), + PRED(MaxCol)),$08,0); + CWriteLn(DietStr(ExpStrR(''+NameOnly(songdata_source)+' [stopped] ['+ + ExpStrL(Num2str(TRUNC(time_playing) DIV 60,10),2,'0')+ + ':'+ExpStrL(Num2str(TRUNC(time_playing) MOD 60,10),2,'0')+']', + PRED(MaxCol),' '), + PRED(MaxCol)),$07,0); + CWriteLn('',$07,0); + If (fkey = kESC) then BREAK; + FindNext(dirinfo); + end; + end; + until (index = ParamCount); + + If _picture_mode then toggle_picture_mode; + MEMW[0:$041c] := MEMW[0:$041a]; + FreeMem(pattdata,PATTERN_SIZE*max_patterns); + ExitProc := @old_exit_proc; + HALT(0); +end. diff --git a/16/ADT2PLAY/parserio.pas b/16/ADT2PLAY/parserio.pas new file mode 100644 index 00000000..52db536e --- /dev/null +++ b/16/ADT2PLAY/parserio.pas @@ -0,0 +1,305 @@ +unit ParserIO; +interface + +type + tDUMMY_BUFF = array[0..PRED(655350)] of Byte; + +function Scan(var buf; skip,size: Longint; str: String): Longint; +function SensitiveScan(var buf; skip,size: Longint; str: String): Longint; +function Compare(var buf1,buf2; size: Longint): Boolean; +function Empty(var buf; size: Longint): Boolean; +function CountLines(var buf; size: Longint): Longint; +function Update16(var buf; size: Longint; crc: Word): Word; +function Update32(var buf; size: Longint; crc: Longint): Longint; + +implementation + +var + CRC16_table: array[BYTE] of Word; + CRC32_table: array[BYTE] of Longint; + +function Scan(var buf; skip,size: Longint; str: String): Longint; assembler; +asm + mov edi,[str] + mov esi,[str] + xor eax,eax + lodsb + stosb + xor ecx,ecx + mov ecx,eax + xor ebx,ebx + mov ebx,eax + jecxz @@9 +@@1: lodsb + cmp al,'a' + jb @@2 + cmp al,'z' + ja @@2 + sub al,20h +@@2: stosb + loop @@1 + sub edi,ebx + mov esi,[buf] + add esi,skip + mov ecx,size + sub ecx,skip + jecxz @@8 + cld + sub ecx,ebx + jb @@8 + inc ecx +@@4: mov ah,[edi] + and ah,NOT 20h +@@5: lodsb + and al,NOT 20h + cmp al,ah + loopne @@5 + jne @@8 + dec esi + mov edx,ecx + mov ecx,ebx +@@6: repe cmpsb + je @@10 + mov al,[esi-1] + cmp al,'a' + jb @@7 + cmp al,'z' + ja @@7 + sub al,20h +@@7: cmp al,[edi-1] + je @@6 + sub ecx,ebx + add esi,ecx + add edi,ecx + inc esi + mov ecx,edx + jne @@4 +@@8: xor eax,eax + jmp @@11 +@@9: mov eax,1 + jmp @@11 +@@10: sub esi,ebx + mov eax,esi + sub eax,dword ptr buf + inc eax +@@11: dec eax +end; + +function SensitiveScan(var buf; skip,size: Longint; str: String): Longint; assembler; +asm + mov edi,[buf] + add edi,skip + mov esi,[str] + mov ecx,size + sub ecx,skip + xor eax,eax + jecxz @@3 + cld + lodsb + cmp al,1 + jb @@5 + ja @@1 + lodsb + repne scasb + jne @@3 + jmp @@5 +@@1: xor ah,ah + mov ebx,eax + dec ebx + mov edx,ecx + sub edx,eax + jb @@3 + lodsb + add edx,2 +@@2: dec edx + mov ecx,edx + repne scasb + jne @@3 + mov edx,ecx + mov ecx,ebx + rep cmpsb + je @@4 + sub ecx,ebx + add esi,ecx + add edi,ecx + inc edi + or edx,edx + jne @@2 +@@3: xor eax,eax + jmp @@6 +@@4: sub edi,ebx +@@5: mov eax,edi + sub eax,dword ptr buf +@@6: dec eax +end; + +function Compare(var buf1,buf2; size: Longint): Boolean; assembler; +asm + xor edx,edx + mov eax,size + cmp eax,16 + jb @@3 + mov ecx,4 + div ecx + mov ecx,eax + jecxz @@1 + mov esi,[buf1] + mov edi,[buf2] + cld + repz cmpsd + jnz @@2 + mov ecx,edx + jecxz @@1 + repz cmpsb + jnz @@2 +@@1: mov al,1 + jmp @@6 +@@2: xor al,al + jmp @@6 +@@3: mov ecx,size + jecxz @@4 + mov esi,[buf1] + mov edi,[buf2] + cld + repz cmpsb + jnz @@5 +@@4: mov al,1 + jmp @@6 +@@5: xor al,al +@@6: +end; + +function Empty(var buf; size: Longint): Boolean; assembler; +asm + xor edx,edx + mov eax,size + cmp eax,16 + jb @@3 + mov ecx,4 + div ecx + mov ecx,eax + jecxz @@1 + mov edi,[buf] + xor eax,eax + repz scasd + jnz @@2 + mov ecx,edx + jecxz @@1 + repz scasb + jnz @@2 +@@1: mov al,1 + jmp @@6 +@@2: xor al,al + jmp @@6 +@@3: mov ecx,size + jecxz @@4 + mov edi,[buf] + xor eax,eax + repz scasb + jnz @@5 +@@4: mov al,1 + jmp @@6 +@@5: xor al,al +@@6: +end; + +function CountLines(var buf; size: Longint): Longint; assembler; +asm + mov edi,[buf] + mov ecx,size + mov edx,edi + add edx,ecx + xor ebx,ebx + jecxz @@3 +@@1: mov al,0dh + repnz scasb + jnz @@3 + cmp byte ptr [edi],0ah + jnz @@2 + inc edi + inc ebx +@@2: cmp edi,edx + jb @@1 +@@3: mov eax,ebx +end; + +function Update16(var buf; size: Longint; crc: Word): Word; assembler; +asm + mov esi,[buf] + lea edi,[CRC16_table] + mov bx,crc + mov ecx,size + jecxz @@2 +@@1: xor ax,ax + lodsb + mov dl,bh + xor dh,dh + xor bh,bh + xor bx,ax + and ebx,000000ffh + shl ebx,1 + mov bx,[edi+ebx] + xor bx,dx + loop @@1 +@@2: mov ax,bx +end; + +function Update32(var buf; size: Longint; crc: Longint): Longint; assembler; +asm + mov esi,[buf] + lea edi,[CRC32_table] + mov ebx,crc + mov ecx,size + jecxz @@2 +@@1: xor eax,eax + lodsb + xor ebx,eax + mov edx,ebx + and ebx,000000ffh + shl ebx,2 + mov ebx,[edi+ebx] + shr edx,8 + and edx,00ffffffh + xor ebx,edx + loop @@1 +@@2: mov eax,ebx +end; + +procedure make_table_16bit; + +var + crc: Word; + n,index: Byte; + +begin + For index := 0 to 255 do + begin + crc := index; + For n := 1 to 8 do + If Odd(crc) then crc := crc SHR 1 XOR $0a001 + else crc := crc SHR 1; + CRC16_table[index] := crc; + end; +end; + +procedure make_table_32bit; + +var + crc: DWord; + n,index: Byte; + +begin + For index := 0 to 255 do + begin + crc := index; + For n := 1 to 8 do + If Odd(crc) then crc := crc SHR 1 XOR $0edb88320 + else crc := crc SHR 1; + CRC32_table[index] := crc; + end; +end; + +begin + make_table_16bit; + make_table_32bit; +end. diff --git a/16/ADT2PLAY/timerint.pas b/16/ADT2PLAY/timerint.pas new file mode 100644 index 00000000..6ed65e16 --- /dev/null +++ b/16/ADT2PLAY/timerint.pas @@ -0,0 +1,154 @@ +unit TimerInt; +interface + +const + _debug_str_: String = ''; + +procedure TimerSetup(Hz: Longint); +procedure TimerDone; +procedure TimerInstallHandler(handler: Pointer); +procedure TimerRemoveHandler; + +implementation + +uses DOS; + +var + oldint08: {$IFDEF __TMT__} FarPointer + {$ELSE} Pointer + {$ENDIF}; +var + newint08: Pointer; + counter, + clock_ticks,clock_flag: Word; + ticks: Longint; + +const + timer_handler: Pointer = NIL; + +procedure int08; interrupt; + assembler; +asm +{$IFNDEF _32BIT} + cmp word ptr timer_handler,0 + jnz @@1 + cmp word ptr timer_handler+2,0 + jz @@2 +@@1: push ds + call [timer_handler] + pop ds +@@2: mov ax,word ptr ticks + mov bx,word ptr ticks+2 + add ax,1 + adc bx,0 + mov word ptr ticks,ax + mov word ptr ticks+2,bx + inc clock_ticks + mov ax,clock_ticks + cmp ax,clock_flag + jb @@3 + mov clock_ticks,0 + pushf + call [oldint08] + jmp @@ret +@@3: mov al,60h + out 20h,al +{$ELSE} + cmp timer_handler,0 + jz @@1 + push ds + push es + call [timer_handler] + pop es + pop ds +@@1: inc ticks + inc clock_ticks + mov ax,clock_ticks + cmp ax,clock_flag + jnz @@2 + mov clock_ticks,0 + pushfd + call [oldint08] + jmp @@ret +@@2: mov al,60h + out 20h,al +{$ENDIF} +@@ret: +end; + +procedure DisableTimerIRQ; assembler; +asm + in al,21h + or al,1 + out 21h,al +end; + +procedure EnableTimerIRQ; assembler; +asm + in al,21h + and al,0feh + out 21h,al +end; + +procedure TimerSetup(Hz: Longint); +begin + _debug_str_ := 'TIMERINT.PAS:TimerSetup'; + If (Hz < 19) then Hz := 19; + If (Hz > 1193180) then Hz := 1193180; + + counter := 1193180 DIV Hz; + clock_flag := Hz*1000 DIV 18206; + newint08 := @int08; + ticks := 0; + clock_ticks := 0; + + DisableTimerIRQ; + asm + mov al,36h + out 43h,al + mov bx,counter + mov al,bl + out 40h,al + mov al,bh + out 40h,al + end; + + SetIntVec($08,newint08); + EnableTimerIRQ; +end; + +procedure TimerDone; +begin + _debug_str_ := 'TIMERINT.PAS:TimerDone'; + DisableTimerIRQ; + asm + mov al,36h + out 43h,al + xor ax,ax + out 40h,al + out 40h,al + end; + + SetIntVec($08,oldint08); + EnableTimerIRQ; +end; + +procedure TimerInstallHandler(handler: Pointer); +begin + _debug_str_ := 'TIMERINT.PAS:TimerInstallHandler'; + DisableTimerIRQ; + timer_handler := handler; + EnableTimerIRQ; +end; + +procedure TimerRemoveHandler; +begin + _debug_str_ := 'TIMERINT.PAS:TimerRemoveHandler'; + DisableTimerIRQ; + timer_handler := NIL; + EnableTimerIRQ; +end; + +begin + GetIntVec($08,oldint08); +end. diff --git a/16/ADT2PLAY/typconst.inc b/16/ADT2PLAY/typconst.inc new file mode 100644 index 00000000..dfe27e72 --- /dev/null +++ b/16/ADT2PLAY/typconst.inc @@ -0,0 +1,12 @@ +const + BYTE_NULL = $0ff; + WORD_NULL = $0ffff; + DWORD_NULL = $0ffffffff; + +type + tCHAR8x8 = array[char] of array[0..7] of Byte; + tCHAR8x16 = array[char] of array[0..15] of Byte; + +type + tRGB = Record r,g,b: Byte end; + tRGB_PALETTE = array[0..255] of tRGB; diff --git a/16/ADT2PLAY/unpk_lib.pas b/16/ADT2PLAY/unpk_lib.pas new file mode 100644 index 00000000..62b872d0 --- /dev/null +++ b/16/ADT2PLAY/unpk_lib.pas @@ -0,0 +1,977 @@ +unit UNPK_LIB; +interface + +// Compression algorithm: RDC +// Algorithm developed by Ed Ross +function RDC_decompress(var source,dest; size: Word): Word; + +// Compression algorithm: LZSS +// Algorithm developed by Lempel-Ziv-Storer-Szymanski +function LZSS_decompress(var source,dest; size: Word): Word; + +// Compression algorithm: LZW +// Algorithm developed by Lempel-Ziv-Welch +function LZW_decompress(var source,dest): Word; + +// Compression algorithm: SixPack +// Algorithm developed by Philip G. Gage +function SIXPACK_decompress(var source,dest; size: Word): Word; + +// Compression algorithm: aPack +// Algorithm developed by Joergen Ibsen +function APACK_decompress(var source,dest): Longint; + +implementation + +const + WORKMEM_SIZE = 64*1024; + +var + work_mem: array[0..PRED(WORKMEM_SIZE)] of Byte; + ibufCount,ibufSize: Word; + input_size,output_size: Word; + input_ptr,output_ptr,work_ptr: Pointer; + +var + ibuf_idx,ibuf_end,obuf_idx,obuf_src: Pointer; + ctrl_bits,ctrl_mask, + command,count,offs: Word; + +procedure RDC_decode; assembler; +asm + mov ctrl_mask,0 + mov eax,input_ptr + mov ibuf_end,eax + xor eax,eax + mov ax,input_size + add ibuf_end,eax + mov eax,input_ptr + mov ibuf_idx,eax + mov eax,output_ptr + mov obuf_idx,eax +@@1: xor ecx,ecx + mov eax,ibuf_idx + cmp eax,ibuf_end + jnb @@7 + mov ax,ctrl_mask + shr ax,1 + mov ctrl_mask,ax + or ax,ax + jnz @@2 + mov esi,ibuf_idx + lodsw + mov ctrl_bits,ax + add ibuf_idx,2 + mov ctrl_mask,8000h +@@2: mov ax,ctrl_bits + and ax,ctrl_mask + or ax,ax + jnz @@3 + mov esi,ibuf_idx + mov edi,obuf_idx + movsb + inc ibuf_idx + inc obuf_idx + jmp @@1 +@@3: xor ah,ah + mov esi,ibuf_idx + lodsb + shr ax,4 + and ax,0fh + mov command,ax + xor ah,ah + mov esi,ibuf_idx + lodsb + and ax,0fh + mov count,ax + inc ibuf_idx + cmp command,0 + jnz @@4 + add count,3 + mov edi,obuf_idx + mov cx,count + mov esi,ibuf_idx + lodsb + rep stosb + inc ibuf_idx + mov cx,count + add obuf_idx,ecx + jmp @@1 +@@4: cmp command,1 + jnz @@5 + xor ah,ah + mov esi,ibuf_idx + lodsb + shl ax,4 + add count,ax + inc ibuf_idx + add count,19 + mov edi,obuf_idx + mov cx,count + mov esi,ibuf_idx + lodsb + rep stosb + inc ibuf_idx + mov cx,count + add obuf_idx,ecx + jmp @@1 +@@5: cmp command,2 + jnz @@6 + mov ax,count + add ax,3 + mov offs,ax + xor ah,ah + mov esi,ibuf_idx + lodsb + shl ax,4 + add offs,ax + inc ibuf_idx + xor ah,ah + mov esi,ibuf_idx + lodsb + mov count,ax + inc ibuf_idx + add count,16 + mov eax,obuf_idx + mov cx,offs + sub eax,ecx + mov obuf_src,eax + mov esi,eax + mov edi,obuf_idx + mov cx,count + rep movsb + mov cx,count + add obuf_idx,ecx + jmp @@1 +@@6: mov ax,count + add ax,3 + mov offs,ax + xor ah,ah + mov esi,ibuf_idx + lodsb + shl ax,4 + add offs,ax + inc ibuf_idx + mov eax,obuf_idx + mov cx,offs + sub eax,ecx + mov obuf_src,eax + mov esi,eax + mov edi,obuf_idx + mov cx,command + rep movsb + mov cx,command + add obuf_idx,ecx + jmp @@1 +@@7: mov eax,obuf_idx + sub eax,output_ptr + mov output_size,ax +end; + +function RDC_decompress(var source,dest; size: Word): Word; +begin + input_ptr := @source; + output_ptr := @dest; + input_size := size; + RDC_decode; + RDC_decompress := output_size; +end; + +const + N = 4096; + F = 18; + THRESHOLD = 2; + +procedure GetChar; assembler; +asm + push ebx + mov bx,ibufCount + cmp bx,ibufSize + jb @@1 + jmp @@2 +@@1: push edi + mov edi,input_ptr + mov al,byte ptr [edi+ebx] + pop edi + inc ebx + mov ibufCount,bx + pop ebx + clc + jmp @@3 +@@2: pop ebx + stc +@@3: +end; + +procedure PutChar; assembler; +asm + push ebx + mov bx,output_size + push edi + mov edi,output_ptr + mov byte ptr [edi+ebx],al + pop edi + inc ebx + mov output_size,bx + pop ebx +end; + +procedure LZSS_decode; assembler; +asm + mov ibufCount,0 + mov ax,input_size + mov ibufSize,ax + mov output_size,0 + xor ebx,ebx + xor edx,edx + mov edi,N-F +@@1: shr dx,1 + or dh,dh + jnz @@2 + call GetChar + jc @@5 + mov dh,0ffh + mov dl,al +@@2: test dx,1 + jz @@3 + call GetChar + jc @@5 + push esi + mov esi,work_ptr + add esi,edi + mov byte ptr [esi],al + pop esi + inc edi + and edi,N-1 + call PutChar + jmp @@1 +@@3: call GetChar + jc @@5 + mov ch,al + call GetChar + jc @@5 + mov bh,al + mov cl,4 + shr bh,cl + mov bl,ch + mov cl,al + and cl,0fh + add cl,THRESHOLD + inc cl +@@4: and ebx,N-1 + push esi + mov esi,work_ptr + mov al,byte ptr [esi+ebx] + add esi,edi + mov byte ptr [esi],al + pop esi + inc edi + and edi,N-1 + call PutChar + inc ebx + dec cl + jnz @@4 + jmp @@1 +@@5: +end; + +function LZSS_decompress(var source,dest; size: Word): Word; + +begin + input_ptr := @source; + output_ptr := @dest; + work_ptr := @work_mem; + input_size := size; + FillChar(work_ptr^,WORKMEM_SIZE,0); + LZSS_decode; + LZSS_decompress := output_size; +end; + +var + le76,le77: Byte; + le6a,le6c,le6e,le70,le72,le74,le78, + le7a_0,le7a_2,le7a_4,le7a_6,le7a_8,le82a,le82b: Word; + +procedure NextCode; assembler; +asm + mov bx,le82a + mov ax,le82b + add bx,le78 + adc ax,0 + xchg bx,le82a + xchg ax,le82b + mov cx,bx + and cx,7 + shr ax,1 + rcr bx,1 + shr ax,1 + rcr bx,1 + shr ax,1 + rcr bx,1 + mov esi,input_ptr + mov ax,[ebx+esi] + mov dl,[ebx+esi+2] + or cx,cx + jz @@2 +@@1: shr dl,1 + rcr ax,1 + loop @@1 +@@2: mov bx,le78 + sub bx,9 + shl bx,1 + and ax,[ebx+le7a_0] +end; + +function LZW_decode: Word; assembler; +asm + xor eax,eax + xor ebx,ebx + xor ecx,ecx + mov le72,0 + mov le78,9 + mov le70,102h + mov le74,200h + mov edi,output_ptr + xor eax,eax + mov le6a,ax + mov le6c,ax + mov le6e,ax + mov le76,al + mov le77,al + mov le82a,ax + mov le82b,ax + mov le7a_0,1ffh + mov le7a_2,3ffh + mov le7a_4,7ffh + mov le7a_6,0fffh + mov le7a_8,1fffh +@@1: call NextCode + cmp ax,101h + jnz @@2 + jmp @@9 +@@2: cmp ax,100h + jnz @@3 + mov le78,9 + mov le74,200h + mov le70,102h + call NextCode + mov le6a,ax + mov le6c,ax + mov le77,al + mov le76,al + mov al,le77 + mov byte ptr [edi],al + inc edi + jmp @@1 +@@3: mov le6a,ax + mov le6e,ax + cmp ax,le70 + jb @@4 + mov ax,le6c + mov le6a,ax + mov al,le76 + push eax + inc le72 +@@4: cmp le6a,0ffh + jbe @@5 + mov esi,work_ptr + mov bx,le6a + shl bx,1 + add bx,le6a + mov al,[ebx+esi+2] + push eax + inc le72 + mov ax,[ebx+esi] + mov le6a,ax + jmp @@4 +@@5: mov ax,le6a + mov le76,al + mov le77,al + push eax + inc le72 + xor ecx,ecx + mov cx,le72 + jecxz @@7 +@@6: pop eax + mov byte ptr [edi],al + inc edi + loop @@6 +@@7: mov le72,0 + push esi + mov bx,le70 + shl bx,1 + add bx,le70 + mov esi,work_ptr + mov al,le77 + mov [ebx+esi+2],al + mov ax,le6c + mov [ebx+esi],ax + inc le70 + pop esi + mov ax,le6e + mov le6c,ax + mov bx,le70 + cmp bx,le74 + jl @@8 + cmp le78,14 + jz @@8 + inc le78 + shl le74,1 +@@8: jmp @@1 +@@9: mov output_size,ax +end; + +function LZW_decompress(var source,dest): Word; +begin + input_ptr := @source; + output_ptr := @dest; + work_ptr := @work_mem; + LZW_decode; + LZW_decompress := output_size; +end; + +const + MAXFREQ = 2000; + MINCOPY = 3; + MAXCOPY = 255; + COPYRANGES = 6; + TERMINATE = 256; + FIRSTCODE = 257; + ROOT = 1; + CODESPERRANGE = MAXCOPY-MINCOPY+1; + MAXCHAR = FIRSTCODE+COPYRANGES*CODESPERRANGE-1; + SUCCMAX = MAXCHAR+1; + TWICEMAX = 2*MAXCHAR+1; + MAXBUF = PRED(64*1024); + MAXDISTANCE = 21389; + MAXSIZE = 21389+MAXCOPY; + +const + BitValue: array[1..14] of Word = (1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192); + CopyBits: array[0..PRED(COPYRANGES)] of Word = (4,6,8,10,12,14); + CopyMin: array[0..PRED(COPYRANGES)] of Word = (0,16,80,336,1360,5456); + +var + leftC,rghtC: array[0..MAXCHAR] of Word; + dad,freq: array[0..TWICEMAX] of Word; + index,ibitCount,ibitBuffer,obufCount: Word; + +procedure InitTree; assembler; +asm + xor edi,edi + mov di,2 + mov bx,2 + mov cx,1 +@@1: xor dx,dx + mov ax,di + div bx + push edi + shl di,1 + mov word ptr dad[edi],ax + mov word ptr freq[edi],cx + pop edi + inc di + cmp di,TWICEMAX + jbe @@1 + mov di,1 +@@2: xor dx,dx + mov ax,di + mul bx + push edi + shl di,1 + mov word ptr leftC[edi],ax + inc ax + mov word ptr rghtC[edi],ax + pop edi + inc di + cmp di,MAXCHAR + jbe @@2 +end; + +procedure UpdateFreq(a,b: Word); assembler; +asm + xor ecx,ecx + xor edi,edi +@@1: mov di,a + shl di,1 + mov bx,word ptr freq[edi] + mov di,b + shl di,1 + add bx,word ptr freq[edi] + mov di,a + shl di,1 + mov dx,word ptr dad[edi] + mov di,dx + shl di,1 + mov word ptr freq[edi],bx + mov a,dx + cmp a,ROOT + jz @@3 + mov di,a + shl di,1 + mov di,word ptr dad[edi] + mov ax,di + shl di,1 + mov bx,word ptr leftC[edi] + cmp a,bx + jnz @@2 + mov di,ax + shl di,1 + mov bx,word ptr rghtC[edi] + mov b,bx + jmp @@3 +@@2: mov di,ax + shl di,1 + mov bx,word ptr leftC[edi] + mov b,bx +@@3: cmp a,ROOT + jnz @@1 + mov bx,MAXFREQ + mov di,ROOT + shl di,1 + cmp word ptr freq[edi],bx + jnz @@5 + lea esi,[freq] + lea edi,[freq] + mov cx,TWICEMAX + movsw +@@4: lodsw + shr ax,1 + stosw + loop @@4 +@@5: +end; + +procedure UpdateModel(code: Word); assembler; +asm + xor ecx,ecx + xor edi,edi + mov bx,code + add bx,SUCCMAX + mov di,bx + shl di,1 + mov ax,di + mov cx,word ptr freq[edi] + inc cx + mov word ptr freq[edi],cx + mov di,ax + mov cx,ROOT + cmp word ptr dad[edi],cx + jz @@10 + mov dx,word ptr dad[edi] + push edi + lea edi,[leftC] + mov cx,dx + shl cx,1 + add edi,ecx + mov si,word ptr [edi] + pop edi + cmp si,bx + jnz @@1 + mov di,dx + shl di,1 + mov si,word ptr rghtC[edi] +@@1: push ebx + push edx + push ebx + push esi + call UpdateFreq + pop edx + pop ebx +@@2: xor edi,edi + mov di,dx + shl di,1 + mov ax,word ptr dad[edi] + mov di,ax + shl di,1 + mov cx,di + cmp word ptr leftC[edi],dx + jnz @@3 + mov di,cx + mov si,word ptr rghtC[edi] + jmp @@4 +@@3: mov si,word ptr leftC[edi] +@@4: xor edi,edi + mov di,bx + shl di,1 + push eax + mov ax,word ptr freq[edi] + mov di,si + shl di,1 + mov cx,ax + pop eax + cmp cx,word ptr freq[edi] + jbe @@9 + mov di,ax + shl di,1 + mov cx,di + cmp word ptr leftC[edi],dx + jnz @@5 + mov di,cx + mov word ptr rghtC[edi],bx + jmp @@6 +@@5: xor edi,edi + mov di,cx + mov word ptr leftC[edi],bx +@@6: lea edi,[leftC] + xor ecx,ecx + mov cx,dx + shl cx,1 + add edi,ecx + cmp word ptr [edi],bx + jnz @@7 + mov word ptr [edi],si + xor edi,edi + mov di,cx + mov cx,word ptr rghtC[edi] + jmp @@8 +@@7: xor edi,edi + mov di,cx + mov word ptr rghtC[edi],si + mov cx,word ptr leftC[edi] +@@8: xor edi,edi + mov di,si + shl di,1 + mov word ptr dad[edi],dx + mov di,bx + shl di,1 + mov word ptr dad[edi],ax + push esi + push esi + push ecx + call UpdateFreq + pop ebx +@@9: xor edi,edi + mov di,bx + shl di,1 + mov bx,word ptr dad[edi] + mov di,bx + shl di,1 + mov dx,word ptr dad[edi] + cmp dx,ROOT + jnz @@2 +@@10: +end; + +function InputCode(bits: Word): Word; assembler; +asm + xor bx,bx + xor ecx,ecx + mov cx,1 +@@1: cmp ibitCount,0 + jnz @@3 + cmp ibufCount,MAXBUF + jnz @@2 + mov ax,input_size + mov ibufCount,0 +@@2: mov edi,input_ptr + xor edx,edx + mov dx,ibufCount + shl dx,1 + add edi,edx + mov ax,[edi] + mov ibitBuffer,ax + inc ibufCount + mov ibitCount,15 + jmp @@4 +@@3: dec ibitCount +@@4: cmp ibitBuffer,7fffh + jbe @@5 + xor edi,edi + mov di,cx + dec di + shl di,1 + mov ax,word ptr BitValue[edi] + or bx,ax +@@5: shl ibitBuffer,1 + inc cx + cmp cx,bits + jbe @@1 + mov ax,bx +end; + +function Uncompress: Word; assembler; +asm + xor eax,eax + xor ebx,ebx + mov bx,1 + mov dx,ibitCount + mov cx,ibitBuffer + mov ax,ibufCount +@@1: or dx,dx + jnz @@3 + cmp ax,MAXBUF + jnz @@2 + mov ax,input_size + xor ax,ax +@@2: shl ax,1 + mov edi,input_ptr + add edi,eax + shr ax,1 + mov cx,[edi] + inc ax + mov dx,15 + jmp @@4 +@@3: dec dx +@@4: cmp cx,7fffh + jbe @@5 + mov edi,ebx + shl edi,1 + mov bx,word ptr rghtC[edi] + jmp @@6 +@@5: mov edi,ebx + shl edi,1 + mov bx,word ptr leftC[edi] +@@6: shl cx,1 + cmp bx,MAXCHAR + jle @@1 + sub bx,SUCCMAX + mov ibitCount,dx + mov ibitBuffer,cx + mov ibufCount,ax + push ebx + push ebx + call UpdateModel + pop eax +end; + +procedure SIXPACK_decode; assembler; +asm + mov ibitCount,0 + mov ibitBuffer,0 + mov obufCount,0 + mov ibufCount,0 + xor ebx,ebx + xor ecx,ecx + mov count,0 + call InitTree + call Uncompress +@@1: cmp ax,TERMINATE + jz @@10 + cmp ax,256 + jae @@3 + mov edi,output_ptr + push ebx + mov bx,obufCount + add edi,ebx + pop ebx + stosb + inc obufCount + mov bx,MAXBUF + cmp obufCount,bx + jnz @@2 + mov output_size,bx + mov obufCount,0 +@@2: mov edi,work_ptr + push ebx + mov bx,count + add edi,ebx + pop ebx + stosb + inc count + cmp count,MAXSIZE + jnz @@9 + mov count,0 + jmp @@9 +@@3: sub ax,FIRSTCODE + mov cx,ax + xor dx,dx + mov bx,CODESPERRANGE + div bx + mov index,ax + xor dx,dx + mul bx + mov bx,cx + add bx,MINCOPY + sub bx,ax + mov si,bx + xor edi,edi + mov di,index + shl di,1 + mov bx,word ptr CopyBits[edi] + push ebx + call InputCode + add ax,si + xor edi,edi + mov di,index + shl di,1 + add ax,word ptr CopyMin[edi] + mov bx,count + mov dx,bx + sub dx,ax + mov cx,dx + cmp count,ax + jae @@4 + add cx,MAXSIZE +@@4: xor dx,dx +@@5: mov edi,work_ptr + add edi,ecx + mov al,byte ptr [edi] + mov edi,output_ptr + push ebx + mov bx,obufCount + add edi,ebx + pop ebx + mov byte ptr [edi],al + inc obufCount + mov ax,MAXBUF + cmp obufCount,ax + jnz @@6 + mov output_size,ax + mov obufCount,0 +@@6: mov edi,work_ptr + push edi + add edi,ecx + mov al,byte ptr [edi] + pop edi + add edi,ebx + mov byte ptr [edi],al + inc bx + cmp bx,MAXSIZE + jnz @@7 + xor bx,bx +@@7: inc cx + cmp cx,MAXSIZE + jnz @@8 + xor cx,cx +@@8: inc dx + cmp dx,si + jb @@5 + mov ax,si + add count,ax + cmp count,MAXSIZE + jb @@9 + sub count,MAXSIZE +@@9: call Uncompress + jmp @@1 +@@10: mov bx,obufCount + mov output_size,bx +end; + +function SIXPACK_decompress(var source,dest; size: Word): Word; +begin + input_ptr := @source; + output_ptr := @dest; + work_ptr := @work_mem; + input_size := size; + SIXPACK_decode; + SIXPACK_decompress := output_size; +end; + +function APACK_decompress(var source,dest): Longint; assembler; +asm + mov esi,[source] + mov edi,[dest] + cld + mov dl,80h +@@1: movsb +@@2: add dl,dl + jnz @@3 + mov dl,[esi] + inc esi + adc dl,dl +@@3: jnc @@1 + xor ecx,ecx + add dl,dl + jnz @@4 + mov dl,[esi] + inc esi + adc dl,dl +@@4: jnc @@8 + xor eax,eax + add dl,dl + jnz @@5 + mov dl,[esi] + inc esi + adc dl,dl +@@5: jnc @@15 + inc ecx + mov al,10h +@@6: add dl,dl + jnz @@7 + mov dl,[esi] + inc esi + adc dl,dl +@@7: adc al,al + jnc @@6 + jnz @@24 + stosb + jmp @@2 +@@8: inc ecx +@@9: add dl,dl + jnz @@10 + mov dl,[esi] + inc esi + adc dl,dl +@@10: adc ecx,ecx + add dl,dl + jnz @@11 + mov dl,[esi] + inc esi + adc dl,dl +@@11: jc @@9 + dec ecx + loop @@16 + xor ecx,ecx + inc ecx +@@12: add dl,dl + jnz @@13 + mov dl,[esi] + inc esi + adc dl,dl +@@13: adc ecx,ecx + add dl,dl + jnz @@14 + mov dl,[esi] + inc esi + adc dl,dl +@@14: jc @@12 + jmp @@23 +@@15: lodsb + shr eax,1 + jz @@25 + adc ecx,ecx + jmp @@20 +@@16: xchg eax,ecx + dec eax + shl eax,8 + lodsb + xor ecx,ecx + inc ecx +@@17: add dl,dl + jnz @@18 + mov dl,[esi] + inc esi + adc dl,dl +@@18: adc ecx,ecx + add dl,dl + jnz @@19 + mov dl,[esi] + inc esi + adc dl,dl +@@19: jc @@17 + cmp eax,32000 + jae @@20 + cmp ah,5 + jae @@21 + cmp eax,7fh + ja @@22 +@@20: inc ecx +@@21: inc ecx +@@22: xchg eax,@dummy +@@23: mov eax,@dummy +@@24: push esi + mov esi,edi + sub esi,eax + rep movsb + pop esi + jmp @@2 +@@25: sub edi,[dest] + mov eax,edi + jmp @ret + +@dummy: dd 0 +@ret: +end; + +end. diff --git a/inputest.exe b/inputest.exe index 4f9190c4eb5db794717115bdce3f058f93d138f7..c6a2851f8d860496cf0d154673ca19813a128dbd 100644 GIT binary patch delta 13649 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%0D2N0xARZ3e|FL%k=}_RI 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 M-Zd)eY$hT93v`o7C;$Ke delta 13959 zcmb_@3sh6b+Vf2W-l|r#7u2?DZF^$rX|49CRS$g6Ov2^3y1upkwSHVrGV{zk zGw;0f&dfV|$A29a|L3@9ojiN0(4RaiOeNK%txcySG9eAVgoG2<->)MHX$5qn2r&U0 zfZn4C84H+IwNe4TR{_U?AAqnigv0~Mz#O0y_!|(QMLpmR;3r_%SVC5eC01fb;_tv& zU|upI-vK`Z&!-SlHja=VfxAFJDj|;mqk!eWCZGkdq!F?OI0%d%Pe=~%E^r^1pd;jC z;H`8*ZUT=^fI`5}QmynWa8t6@O1F`?2ebmBvR3i{yZ}GIA5a6mfiNHvhz8<;fxuuu z1B?W;z&Jn$Oai6=S-=cn4U9>F{{cP%z6b6C{`48)5$jjpgv^Fi4lo}u0*iqnzyvG< zRsySmX?}!!3moZ2NOX5XvI7Zu7WjKlLf!#B1kM4I)r8#ZMab$PmNyok`hPAW57b-b^<1D7(5E_98Sm|z#Sl91R-(2 zV!#5N1pW<#!8@k|c|Zy9BJdG#0r*L*m3{_p0=I#CKr0|BFwcM&;Ah2$KcEJB17ScU z5Dmlw1A)PS1{euwfpLHim;_7#vVa-DY#;}i4;X>PKoMX9mH{h))xfjBb3i3vb>QO# zU^DOvunpJ&yant6_5k~U4}b%}VW0sx3Y-Ma0Ox?OfQ!I)!1usUz|X+1z)j#ba1Uq& zM0mRg;3d^sB|jwm0X5JY2m>O4XdoUK2n+@^z(_y~j01GQBwz}V1q`eIv#{75%||^p%EI-lr0o7xi*KEanGEK0a=Wq299YpD zWlj9S*2qgLK0K|uzMJs$_6Akeg&mD5+wqF##9u1HGG*J*im(RN(Y2>lLYa1>Ow2xY z4s=ktmI&9Ep#6~+Wtrv^mB6c)Y4514#G)$GDj*qKscYrE@Cxh8$mkT)$kDS)H3y;4 zr84a&Dq@b8!ds&MTaJ*?xhDV7D@*;l$cg>K*Vdb5&g_^XyN3jQc&c3MK!4s`L8V1% zQ#*%i<;Nx?lPyoJm>E8=@j><^^agPZ!`vt7Qj4qZX?A4FnjKRp^)X;jfBLMnqPAsM z%MFZ3pMw#7Eq^Va@H*l3vsWAbWzAsK%YX5+9kb=!wM}`D_%GZ2cO^&8gY(yt>V^9@ z-OZ+JHr*eJoV&1TWqNqhxzQe_PgLk`SIoF$&$-=nZD8BqpOv@R8k?>(T{%2e#_Z0x z*L1~^b5A&0Iaf+-vuetq8nJj+&Q-dSX2tbFQaM+2=i)2pD%?qBOX&4~3hzp``{%C- z_nWRk4Rl;)4HGTWQC({rT7__8n_E1!qY=ySzpNCAN><_e8p11z?G-IEJG)d|UjSVs zcZ+>Hl(Yo>WsBnbE+v%hZJGOZ))rg-q7qYHd|zN1gmhFA#&L~=4nk4hAXYfHysNV5 zZlAxBpt}v5W9e_{%-(!hAG_`kTY6AMafn@a)0W;F(iQ2U6=$P_iu6Eyi52NRE6#== zr$yboth}kl3TM-`E#-}3ve0N29z%O~&tDPl+GpHl^YuVz&{VE3Q`*i~q=&ifb;o5E zi*Hw}7hK;&HcYvhbZJYrtzkpXAL{a-#c8&)RZY$}@7T^d2mWbmXz8~h=jI08A5~3N z=bRtkuCpqL^R?S8-PLu7Go1rH%a2GF#dWVX3}IdUGs?QQwieIT$~u9xh)MMopJG6u zRgCV|60q761#rIWf3~6!-@mtZn7pf3xd&vQ@c?7WVPm=|G&0{YCk=;br>g5lqVs(+ zY*Bv1gXL3^-yu6LR;Gu!nG7%+Wn}njncYYey2p4sq{C%`qoL~D!5eg5_h{=4QDcAU zrZ_LhwGOvu%Ge<8Vr^#11S^s);_Xw~xhb5><|GrejKd0NTSY(}jH3Iu*_(Z9|82R8 zWsODek;+#6c^IDUG&gO{&iXs+>dn`Y_z(%poq5(djfp=ve<$t^=QOrA4)&6pb@w5& zwy*tRx!b;*1iIVxM05GPxzv__I&<65cQ)IsHI-^?A1(#GSmn3=FpK+y_UdX@U4~xX zsP92-JtA>3?Cvo!`Lv3)fCefW;nEdY@S2e@hefHW&}Pc+GIrj<#ZIf3?We=iYdv@t z=B9o9w`g$keRA-GXL)0{vTHY@ZDFq}qpQL;D;3|k7)O)+8rW@0`}wAyUH_uXw6Dy7yOU3t2_=V?cdlx-SLJpJo>QGhPoe} z@cg)5mGJpqa%)$)_AMo`1l0}bUh|f+%5SH#W*5G8D{J=PYp-(1zv}vTui1z6dvJ5& z3|Bh;Ax%9{O9ur8^$3F2hbDSuPtB_O+;RCpx*wet7#i}J-$x>OFZp!Dtf_T`9Oy=z zk0@uomvK5`YF#aTJ}_I@Mt=;PEj(V6+*9zx6~gtmf2{gbLHL|1gA9S63(01s^HI5? zq2dONeoS+F-RE?5P|{;plvxLArK%aNPJbC5&JMWitL{&mVf)1Pm9t)kpDA*lXtW)- z-E*2=enqa?A=lJ_*d|wR!Pf_J&8u?Fdvtd1 zY@v4lp5D8K-YlZ4ehb2HU_cg+b>}SN>_*#JyZS9^4l!82x*KIUVAqo#fq zk5Srsr74uN)kiSJ^-7zjL5XcdeN@@wCORmEhKa5)su4X3`+a=GQ)eFgQF?qHr_Z%0J+HAT9_VHeh2HTX@ zXf#95hek=ql{Kg6{m_9uA=TWnpAV;8dmQfRX;UAk+OUw+Q_Ab5ZQ0XoP3z8?94G2Tvo}L_`W3)PXkArXH=T>rR|s-r)-HEGueLYgM-9>*H=_*&6<$T_0UN zl712UQ5ez}!6Rx>Ab1#arLFX?GK7qR@0Tbb@^)M~yGdNMYYxflZkx3uj+V;yK;hQ;a(zB& zZ!jEv4d!Kk)mIQUnA7pShQbkUIWr${3)rCSDD+a|X;1TF<}D4#fs4A@cPamQOIc0Y z{-A^}gcyvX`S2NKS@eIDcWs}P`Ta*JIWCm1@*);BZ!M|5X0Kecj|L1#j6yGyJ>byl z-E#FF*^$#~8!tl0){{ATt4+IGuGvEu4jAS)OF(bVM_O7o9n-be(%l34_~Xe);~6D< zKIeg5y+^i(?WPw7j1*$`2M!!3VnxqPoaXI|E$hMz$K^KNA8qPo^!-sKLM@FOogBcF zEY}{z_2znIjx({Xa{URqYIHLW5~ky&q&9mP40*}yJK{T&C;GT-*GnzGxva5Dw9S>) zwVB7+EYiA5mK5x*m19Q5!^;l31WLu0_p^Dj8jaMO18t3Vy}w;0G%H28!Y2CLm{A@~ z12{yYw%;(G)Gf{YuS}( zr)4X4?ktz?o0Q7#BI@N5}pZg{u+K%yU z8<#tcYeMghE#u2&l*a^>Ntsj+uY)bsCKUqwFtbWHZ&!iJp2n+jAqBL8h+l`uXSQCT zx^#jg6gF$RVn+k4sWta&C5y+Jdy`b=7+aI=q7A2*a|EL4R_y-GdPCpxuB&Xy1G{#DDgh#i^-Wis z{^@8?tZtoIc?E)RLvWWKb5Ubb;lgZFn^iRvR4o;5^SiVg1Lfo)OuP28$gFbKf5RKE zF{`Q%<6JeVCb62#lr!8_q*GECK2*MKkj^f;S07Uqqri;hce>LavU>M-Q7 zOv84|cI_TIEmenSCWm*^t*KfA1OwsSdvTKPlN}dqtV7#O5$h;yFE-MBEP~)iBbydJ zclNM-h!gh8SWlkoPFR%u25tMy0ovAFb{}2|8{3_HGdT%5mAg`nGMxzRDMOzM#9}1@$lCu|?(UJL%85 zIZraLPAg+@Pig{23vv~R|ED4Crx4xgJdQn1rDXJjctV+)tZjp>)?Nn#6E zxDt8!CJr7G4K>n0$6}jUzeY|5yHR?#9^2p9h#_D9~<&7m@zI>iY<#2jENVGo^>A^8zBn{iWe-&D zqQ_vQ>A=@|(|sFG*2Ii;Ej-p zQ!@0ZJ)yXG33vy6S)Ypw0A4HQo2KW^FED^Cqh3#@@+M1`8W!Z|7J%Ehf9{jb0+%ev zEis$(3z_7m{b}=6vM_{ZERGT0q2|T?vj_JeTuVpW9V=La6d3%~XiBSf% z+4DA1{z(1D>pxzE7(C2^eP|t$sxM-gdeVstu&?nD5`Xyo;i{KH&4qoXFyBI7y0vgrL^57!#`qe2jbo7*>zn0k)FP4U zI~A{{SvN1!JB1Nak?(3>8d4PPy9I?N-=|SnAzY@JMUknieP7`k92XW8=NYh)moUFJ zeh0y4eP7~&Nmy0vZ2^%KnEZ)T^iRzvm>Lk`^U^E64fMUDXjLMFw)uWcuNEZ<4`@Jf z(?kBfk=`m!kgoLb^QVzZ{`QB#V|`te1@mW7M-lMRK%rWGh{zEoxTg=G^(e^7*X$~DpJrjFN}%tb^opgTQX zk`O$wqe@9(Zb5;b%@|r5*q!z;53+8Nd4p^mxu%87i1cbF;byjXG7wonq#d0E69KbP z#dTn<=yQvTi-ry((w>Joyk*uvOeE7`cS+1IGA~c0ADcY_Iy3||T(ca?eM+0nvBGau zunZFJ(IiW(Kig5<1D`lFjVPw|pi3-KB4+4$OH}B5I9^vfc9@JP41x5VWteCUq~6P7 z2X2QTH`W4}0tPQKJ1Y9+BSYWQvN1!`Ayc3BAq=2UwI_lviLd5ovR0$THSHxK} z5VyEzIe&hketv#&iJn=_oWEcRYv4&1*SNf(od$cjy%rBTK=AO#CFY{wFj(u-PIu3e zo)d-naLE$Gg5sjQ5=@+mV2Dhw+bbf4A8GK)7;KR#D+3G<+S_N#xp)B@!ehvGW9f~H z47r%+lMho_#mksKoa(}7z&x1g?EIC6aYNnZuew(){b*%mKwEJ8_>D%Bf$bV?^w*V9 zVoGls_;l2;mwR^%-?B6>*KE+ww-}8EwxGW6EP^w^WE~|^A6oo$w0s5!0dsTu+S7f- z^bp$cbd>c>7v1uU=MzZ-W!!7Q=<h?9c^ySN9@>aB zNkn?@VQw&DK*Oq@y&ey7kBRxVeyPO_`zi`U=<};$BL?CJI&OCuUt~6zX3m(HHa-*f zAMVzZUR)K^=e;hP=u`NfTIZ%{$TNLqJmYtbJpGvnYZjVxc@R5AT>CvXZ}iDZ+@0|v z?2Utmw4V~$?S<}BqpUse7LZ1}J7F7gXH6n$yYM(D=s%z7H=b?YZYyW=Q)|{l*Y52m z#~0=4AEI1xPe2au(_N#Pwz{u;pnaUHRu7*1N{3EG9gdpZ*_FPCIqH1FLL!ap!cN9g zn1BMeJEpZae}DDRz6JPEl*=S(#S^DY&w`cS0mbc?SDcR^xrt_3`}X)LqFqiuap+{C z_=!GejS*Vu9_t{ndnCPV?Im2KcdYT^uqfKMEJ2LxN2iwc#|xBa%Hn%B_G_g`tR}qVZRP{3+mY! zv*humQw*h(nYTc^WCTrK8`$R+{ASIyp!6wui!CMQl)_>QIwOi-Xz|)4;ZIt!yo}T?$AOx-5h#I&47L*d}%1 zT*m}I3{73>Vm;p-i5+8ig;zB0IX|nuvoqd7elZinKtslKC|9xw9#ED+X)KC%SKP1^LW-%A%LS$ny z-C7YP?5Fh=al)7M=ZetqWnE@qye=K93r=k$(sDOXV{9=p-k-Rhntq z=fkbIpWmm?+d?9acZ^rBpFA!#dt!;}k}mCZTbQ1)MFfzPcC`u$T#Efj#mXpu-M9|k zMZZsnSN833t(`7G5QM->}gB zkMxi|LAXVo_82j8Jnc~xEAMO%3sS10LbT(#bK!@l@R7Xv*rUv@#i*D)p026t9kL1n z?#V2i&;61}j&}2ZSQQ;O6VHrX0)-`ra?s~Y9sRv3R$Qc`eKv#%-_nsA;?)Btv`ZNc z%a0IT-=D?O5+;L z|1h;^>kNb>(Zw()VOL@NG}+D6O5rSvzqi|kh>rgn-o@fGmarp2B!Bj4Zzxjf0S3DW z>C010oqkFm+Jgr8u0oh5iR|KtYdvQ^;LLBF@#f4=oVmvtKN_()pqCmUi6pYCBq6M| z51`&xk{6dw=Vgz=O!&n$XNoz)u9k#^a^_>sSUD5Hm;u*0!*7*Dgzt9#p>vF8E#ebN zJi_~l=WPh#jQN!_B4-jfvjg`QxFOTC=XB2SXQ!kTl0TrNAASCXp7KRrf?LX-7lPzg zp21z^%nLzru?Tu3k={fxT9Ami4 zYqDDG;Sp*wEmfN$S^I6&N`vLkcpA5W?KDXKoo8O|P3vh;Y(`%u#pdi&>96cj%FEM3 zUf2{ASIyI{ytl>Z7yj?olNs1G=f5D;kEU$uDG!NaE#s#VIh%rdE#(;&j}w9Wc5H)j^RWnf@+B+e*Fq(ww!Kv&2Hax(0Kc#ELZ}GB&P=$~lysa~wImMZ7 zoVm%FOPony%zz*SkP@O-Rx1JK@BDMQZZa=tVJ#j+b3=U28U6sDd=7RvYP~HDWUa}q zyeu=0CcYG;dLo`ReV%5%6f9eL8o}t&mxAQCc_t}=ZiLh>M5dD1Lf?5QSk=taztYc< zp3$H2f70Jx3hwm|PqUB=Lj#t%ClOux-sWX26eHwGKFHySY$fqBXNGf?=W~VyWB6|m zz;a%HAWfoy;k<~&NO)e0k+5CP<#eq`wcB>pK-T2@W0=%TKGHWigFq%^b5O6(c!q^D zuAK^xI8jyNeUC+qEQu^sA;b$j9@2L-yN{Q#U7Z)2Mc9kZLZ^T%hx|2CKI7^ey@fgpTtx z0*P%~gS>y^nF?t2HvMF4&t9QJSqnU(Ai-b{b7Q#H&x^c_#R~5AGvF*|7IEg&zZhAc zM_FquZopewy5_||A5P?O!gWHe!(*3 zVnjw}w;6=|FaO!|6#xJL diff --git a/makefile b/makefile index 90b48240..f1d5628b 100644 --- a/makefile +++ b/makefile @@ -25,7 +25,7 @@ WCPULIB=$(SRCLIB)wcpu$(DIRSEP) 16LIBOBJS = 16_in.$(OBJ) 16_mm.$(OBJ) wcpu.$(OBJ) 16_head.$(OBJ) scroll16.$(OBJ) 16_ca.$(OBJ) 16_snd.$(OBJ) GFXLIBOBJS = modex16.$(OBJ) bitmap.$(OBJ) planar.$(OBJ) 16text.$(OBJ) -all: 16.exe test.exe pcxtest.exe test2.exe palettec.exe maptest.exe fmemtest.exe fonttest.exe inputest.exe exmmtest.exe fonttes0.exe fontgfx.exe +all: 16.exe test.exe pcxtest.exe test2.exe palettec.exe maptest.exe fmemtest.exe fonttest.exe inputest.exe exmmtest.exe fonttes0.exe fontgfx.exe sountest.exe # #executables @@ -55,6 +55,9 @@ fontgfx.exe: fontgfx.$(OBJ) 16.lib inputest.exe: inputest.$(OBJ) 16.lib wcl $(FLAGS) inputest.$(OBJ) 16.lib +sountest.exe: sountest.$(OBJ) 16.lib + wcl $(FLAGS) sountest.$(OBJ) 16.lib + pcxtest.exe: pcxtest.$(OBJ) gfx.lib wcl $(FLAGS) pcxtest.$(OBJ) gfx.lib @@ -124,6 +127,9 @@ fontgfx.$(OBJ): $(SRC)fontgfx.c inputest.$(OBJ): $(SRC)inputest.c wcl $(FLAGS) -c $(SRC)inputest.c +sountest.$(OBJ): $(SRC)sountest.c + wcl $(FLAGS) -c $(SRC)sountest.c + exmmtest.$(OBJ): $(SRC)exmmtest.c wcl $(FLAGS) -c $(SRC)exmmtest.c diff --git a/sountest.exe b/sountest.exe new file mode 100644 index 0000000000000000000000000000000000000000..1930aaf795f8162157e8a1006b894b17bb009aab GIT binary patch literal 44275 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 literal 0 HcmV?d00001 diff --git a/src/lib/16_in.c b/src/lib/16_in.c index 687ec649..b2f31362 100644 --- a/src/lib/16_in.c +++ b/src/lib/16_in.c @@ -1208,8 +1208,10 @@ void IN_ClearKey(byte code) } boolean IN_qb(byte kee) -{ - printf("%u\n", inpu.Keyboard[kee]); +{ + #ifdef TESTKEYIN + printf("%u\n", inpu.Keyboard[kee]); + #endif if(inpu.Keyboard[kee]==true) return 1; else return 0; } diff --git a/src/lib/16_in.h b/src/lib/16_in.h index 792ac5b1..68f2d721 100644 --- a/src/lib/16_in.h +++ b/src/lib/16_in.h @@ -31,11 +31,11 @@ #include "src/lib/16_head.h" #ifdef __DEBUG__ -#define __DEBUG_InputMgr__ +//#define __DEBUG_InputMgr__ #endif #ifdef __DEBUG_InputMgr__ -//#define TESTKEYIN +#define TESTKEYIN #define TESTCONTROLNOISY #endif diff --git a/src/lib/16_snd.c b/src/lib/16_snd.c index 828237f5..47cab348 100644 --- a/src/lib/16_snd.c +++ b/src/lib/16_snd.c @@ -107,3 +107,89 @@ void FMReset(void/*int percusiveMode*/) //FMSetPercusiveMode(percusiveMode); } /* End of FMReset */ + +/* Function: FMKeyOff ******************************************************* +* +* Parameters: voice - which voice to turn off. +* +* Description: turns off the specified voice. +* +*/ +void FMKeyOff(int voice) +{ + int regNum; + + /* turn voice off */ + regNum = 0xB0 + voice % 11;//NUMVOICE; + opl2out(regNum, 0x0E); +} /* End of FMKeyOff */ + +/* Function: FMKeyOn ******************************************************* +* +* Parameters: voice - which voice to turn on. +* freq - its frequency (note). +* octave - its octave. +* +* Description: turns on a voice of specfied frequency and +* octave. +* +*/ +void FMKeyOn(int voice, int freq, int octave) +{ + int regNum, tmp; + + regNum = 0xA0 + voice % 11;//NUMVOICE; + opl2out(regNum, freq & 0xff); + regNum = 0xB0 + voice % 11;//NUMVOICE; + tmp = (freq >> 8) | (octave << 2) | 0x20; + opl2out(regNum, tmp); +} /* End of FMKeyOn */ + +/* Function: FMSetVoice ***************************************************** +* +* Parameters: voiceNum - which voice to set. +* ins - instrument to set voice. +* +* Description: sets the instrument of a voice. +* +*/ +void FMSetVoice(int voiceNum, FMInstrument *ins){ + int opCellNum, cellOffset; + + voiceNum %= 11;//NUMVOICE; + cellOffset = voiceNum % 3 + ((voiceNum / 3) << 3); + + /* set sound characteristic */ + opCellNum = 0x20 + (char)cellOffset; + opl2out(opCellNum, ins->SoundCharacteristic[0]); + opCellNum += 3; + opl2out(opCellNum, ins->SoundCharacteristic[1]); + + /* set level/output */ + opCellNum = 0x40 + (char)cellOffset; + opl2out(opCellNum, ins->Level[0]); + opCellNum += 3; + opl2out(opCellNum, ins->Level[1]); + + /* set Attack/Decay */ + opCellNum = 0x60 + (char)cellOffset; + opl2out(opCellNum, ins->AttackDecay[0]); + opCellNum += 3; + opl2out(opCellNum, ins->AttackDecay[1]); + + /* set Sustain/Release */ + opCellNum = 0x80 + (char)cellOffset; + opl2out(opCellNum, ins->SustainRelease[0]); + opCellNum += 3; + opl2out(opCellNum, ins->SustainRelease[1]); + + /* set Wave Select */ + opCellNum = 0xE0 + (char)cellOffset; + opl2out(opCellNum, ins->WaveSelect[0]); + opCellNum += 3; + opl2out(opCellNum, ins->WaveSelect[1]); + + /* set Feedback/Selectivity */ + opCellNum = (byte)0xC0 + (byte)voiceNum; + opl2out(opCellNum, ins->Feedback); +} /* End of FMSetVoice */ diff --git a/src/lib/16_snd.h b/src/lib/16_snd.h index 86c1de58..afadb348 100644 --- a/src/lib/16_snd.h +++ b/src/lib/16_snd.h @@ -30,9 +30,31 @@ #define ADLIB_FM_ADDRESS 0x388 /* adlib address/status register */ #define ADLIB_FM_DATA 0x389 /* adlib data register */ +/* +* FM Instrument definition for .SBI files - SoundBlaster instrument +* - these are the important parts - we will skip the header, but since +* I am not sure where it starts and ends so I have had to guess. +* However it SEEMS! to work. Each array has two values, one for +* each operator. +*/ +typedef struct{ + byte SoundCharacteristic[2]; /* modulator frequency multiple... */ + byte Level[2]; /* modulator frequency level... */ + byte AttackDecay[2]; /* modulator attack/decay... */ + byte SustainRelease[2]; /* modulator sustain/release... */ + byte WaveSelect[2]; /* output waveform distortion */ + byte Feedback; /* feedback algorithm and strength */ +} FMInstrument; + + void opl2out(word reg, word data); void opl3out(word reg, word data); void opl3exp(word data); + +//Unknown licence! void FMReset(void/*int percusiveMode*/); +void FMKeyOff(int voice); +void FMKeyOn(int voice, int freq, int octave); +void FMSetVoice(int voiceNum, FMInstrument *ins); #endif /*__16_SND_H_*/ diff --git a/src/sountest.c b/src/sountest.c new file mode 100644 index 00000000..b3d1c33a --- /dev/null +++ b/src/sountest.c @@ -0,0 +1,58 @@ +/* Project 16 Source Code~ + * Copyright (C) 2012-2015 sparky4 & pngwen & andrius4669 + * + * This file is part of Project 16. + * + * Project 16 is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Project 16 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see , or + * write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301 USA. + * + */ + +#include + +#include "src/lib/16_in.h" +#include "src/lib/16_snd.h" + +void main(int argc, char near *argv[]) +{ + static FMInstrument testInst = +{ +0x00, 0x01, /* modulator frequency multiple... 0x20 */ +0x00, 0x00, /* modulator frequency level... 0x40 */ +0xF0, 0xF0, /* modulator attack/decay... 0x60 */ +0x73, 0x73, /* modulator sustain/release... 0x80 */ +0x03, 0x00, /* output waveform distortion 0xE0 */ +0x36, /* feedback algorithm and strength 0xC0 */ +}; + + IN_Startup(); + FMReset(); + FMSetVoice(0, &testInst); + printf("p"); + while(!IN_qb(1)) + { + if(IN_qb(44)) + { + printf("e"); + FMKeyOn(0, 0x106, 4); + } + else + { + FMKeyOff(0); + } + } + printf("!\n"); + IN_Shutdown(); +} \ No newline at end of file -- 2.39.5