Autore Topic: Operator << >> In gambas  (Letto 1583 volte)

Offline eloaders

  • Gamberetto
  • *
  • Post: 38
    • Mostra profilo
Operator << >> In gambas
« il: 29 Novembre 2019, 18:24:18 »
Again I have to ask. I can't understand how to convert some code from C to gambas

Source file adress: https://github.com/lpereira/hardinfo/blob/master/modules/devices/spd-decode.c

Part of the code I'm trying to understand:

Codice: [Seleziona]
  ' unsigned int sdr_capacity = 256 << (bytes[4] & 0xF);
  ' unsigned int sdr_width = 4 << (bytes[7] & 0x7);
  ' unsigned int bus_width = 8 << (bytes[8] & 0x7);
  ' unsigned int ranks = 1 + ((bytes[7] >> 3) & 0x7);

My code:

Codice: [Seleziona]
  Print Lsl(CInt(bb[4] & &HF), 256)
 
  Print Lsl(bb[7], 3) & &h7
  Print Lsl(bb[8], 7) & &h7
  Print 1 + (Lsr(bb[7], 2) & &h7)

I would like an explanation or code that I could understand.

Offline vuott

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 11.724
  • Ne mors quidem nos iunget
    • Mostra profilo
Re:Operator << >> In gambas
« Risposta #1 il: 29 Novembre 2019, 21:13:38 »
This little part:

 
Codice: [Seleziona]
(bytes[4] & 0xF)

in Gambas is:

 
Codice: [Seleziona]
(bytes[4] And &F)

...&F or &hF, if you prefer.
« Ultima modifica: 29 Novembre 2019, 21:16:19 da vuott »
« Chiunque, non ricorrendo lo stato di necessità, nel proprio progetto Gambas fa uso delle istruzioni Shell o Exec, è punito con la sanzione pecuniaria da euro 20,00 a euro 60,00. »

Offline eloaders

  • Gamberetto
  • *
  • Post: 38
    • Mostra profilo
Re:Operator << >> In gambas
« Risposta #2 il: 29 Novembre 2019, 22:31:53 »
Yes, I understand. However, I mean using operator << or >> did I use it correctly?

Please, remove a duplicate of this topic :)

ps: I have a problem navigating the forum. I don't know where to change language to English

Offline vuott

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 11.724
  • Ne mors quidem nos iunget
    • Mostra profilo
Re:Operator << >> In gambas
« Risposta #3 il: 29 Novembre 2019, 23:58:17 »
where to change language to English

Did you use "Google translate" ?  Or "http://www.reverso.net" ?
« Chiunque, non ricorrendo lo stato di necessità, nel proprio progetto Gambas fa uso delle istruzioni Shell o Exec, è punito con la sanzione pecuniaria da euro 20,00 a euro 60,00. »

Offline vuott

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 11.724
  • Ne mors quidem nos iunget
    • Mostra profilo
Re:Operator << >> In gambas
« Risposta #4 il: 30 Novembre 2019, 00:08:22 »
However, I mean using operator << or >> did I use it correctly?

In C language:
Codice: [Seleziona]
integer_variable << number_of_positions
It means that the bits of integer variable are all moved to the left equivalent to number_of_positions.

So, from your example:  256 << (bytes[4] & 0xF)
in Gambas:

Codice: [Seleziona]
Lsl(256, (bytes[4] And &F))
« Ultima modifica: 30 Novembre 2019, 00:18:54 da vuott »
« Chiunque, non ricorrendo lo stato di necessità, nel proprio progetto Gambas fa uso delle istruzioni Shell o Exec, è punito con la sanzione pecuniaria da euro 20,00 a euro 60,00. »

Offline eloaders

  • Gamberetto
  • *
  • Post: 38
    • Mostra profilo
Re:Operator << >> In gambas
« Risposta #5 il: 30 Novembre 2019, 10:48:55 »
Thank you so much for your help. Here is the code I'm writing.
It is used to read and inform about ram memories using EEPROM

Codice: [Seleziona]
' Gambas module file

Export

Private Enum UNKNOWN = 0,
  DIRECT_RAMBUS = 1,
  RAMBUS = 2,
  FPM_DRAM = 3,
  EDO = 4,
  PIPELINED_NIBBLE = 5,
  SDR_SDRAM = 6,
  MULTIPLEXED_ROM = 7,
  DDR_SGRAM = 8,
  DDR_SDRAM = 9,
  DDR2_SDRAM = 10,
  DDR3_SDRAM = 11,
  DDR4_SDRAM = 12,
  N_RAM_TYPES = 13

Private RAM_TYPE As Integer = UNKNOWN
Private ram_types As String[] = ["Unknown", "Direct Rambus",
                                 "Rambus", "FPM DRAM", "EDO",
                                 "Pipelined Nibble", "SDR SDRAM",
                                 "Multiplexed ROM", "DDR SGRAM",
                                 "DDR SDRAM", "DDR2 SDRAM",
                                 "DDR3 SDRAM", "DDR4 SDRAM"]

Public Struct SPD_DATA
  bytes[512] As Byte
  dev[32] As String
  spd_driver As Integer '/* 0 = eeprom, 1 = ee1004 */
  spd_size As Integer
  ram_type As String
  vendor_bank As Integer
  vendor_index As Integer
  vendor_str As String
  partno As String
  '     const Vendor *vendor;
  '     int dram_vendor_bank;
  '     int dram_vendor_index;
  '     const char *dram_vendor_str;
  '     const Vendor *dram_vendor;
  '     char partno[32];
  form_factor As String
  type_detail As String
  dmi_mem_size As Long
  '     int spd_rev_major; // bytes[1] >> 4
  '     int spd_rev_minor; // bytes[1] & 0xf
  '     int week, year;
  manufacturer_date As String
  '     gboolean ddr4_no_ee1004;
  '     struct dmi_mem_socket *dmi_socket;
  '     int match_score
End Struct

Public MEMORY_SUPPORTED_VOLTAGE As String
Public MEMORY_SUPPORTED_CAS_LATENCIES As String
Public MEMORY_THERMAL_SENSOR As String

Public Sub main()

  Dim fl As File
  Dim bb As New Byte[512]
  Dim AA As New Byte[512]
  Dim s As String
  Dim i As Integer
  Dim bytes_used, bytes_free As Integer = 0
  Dim spd_data As New SPD_DATA
  Dim spd_size As Integer
 
  'fl = Open "/home/michal/Dokumenty/SPD/DDR RAM SPD HEX and BIN/DDR4/Ballistix Elite 4× 8 GB DDR-4000 (Micron E).SPD" For Read
  'fl = Open "/home/michal/Dokumenty/SPD/DDR RAM SPD HEX and BIN/DDR3/KINGSTON-KVR16LS11S6-2-001-A00LF-800MHz.SPD" For Read
  '/sys/bus/i2c/drivers/eeprom/" & Finfosys.ComboBox10.Text & "/eeprom
  fl = Open "/sys/bus/i2c/drivers/eeprom/0-0052/eeprom" For Read
  bb.Read(fl, 0, Lof(fl))
  'AA.Read(fl, 128, 140)
  fl.Close
 
  'spd_size = read_spd("/home/michal/Dokumenty/SPD/DDR RAM SPD HEX and BIN/DDR4/Ballistix Elite 4× 8 GB DDR-4000 (Micron E).SPD")
  'spd_size = read_spd("/home/michal/Dokumenty/SPD/DDR RAM SPD HEX and BIN/DDR3/KINGSTON-KVR16LS11S6-2-001-A00LF-800MHz.SPD")
  spd_size = read_spd("/sys/bus/i2c/drivers/eeprom/0-0052/eeprom")
  RAM_TYPE = decode_ram_type(bb)

  Select RAM_TYPE
    Case SDR_SDRAM
     
    Case DDR_SDRAM
     
    Case DDR2_SDRAM
     
    Case DDR3_SDRAM
      With spd_data
        .ram_type = ram_types[RAM_TYPE]
        .partno = decode_ddr3_part_number(bb)
        '.vendor_str = decode_ddr3_manufacturer(bb, SPD_DATA.vendor_str)
        .form_factor = decode_ddr3_module_type(bb)
        .type_detail = decode_ddr3_module_speed(bb)
        .manufacturer_date = decode_ddr3_module_date(bb)
        .dmi_mem_size = decode_ddr3_module_size(bb)
        MEMORY_SUPPORTED_VOLTAGE &= If(bb[6] = 4, "1.25V ", "") & If(bb[6] = 2, "1.35V ", "") & If(bb[6] = 1, "", "1.5V")
       
        'MEMORY_THERMAL_SENSOR = If(bytes[32] = )
        MEMORY_SUPPORTED_CAS_LATENCIES &= If(Mid$(Bin(bb[15], 8), 1, 1) = 1, "18T ", "")
        MEMORY_SUPPORTED_CAS_LATENCIES &= If(Mid$(Bin(bb[15], 8), 2, 1) = 1, "17T ", "")
        MEMORY_SUPPORTED_CAS_LATENCIES &= If(Mid$(Bin(bb[15], 8), 3, 1) = 1, "16T ", "")
        MEMORY_SUPPORTED_CAS_LATENCIES &= If(Mid$(Bin(bb[15], 8), 4, 1) = 1, "15T ", "")
        MEMORY_SUPPORTED_CAS_LATENCIES &= If(Mid$(Bin(bb[15], 8), 5, 1) = 1, "14T ", "")
        MEMORY_SUPPORTED_CAS_LATENCIES &= If(Mid$(Bin(bb[15], 8), 6, 1) = 1, "13T ", "")
        MEMORY_SUPPORTED_CAS_LATENCIES &= If(Mid$(Bin(bb[15], 8), 7, 1) = 1, "12T ", "")

        MEMORY_SUPPORTED_CAS_LATENCIES &= If(Mid$(Bin(bb[14], 8), 1, 1) = 1, "11T ", "")
        MEMORY_SUPPORTED_CAS_LATENCIES &= If(Mid$(Bin(bb[14], 8), 2, 1) = 1, "10T ", "")
        MEMORY_SUPPORTED_CAS_LATENCIES &= If(Mid$(Bin(bb[14], 8), 3, 1) = 1, "9T ", "")
        MEMORY_SUPPORTED_CAS_LATENCIES &= If(Mid$(Bin(bb[14], 8), 4, 1) = 1, "8T ", "")
        MEMORY_SUPPORTED_CAS_LATENCIES &= If(Mid$(Bin(bb[14], 8), 5, 1) = 1, "7T ", "")
        MEMORY_SUPPORTED_CAS_LATENCIES &= If(Mid$(Bin(bb[14], 8), 6, 1) = 1, "6T ", "")
        MEMORY_SUPPORTED_CAS_LATENCIES &= If(Mid$(Bin(bb[14], 8), 7, 1) = 1, "5T ", "")
        MEMORY_SUPPORTED_CAS_LATENCIES &= If(Mid$(Bin(bb[14], 8), 8, 1) = 1, "4T ", "")

      End With
    Case DDR4_SDRAM
      With spd_data
        .ram_type = ram_types[RAM_TYPE]
        .form_factor = decode_ddr4_module_type(bb)
        .type_detail = decode_ddr4_module_speed(bb)
        .partno = decode_ddr4_part_number(bb)
      End With
  End Select

  Print spd_data.ram_type
  Print spd_data.partno
  Print spd_data.form_factor
  Print spd_data.type_detail
  Print spd_data.manufacturer_date
  Print MEMORY_SUPPORTED_VOLTAGE
  Print MEMORY_SUPPORTED_CAS_LATENCIES
  Print spd_size
  Print SPD_DATA.dmi_mem_size

  For i = 0 To bb.Count - 1
    '
    If bb[i] Then
      bytes_used += 1
     
      'Print "RAW:" & bb[i] & "|HEX: " & Hex(bb[i]) & " |Bin: " & Bin(bb[i], 8) & " |Int: " & CInt(bb[i])
    Else
      bytes_free += 1
      'Print "RAW:" & bb[i] & "|HEX: " & Hex(bb[i]) & " |Bin: " & Bin(bb[i], 8) & " |Int: " & CInt(bb[i])
    Endif
  Next
  'Print Subst("Bytes Used: &1 Bytes Free: &2 Bytes Total: &3", bytes_used, bytes_free, bytes_free + bytes_used)
  'Print CInt(bb[32] & &H80&)
  'Print bb[121] & &hF0&
  's = Hex(bb[0], 2) & Hex(bb[1], 2) & Hex(bb[2], 2)
  'Print "RAW:" & bb[6] & "|HEX: " & Hex(bb[6]) & " |Bin: " & Bin(bb[6], 8) & " |Int: " & CInt(bb[6])
  'Print "RAW:" & bb[15] & "|HEX: " & Hex(bb[15]) & " |Bin: " & Bin(bb[15], 8) & " |Int: " & CInt(bb[15])
  'Print "RAW:" & bb[31] & "|HEX: " & Hex(bb[32]) & " |Bin: " & Bin(bb[32], 8) & " |Int: " & CInt(bb[32])
  'Print Hex$(15, 3)
  'Print "HEX: " & Hex(bb[2], 2) & " |Bin: " & Bin(bb[2], 8) & " |Int: " & CInt(bb[2])
  'Print "HEX: " & Hex(bb[3], 2) & " |Bin: " & Bin(bb[3], 8) & " |Int: " & CInt(bb[3])
  'Print "HEX: " & Hex(bb[4], 2) & " |Bin: " & Bin(bb[4], 8) & " |Int: " & CInt(bb[4])
  'Print "HEX: " & Hex(bb[5], 2) & " |Bin: " & Bin(bb[5], 8) & " |Int: " & CInt(bb[5])
  'Print "HEX: " & Hex(bb[6], 2) & " |Bin: " & Bin(bb[6], 8) & " |Int: " & CInt(bb[6])
  'Print Hex(bb[128], 2)
  'Print bb.ToString(128, 20)
  'Print Chr(bb[128]) & Chr(bb[129]) & Chr(bb[130]) & Chr(bb[131]) & Chr(bb[132]) & Chr(bb[133]) & Chr(bb[134]) & Chr(bb[135]) & Chr(bb[136]) & Chr(bb[137]) & Chr(bb[138]) & Chr(bb[139]) & Chr(bb[140])
  'i = Val("&" & s)
   
  'Print i
  'Print s
 
End

Private Function decode_ram_type(bytes As Byte[]) As Integer
  If bytes[0] < 4 Then
    Select bytes[2]
      Case 1
        Return DIRECT_RAMBUS
      Case 17
        Return RAMBUS
    End Select
  Else
    Select bytes[2]
      Case 1
        Return FPM_DRAM
      Case 2
        Return EDO
      Case 3
        Return PIPELINED_NIBBLE
      Case 4
        Return SDR_SDRAM
      Case 5
        Return MULTIPLEXED_ROM
      Case 6
        Return DDR_SGRAM
      Case 7
        Return DDR_SDRAM
      Case 8
        Return DDR2_SDRAM
      Case 11
        Return DDR3_SDRAM
      Case 12
        Return DDR4_SDRAM
    End Select
    Return UNKNOWN
  Endif
End

Private Function decode_ddr3_part_number(bytes As Byte[], Optional partnumber As String) As String
  Dim i As Integer
  For i = 128 To 145
    partnumber &= Chr(bytes[i])
  Next
  Return partnumber
End

Private Function decode_ddr4_part_number(bytes As Byte[], Optional partnumber As String) As String
  Dim i As Integer
  For i = 329 To 348
    partnumber &= Chr(bytes[i])
  Next
  Return partnumber
End

Private Function read_spd(spd_path As String) As Integer
  Dim data_size As Integer = 0
  data_size = Stat(spd_path).Size
  Return data_size
End

Private Function decode_ddr3_module_type(bytes As Byte[]) As String
  Dim type As String
  Select bytes[3]
    Case 01
      type = "RDIMM (Registered Long DIMM)"
    Case 02
      type = "UDIMM (Unbuffered Long DIMM)"
    Case 03
      type = "SODIMM (Small Outline DIMM)"
    Default
      type = Null
  End Select
  Return type
End

Private Function decode_ddr4_module_type(bytes As Byte[]) As String
  Dim type As String = "Unknown" ''Default Unknown if no detect
  Select Hex(bytes[3], 2)
    Case &h01
      type = "RDIMM (Registered DIMM)"
    Case "02"
      type = "UDIMM (Unbuffered DIMM)"
    Case "03"
      type = "SODIMM (Small Outline Unbuffered DIMM)"
    Case "04"
      type = "LRDIMM (Load-Reduced DIMM)"
    Case "05"
      type = "Mini-RDIMM (Mini Registered DIMM)"
    Case "06"
      type = "Mini-UDIMM (Mini Unbuffered DIMM)"
    Case "08"
      type = "72b-SO-RDIMM (Small Outline Registered DIMM, 72-bit data bus)"
    Case "09"
      type = "72b-SO-UDIMM (Small Outline Unbuffered DIMM, 72-bit data bus)"
    Case "0c"
      type = "16b-SO-UDIMM (Small Outline Unbuffered DIMM, 16-bit data bus)"
    Case "0d"
      type = "32b-SO-UDIMM (Small Outline Unbuffered DIMM, 32-bit data bus)"
  End Select
  Return type
End

Private Function decode_ddr3_module_speed(bytes As Byte[]) As String
  ' Dim ctime As Float
  ' Dim ddrclk As Float
  ' Dim tbits, pcclk As Integer
  ' Dim mtb As Float = 0.125
  '
  ' If (bytes[10] == 1 And bytes[11] == 8) Then mtb = 0.125
  ' If (bytes[10] == 1 And bytes[11] == 15) Then mtb = 0.0625
  ' ctime = mtb * bytes[12]
  ' ddrclk = 2 * (1000 / ctime)
  '
  ' tbits = 64
  ' Select bytes[8]
  '   Case 1
  '     tbits = 16
  '   Case 4
  '     tbits = 32
  '   Case 3
  '   Case 0
  '     tbits = 64
  ' End Select
  '
  ' pcclk = ddrclk * (tbits / 8)
  ' pcclk -= pcclk % 100
  '
  ' Return Subst("DDR3-&1Mhz PC3-&2", CInt(ddrclk), pcclk)
  Dim divisor As Integer = bytes[10]
  Dim dividend As Integer = bytes[11]
  Dim ratio As Integer = bytes[12]
  If dividend = 0 And divisor = 0 And ratio = 0 Then
    Return "DDR3-Unknown Mhz"
  Else
    Return Subst("DDR3-&1Mhz", ((2000 * dividend) / (divisor * ratio)))
  Endif
End

Private Function decode_ddr4_module_speed(bytes As Byte[]) As String
  Dim mincycle As Integer = bytes[18]
  Dim fineadjust As Integer = Bytes[125]
  Dim frequency As Integer
  frequency = (2000000 / (mincycle * 125 + fineadjust))
  Return Subst("DDR4-&1Mhz", frequency)
End

Private Function decode_ddr3_module_size(bytes As Byte[]) As Long
  Dim sdr_capacity As Integer = Lsl(256, (bytes[4] And &F))
  Dim sdr_width As Integer = Lsl(4, (bytes[7] And &7))
  Dim bus_width As Integer = Lsl(8, (bytes[8] And &7))
  Dim ranks As Integer = 1 + Lsr(3, (bytes[7] And &7))

  Return sdr_capacity / 8 * bus_width / sdr_width * ranks
End

' static void decode_ddr4_module_size(unsigned char *bytes, dmi_mem_size *size) {
'     int sdrcap = 256 << (bytes[4] & 15);
'     int buswidth = 8 << (bytes[13] & 7);
'     int sdrwidth = 4 << (bytes[12] & 7);
'     int signal_loading = bytes[6] & 3;
'     int lranks_per_dimm = ((bytes[12] >> 3) & 7) + 1;
'
'     if (signal_loading == 2) lranks_per_dimm *= ((bytes[6] >> 4) & 7) + 1;
'
'     *size = sdrcap / 8 * buswidth / sdrwidth * lranks_per_dimm;
' }

Private Function decode_ddr3_module_date(bytes As Byte[]) As String
  Return Subst("&1-W&2", CInt(2000 + bytes[120]), bytes[121])
End

' static void decode_ddr3_module_date(unsigned char *bytes, int *week, int *year) {
'     if (bytes[120] == 0x0 || bytes[120] == 0xff ||
'         bytes[121] == 0x0 || bytes[121] == 0xff) {
'         return;
'     }
'     *week = (bytes[121]>>4) & 0xf;
'     *week *= 10;
'     *week += bytes[121] & 0xf;
'     *year = (bytes[120]>>4) & 0xf;
'     *year *= 10;
'     *year += bytes[120] & 0xf;
'     *year += 2000;
' }


Offline vuott

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 11.724
  • Ne mors quidem nos iunget
    • Mostra profilo
Re:Operator << >> In gambas
« Risposta #6 il: 30 Novembre 2019, 14:24:54 »
Make sure that the size of the "spd_data" structure is exactly the same as the "SPD_DATA" structure, written by you in Gambas !
« Chiunque, non ricorrendo lo stato di necessità, nel proprio progetto Gambas fa uso delle istruzioni Shell o Exec, è punito con la sanzione pecuniaria da euro 20,00 a euro 60,00. »

Offline Top Fuel

  • Gran Maestro dei Gamberi
  • *****
  • Post: 959
    • Mostra profilo
Re:Operator << >> In gambas
« Risposta #7 il: 30 Novembre 2019, 15:01:11 »
Not to be confused with the Asl/Shl and Asr/Shr instructions that keep the sign bit.
« Ultima modifica: 30 Novembre 2019, 15:01:42 da Top Fuel »
Dear youtube administrators, your search bar is broken. When I type the letter "J" it appears justin bieber when it should appear Jimi Hendrix. Fix this, please.

Offline vuott

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 11.724
  • Ne mors quidem nos iunget
    • Mostra profilo
« Chiunque, non ricorrendo lo stato di necessità, nel proprio progetto Gambas fa uso delle istruzioni Shell o Exec, è punito con la sanzione pecuniaria da euro 20,00 a euro 60,00. »

Offline eloaders

  • Gamberetto
  • *
  • Post: 38
    • Mostra profilo
Re:Operator << >> In gambas
« Risposta #9 il: 01 Dicembre 2019, 09:19:22 »
Thanks for the answers. Maybe I can do it now.

Code update:
Codice: [Seleziona]
' Gambas module file

Export

Private Enum UNKNOWN = 0,
  DIRECT_RAMBUS = 1,
  RAMBUS = 2,
  FPM_DRAM = 3,
  EDO = 4,
  PIPELINED_NIBBLE = 5,
  SDR_SDRAM = 6,
  MULTIPLEXED_ROM = 7,
  DDR_SGRAM = 8,
  DDR_SDRAM = 9,
  DDR2_SDRAM = 10,
  DDR3_SDRAM = 11,
  DDR4_SDRAM = 12,
  N_RAM_TYPES = 13

Private RAM_TYPE As Integer = UNKNOWN
Private ram_types As String[] = ["Unknown", "Direct Rambus",
                                 "Rambus", "FPM DRAM", "EDO",
                                 "Pipelined Nibble", "SDR SDRAM",
                                 "Multiplexed ROM", "DDR SGRAM",
                                 "DDR SDRAM", "DDR2 SDRAM",
                                 "DDR3 SDRAM", "DDR4 SDRAM"]

Public Struct SPD_DATA
  bytes[512] As Byte
  dev[32] As String
  spd_driver As Integer '/* 0 = eeprom, 1 = ee1004 */
  spd_size As Integer
  ram_type As String
  vendor_bank As Integer
  vendor_index As Integer
  vendor_str As String
  partno As String
  '     const Vendor *vendor;
  '     int dram_vendor_bank;
  '     int dram_vendor_index;
  '     const char *dram_vendor_str;
  '     const Vendor *dram_vendor;
  '     char partno[32];
  form_factor As String
  type_detail As String
  dmi_mem_size As String
  spd_rev As String '//bytes[1] >> 4
  '     int spd_rev_minor; // bytes[1] & 0xf
  '     int week, year;
  manufacturer_date As String
  '     gboolean ddr4_no_ee1004;
  '     struct dmi_mem_socket *dmi_socket;
  '     int match_score
End Struct

Public MEMORY_SUPPORTED_VOLTAGE As String
Public MEMORY_SUPPORTED_CAS_LATENCIES As String
Public MEMORY_THERMAL_SENSOR As String

Public Sub main()

  Dim fl As File
  Dim bb As New Byte[512]
  Dim AA As New Byte[512]
  Dim s As String
  Dim i As Integer
  Dim bytes_used, bytes_free As Integer = 0
  Dim spd_data As New SPD_DATA
  Dim spd_size As Integer
 
  fl = Open "/home/michal/Dokumenty/SPD/DDR RAM SPD HEX and BIN/DDR4/Ballistix Elite 4× 8 GB DDR-4000 (Micron E).SPD" For Read
  'fl = Open "/home/michal/Dokumenty/SPD/DDR RAM SPD HEX and BIN/DDR3/KINGSTON-KVR16LS11S6-2-001-A00LF-800MHz.SPD" For Read
  '/sys/bus/i2c/drivers/eeprom/" & Finfosys.ComboBox10.Text & "/eeprom
  'fl = Open "/sys/bus/i2c/drivers/eeprom/0-0052/eeprom" For Read
  bb.Read(fl, 0, Lof(fl))
  'AA.Read(fl, 128, 140)
  fl.Close
 
  spd_size = read_spd("/home/michal/Dokumenty/SPD/DDR RAM SPD HEX and BIN/DDR4/Ballistix Elite 4× 8 GB DDR-4000 (Micron E).SPD")
  'spd_size = read_spd("/home/michal/Dokumenty/SPD/DDR RAM SPD HEX and BIN/DDR3/KINGSTON-KVR16LS11S6-2-001-A00LF-800MHz.SPD")
  'spd_size = read_spd("/sys/bus/i2c/drivers/eeprom/0-0052/eeprom")
  RAM_TYPE = decode_ram_type(bb)

  Select RAM_TYPE
    Case SDR_SDRAM
     
    Case DDR_SDRAM
     
    Case DDR2_SDRAM
     
    Case DDR3_SDRAM
      With spd_data
        .ram_type = ram_types[RAM_TYPE]
        .partno = decode_ddr3_part_number(bb)
        '.vendor_str = decode_ddr3_manufacturer(bb, SPD_DATA.vendor_str)
        .form_factor = decode_ddr3_module_type(bb)
        .type_detail = decode_ddr3_module_speed(bb)
        .manufacturer_date = decode_ddr3_module_date(bb)
        .dmi_mem_size = decode_ddr3_module_size(bb)
        .spd_rev = decode_ddr3_spd_revision(bb)
        MEMORY_SUPPORTED_VOLTAGE &= If(bb[6] = 4, "1.25V ", "") & If(bb[6] = 2, "1.35V ", "") & If(bb[6] = 1, "", "1.5V")
       
        'MEMORY_THERMAL_SENSOR = If(bytes[32] = )
        MEMORY_SUPPORTED_CAS_LATENCIES &= If(Mid$(Bin(bb[15], 8), 1, 1) = 1, "18T ", "")
        MEMORY_SUPPORTED_CAS_LATENCIES &= If(Mid$(Bin(bb[15], 8), 2, 1) = 1, "17T ", "")
        MEMORY_SUPPORTED_CAS_LATENCIES &= If(Mid$(Bin(bb[15], 8), 3, 1) = 1, "16T ", "")
        MEMORY_SUPPORTED_CAS_LATENCIES &= If(Mid$(Bin(bb[15], 8), 4, 1) = 1, "15T ", "")
        MEMORY_SUPPORTED_CAS_LATENCIES &= If(Mid$(Bin(bb[15], 8), 5, 1) = 1, "14T ", "")
        MEMORY_SUPPORTED_CAS_LATENCIES &= If(Mid$(Bin(bb[15], 8), 6, 1) = 1, "13T ", "")
        MEMORY_SUPPORTED_CAS_LATENCIES &= If(Mid$(Bin(bb[15], 8), 7, 1) = 1, "12T ", "")

        MEMORY_SUPPORTED_CAS_LATENCIES &= If(Mid$(Bin(bb[14], 8), 1, 1) = 1, "11T ", "")
        MEMORY_SUPPORTED_CAS_LATENCIES &= If(Mid$(Bin(bb[14], 8), 2, 1) = 1, "10T ", "")
        MEMORY_SUPPORTED_CAS_LATENCIES &= If(Mid$(Bin(bb[14], 8), 3, 1) = 1, "9T ", "")
        MEMORY_SUPPORTED_CAS_LATENCIES &= If(Mid$(Bin(bb[14], 8), 4, 1) = 1, "8T ", "")
        MEMORY_SUPPORTED_CAS_LATENCIES &= If(Mid$(Bin(bb[14], 8), 5, 1) = 1, "7T ", "")
        MEMORY_SUPPORTED_CAS_LATENCIES &= If(Mid$(Bin(bb[14], 8), 6, 1) = 1, "6T ", "")
        MEMORY_SUPPORTED_CAS_LATENCIES &= If(Mid$(Bin(bb[14], 8), 7, 1) = 1, "5T ", "")
        MEMORY_SUPPORTED_CAS_LATENCIES &= If(Mid$(Bin(bb[14], 8), 8, 1) = 1, "4T ", "")

      End With
    Case DDR4_SDRAM
      With spd_data
        .ram_type = ram_types[RAM_TYPE]
        .form_factor = decode_ddr4_module_type(bb)
        .type_detail = decode_ddr4_module_speed(bb)
        .partno = decode_ddr4_part_number(bb)
        .dmi_mem_size = decode_ddr4_module_size(bb)
      End With
  End Select

  Print spd_data.ram_type
  Print spd_data.partno
  Print spd_data.form_factor
  Print spd_data.type_detail
  Print spd_data.manufacturer_date
  Print SPD_DATA.spd_rev
  Print MEMORY_SUPPORTED_VOLTAGE
  Print MEMORY_SUPPORTED_CAS_LATENCIES
  Print spd_size
  Print SPD_DATA.dmi_mem_size
  For i = 0 To bb.Count - 1
    '
    If bb[i] Then
      bytes_used += 1
     
      'Print "RAW:" & bb[i] & "|HEX: " & Hex(bb[i]) & " |Bin: " & Bin(bb[i], 8) & " |Int: " & CInt(bb[i])
    Else
      bytes_free += 1
      'Print "RAW:" & bb[i] & "|HEX: " & Hex(bb[i]) & " |Bin: " & Bin(bb[i], 8) & " |Int: " & CInt(bb[i])
    Endif
  Next
  'Print Subst("Bytes Used: &1 Bytes Free: &2 Bytes Total: &3", bytes_used, bytes_free, bytes_free + bytes_used)
  'Print CInt(bb[32] & &H80&)
  'Print bb[121] & &hF0&
  's = Hex(bb[0], 2) & Hex(bb[1], 2) & Hex(bb[2], 2)
  'Print "RAW:" & bb[6] & "|HEX: " & Hex(bb[6]) & " |Bin: " & Bin(bb[6], 8) & " |Int: " & CInt(bb[6])
  'Print "RAW:" & bb[15] & "|HEX: " & Hex(bb[15]) & " |Bin: " & Bin(bb[15], 8) & " |Int: " & CInt(bb[15])
  'Print "RAW:" & bb[31] & "|HEX: " & Hex(bb[32]) & " |Bin: " & Bin(bb[32], 8) & " |Int: " & CInt(bb[32])
  'Print Hex$(15, 3)
  'Print "HEX: " & Hex(bb[2], 2) & " |Bin: " & Bin(bb[2], 8) & " |Int: " & CInt(bb[2])
  'Print "HEX: " & Hex(bb[3], 2) & " |Bin: " & Bin(bb[3], 8) & " |Int: " & CInt(bb[3])
  'Print "HEX: " & Hex(bb[4], 2) & " |Bin: " & Bin(bb[4], 8) & " |Int: " & CInt(bb[4])
  'Print "HEX: " & Hex(bb[5], 2) & " |Bin: " & Bin(bb[5], 8) & " |Int: " & CInt(bb[5])
  'Print "HEX: " & Hex(bb[6], 2) & " |Bin: " & Bin(bb[6], 8) & " |Int: " & CInt(bb[6])
  'Print Hex(bb[128], 2)
  'Print bb.ToString(128, 20)
  'Print Chr(bb[128]) & Chr(bb[129]) & Chr(bb[130]) & Chr(bb[131]) & Chr(bb[132]) & Chr(bb[133]) & Chr(bb[134]) & Chr(bb[135]) & Chr(bb[136]) & Chr(bb[137]) & Chr(bb[138]) & Chr(bb[139]) & Chr(bb[140])
  'i = Val("&" & s)
   
  'Print i
  'Print s
 
End

Private Function decode_ddr3_spd_revision(bytes As Byte[]) As String
  Return Mid(Hex(bytes[1]), 1, 1) & "." & Mid(Hex(bytes[1]), 2, 1)
End

' Version   0.0              00h
' Revision 0.5              05h
' Revision 1.0              10h
' Revision 1.1              11h
' Revision 1.2              12h

Private Function decode_ram_type(bytes As Byte[]) As Integer
  If bytes[0] < 4 Then
    Select bytes[2]
      Case 1
        Return DIRECT_RAMBUS
      Case 17
        Return RAMBUS
    End Select
  Else
    Select bytes[2]
      Case 1
        Return FPM_DRAM
      Case 2
        Return EDO
      Case 3
        Return PIPELINED_NIBBLE
      Case 4
        Return SDR_SDRAM
      Case 5
        Return MULTIPLEXED_ROM
      Case 6
        Return DDR_SGRAM
      Case 7
        Return DDR_SDRAM
      Case 8
        Return DDR2_SDRAM
      Case 11
        Return DDR3_SDRAM
      Case 12
        Return DDR4_SDRAM
    End Select
    Return UNKNOWN
  Endif
End

Private Function decode_ddr3_part_number(bytes As Byte[], Optional partnumber As String) As String
  Dim i As Integer
  For i = 128 To 145
    partnumber &= Chr(bytes[i])
  Next
  Return partnumber
End

Private Function decode_ddr4_part_number(bytes As Byte[], Optional partnumber As String) As String
  Dim i As Integer
  For i = 329 To 348
    partnumber &= Chr(bytes[i])
  Next
  Return partnumber
End

Private Function read_spd(spd_path As String) As Integer
  Dim data_size As Integer = 0
  data_size = Stat(spd_path).Size
  Return data_size
End

Private Function decode_ddr3_module_type(bytes As Byte[]) As String
  Dim type As String
  Select bytes[3]
    Case 01
      type = "RDIMM (Registered Long DIMM)"
    Case 02
      type = "UDIMM (Unbuffered Long DIMM)"
    Case 03
      type = "SODIMM (Small Outline DIMM)"
    Default
      type = Null
  End Select
  Return type
End

Private Function decode_ddr4_module_type(bytes As Byte[]) As String
  Dim type As String = "Unknown" ''Default Unknown if no detect
  Select Hex(bytes[3], 2)
    Case &h01
      type = "RDIMM (Registered DIMM)"
    Case "02"
      type = "UDIMM (Unbuffered DIMM)"
    Case "03"
      type = "SODIMM (Small Outline Unbuffered DIMM)"
    Case "04"
      type = "LRDIMM (Load-Reduced DIMM)"
    Case "05"
      type = "Mini-RDIMM (Mini Registered DIMM)"
    Case "06"
      type = "Mini-UDIMM (Mini Unbuffered DIMM)"
    Case "08"
      type = "72b-SO-RDIMM (Small Outline Registered DIMM, 72-bit data bus)"
    Case "09"
      type = "72b-SO-UDIMM (Small Outline Unbuffered DIMM, 72-bit data bus)"
    Case "0c"
      type = "16b-SO-UDIMM (Small Outline Unbuffered DIMM, 16-bit data bus)"
    Case "0d"
      type = "32b-SO-UDIMM (Small Outline Unbuffered DIMM, 32-bit data bus)"
  End Select
  Return type
End

Private Function decode_ddr3_module_speed(bytes As Byte[]) As String
  ' Dim ctime As Float
  ' Dim ddrclk As Float
  ' Dim tbits, pcclk As Integer
  ' Dim mtb As Float = 0.125
  '
  ' If (bytes[10] == 1 And bytes[11] == 8) Then mtb = 0.125
  ' If (bytes[10] == 1 And bytes[11] == 15) Then mtb = 0.0625
  ' ctime = mtb * bytes[12]
  ' ddrclk = 2 * (1000 / ctime)
  '
  ' tbits = 64
  ' Select bytes[8]
  '   Case 1
  '     tbits = 16
  '   Case 4
  '     tbits = 32
  '   Case 3
  '   Case 0
  '     tbits = 64
  ' End Select
  '
  ' pcclk = ddrclk * (tbits / 8)
  ' pcclk -= pcclk % 100
  '
  ' Return Subst("DDR3-&1Mhz PC3-&2", CInt(ddrclk), pcclk)
  Dim divisor As Integer = bytes[10]
  Dim dividend As Integer = bytes[11]
  Dim ratio As Integer = bytes[12]
  If dividend = 0 And divisor = 0 And ratio = 0 Then
    Return "DDR3-Unknown Mhz"
  Else
    Return Subst("DDR3-&1Mhz", ((2000 * dividend) / (divisor * ratio)))
  Endif
End

Private Function decode_ddr4_module_speed(bytes As Byte[]) As String
  Dim mincycle As Integer = bytes[18]
  Dim fineadjust As Integer = Bytes[125]
  Dim frequency As Integer
  frequency = (2000000 / (mincycle * 125 + fineadjust))
  Return Subst("DDR4-&1Mhz", frequency)
End

Private Function decode_ddr3_module_size(bytes As Byte[]) As String
  Dim size As Integer
  ' Dim sdr_capacity As Integer = Lsl(256, Hex(bytes[4]) And &hF)
  ' Dim sdr_width As Integer = Lsl(4, Hex(bytes[7]) And &h7)
  ' Dim bus_width As Integer = Lsl(8, Hex(bytes[8]) And &h7)
  ' Dim ranks As Integer = 1 + Lsr(3, Hex(bytes[7]) And &h7)
 
  ' Print "sdr_capacity = " & Lsl(256, Bytes[4])
  ' Print "sdr_width = " & Lsl(4, bytes[7])
  ' Print "bus_width = " & Lsl(8, bytes[8])
  ' Print "ranks = " & (Lsr(3, bytes[7]) + 1)
 
  ' size = sdr_capacity / 8 * bus_width / sdr_width * ranks

  size = ((Hex(bytes[4]) And &h0f) + 28) + ((Hex(bytes[8]) And &h7) + 3)
  size -= (Hex(bytes[7]) And &h7) + 25
  size = (Lsl(1, size)) * (Lsr(3, bytes[7] And &h1f) + 1)
  Return Subst("Module size: &1", size / 1024)
End

Private Function decode_ddr4_module_size(bytes As Byte[]) As String
  Dim size As Integer
  size = Lsl(1, Hex(bytes[4]) And &h0f) + 8
  size *= Lsl(1, Hex(bytes[13]) And &h07) + 3
  size /= Lsl(1, Hex(bytes[12]) And &h07) + 2
  size *= (Lsr(3, Hex(bytes[12]) And &h07) + 1)
  size *= (Hex(bytes[6]) And &h03)
  Return Subst("Module size: &1", size / 1024)
End
' static void decode_ddr4_module_size(unsigned char *bytes, dmi_mem_size *size) {
'     int sdrcap = 256 << (bytes[4] & 15);
'     int buswidth = 8 << (bytes[13] & 7);
'     int sdrwidth = 4 << (bytes[12] & 7);
'     int signal_loading = bytes[6] & 3;
'     int lranks_per_dimm = ((bytes[12] >> 3) & 7) + 1;
'
'     if (signal_loading == 2) lranks_per_dimm *= ((bytes[6] >> 4) & 7) + 1;
'
'     *size = sdrcap / 8 * buswidth / sdrwidth * lranks_per_dimm;
' }

'         gRAM.SPD[i].Type = MemoryTypeDdr4;
'
'         gRAM.SPD[i].ModuleSize
'         = (1 << ((spdbuf[4] & 0x0f) + 8 /* Mb */ - 3 /* MB */)) // SDRAM Capacity
'         * (1 << ((spdbuf[13] & 0x07) + 3)) // Primary Bus Width
'         / (1 << ((spdbuf[12] & 0x07) + 2)) // SDRAM Width
'         * (((spdbuf[12] >> 3) & 0x07) + 1) // Logical Ranks per DIMM
'         * (((spdbuf[6] & 0x03) == 2) ? (((spdbuf[6] >> 4) & 0x07) + 1) : 1);

Private Function decode_ddr3_module_date(bytes As Byte[]) As String
  ' Dim sweek As Long
  ' Dim syear As Long
  ' If bytes[120] = &h0 Or bytes[120] = &hff Or bytes[121] = &h0 Or bytes[121] = &ff Then
  '   Return
  ' Endif
  ' 'Lsr(3, (bytes[7] And &7))
  ' sweek = Lsr(4, Hex(bytes[121]) And &hf)
  ' sweek *= 10
  ' sweek += Hex(bytes[121]) And &hf
  ' syear = Lsr(4, Hex(bytes[120]) And &hf)
  ' syear *= 10
  ' syear += (Hex(bytes[120]) And &hf)
  ' syear += 2000
  ' Print Subst("Week: &1 Year: &2", sweek, syear)
  Return Subst("Year &1-W&2", CInt(2000 + Hex(bytes[120])), Hex(bytes[121]))
End

' static void decode_ddr3_module_date(unsigned char *bytes, int *week, int *year) {
'     if (bytes[120] == 0x0 || bytes[120] == 0xff ||
'         bytes[121] == 0x0 || bytes[121] == 0xff) {
'         return;
'     }
'     *week = (bytes[121]>>4) & 0xf;
'     *week *= 10;
'     *week += bytes[121] & 0xf;
'     *year = (bytes[120]>>4) & 0xf;
'     *year *= 10;
'     *year += bytes[120] & 0xf;
'     *year += 2000;
' }

Offline vuott

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 11.724
  • Ne mors quidem nos iunget
    • Mostra profilo
Re:Operator << >> In gambas
« Risposta #10 il: 01 Dicembre 2019, 14:59:57 »
Codice: [Seleziona]
Public Struct SPD_DATA
   ... As String
 

mmm... I would use a Pointer datatype. 
« Chiunque, non ricorrendo lo stato di necessità, nel proprio progetto Gambas fa uso delle istruzioni Shell o Exec, è punito con la sanzione pecuniaria da euro 20,00 a euro 60,00. »

Offline eloaders

  • Gamberetto
  • *
  • Post: 38
    • Mostra profilo
Re:Operator << >> In gambas
« Risposta #11 il: 07 Dicembre 2019, 16:00:02 »
Let me re-share the sources, already quite rebuilt.

Codice: [Seleziona]
' Gambas module file

Private spd_i2c_eeprom_dir As String[] = ["/sys/bus/i2c/drivers/eeprom/",
  "/sys/bus/i2c/drivers/ee1004/",
  "/sys/bus/i2c/drivers/at24/",
  "/home/michal/Dokumenty/SPD/"]
Private spd_i2c_eeprom_files As New String[]
Private eeprom_file_name As String = "eeprom"

Private Enum UNKNOWN = 0,
  DIRECT_RAMBUS = 1,
  RAMBUS = 2,
  FPM_DRAM = 3,
  EDO = 4,
  PIPELINED_NIBBLE = 5,
  SDR_SDRAM = 6,
  MULTIPLEXED_ROM = 7,
  DDR_SGRAM = 8,
  DDR_SDRAM = 9,
  DDR2_SDRAM = 10,
  DDR3_SDRAM = 11,
  DDR4_SDRAM = 12,
  N_RAM_TYPES = 13

Private ram_types As String[] = ["Unknown", "Direct Rambus",
  "Rambus", "FPM DRAM", "EDO",
  "Pipelined Nibble", "SDR SDRAM",
  "Multiplexed ROM", "DDR SGRAM",
  "DDR SDRAM", "DDR2 SDRAM",
  "DDR3 SDRAM", "DDR4 SDRAM"]

Public spd_size As New Long[]
Public ram_type_str As New String[]
Public ram_type_int As New Integer[]
Public spd_revision As New String[]
Public part_number As New String[]
Public module_type As New String[]
Public module_speed As New String[]
Public module_size As New String[]
Public voltage As New String[]
Public module_manufacturer As New String[]
Public module_dram_manufacturer As New String[]
Public module_manufacture_date As New String[]
Public eeprom As New Byte[512]

Private Function read_spd(file_path As String)

  Dim eeprom_file As File
  eeprom_file = Open file_path For Read
  eeprom.Read(eeprom_file, 0, Lof(eeprom_file))
  eeprom_file.Close

End

Private Function calculate_spd_size(file_path As String) As Long

  If Exist(file_path) Then
    Return Stat(file_path).Size
  Else
    Return Null
  Endif

End

Private Function find_spd_eeprom_file()

  Dim eeprom_file As File
  Dim eeprom_byte As New Byte[512]
  Dim i As Integer
 
  For i = 0 To spd_i2c_eeprom_dir.Max
    If Exist(spd_i2c_eeprom_dir[i]) Then
      For Each element As String In Dir(spd_i2c_eeprom_dir[i], "*-****")
        If Exist(spd_i2c_eeprom_dir[i] &/ element &/ eeprom_file_name) Then
          eeprom_file = Open (spd_i2c_eeprom_dir[i] &/ element &/ eeprom_file_name) For Read
          eeprom_byte.Read(eeprom_file, 0, Lof(eeprom_file))
          If eeprom_byte[0] > 0 Then
            spd_i2c_eeprom_files.Add(spd_i2c_eeprom_dir[i] &/ element &/ eeprom_file_name)
          Endif
          eeprom_file.Close
        Endif
      Next
    Endif
  Next

End

Public Sub Main()

  Dim i As Integer
  Dim eeprom_file As File
  Dim eeprom_byte As New Byte[]

  find_spd_eeprom_file()
 
  For Each Variable As String In spd_i2c_eeprom_files
    spd_size.Add(calculate_spd_size(Variable))
  Next
 
  For i = 0 To spd_i2c_eeprom_files.Max
    read_spd(spd_i2c_eeprom_files[i])
    ram_type_str.Add(ram_types[decode_ram_type(eeprom)])
    ram_type_int.Add(decode_ram_type(eeprom))
   
    Select ram_type_int[i]
      Case SDR_SDRAM
      Case DDR_SDRAM
      Case DDR2_SDRAM
      Case DDR3_SDRAM
        spd_revision.Add(decode_ddr3_spd_revision(eeprom))
        part_number.Add(decode_ddr3_part_number(eeprom))
        module_type.Add(decode_ddr3_module_type(eeprom))
        module_speed.Add(decode_ddr3_module_speed(eeprom))
        module_size.Add(decode_ddr3_module_size(eeprom))
        voltage.Add(decode_ddr3_voltage(eeprom))
        module_manufacturer.Add(decode_ddr3_module_manufacturer(eeprom))
        module_dram_manufacturer.Add(decode_ddr3_module_dram_manufacturer(eeprom))
        module_manufacture_date.Add(decode_ddr3_module_date(eeprom[120], eeprom[121]))
        'Print "Manufacturer:" & Hex(eeprom[117] And &h7F) & " " & Hex(eeprom[118])
        'Print CMemVendors.MemVendors[CString(Hex(eeprom[117] And &h7F))][LCase(Hex(eeprom[118]))]
       
        'decode_ddr34_manufacturer(eeprom[117], eeprom[118])
      Case DDR4_SDRAM
        part_number.Add(decode_ddr4_part_number(eeprom))
        module_type.Add(decode_ddr4_module_type(eeprom))
        module_speed.Add(decode_ddr4_module_speed(eeprom))
        module_size.Add(decode_ddr4_module_size(eeprom))
        module_manufacturer.Add(decode_ddr4_module_manufacturer(eeprom))
        module_dram_manufacturer.Add(decode_ddr4_module_dram_manufacturer(eeprom))
        module_manufacture_date.Add(decode_ddr4_module_date(eeprom, spd_size[i], eeprom[323], eeprom[324]))
    End Select
  Next
  Print
  For i = 0 To spd_size.max
   
   
   
    Try Print ram_type_str[i];;
   
    Try Print module_manufacturer[i];;
    Try Print module_dram_manufacturer[i]
    Try Print "Manufacturing Date: "; module_manufacture_date[i]; " | ";
    Try Print part_number[i]
    Try Print module_type[i];;
   
    Try Print module_speed[i]
    Try Print module_size[i] & " MB";;
    Try Print voltage[i];;
    Try Print spd_size[i];;
   
    Try Print ram_type_int[i];;
    Try Print spd_revision[i]
    Print "\n"
   
  Next
 
End

Private Function decode_ddr3_spd_revision(bytes As Byte[]) As String

  Return Mid(Hex(bytes[1]), 1, 1) & "." & Mid(Hex(bytes[1]), 2, 1)

End

Private Function decode_ddr3_part_number(bytes As Byte[], Optional partnumber As String) As String

  Dim i As Integer
  For i = 128 To 145
    partnumber &= Chr(bytes[i])
  Next
  Return partnumber

End

Private Function decode_ddr4_part_number(bytes As Byte[], Optional partnumber As String) As String
  Dim i As Integer
  For i = 329 To 348
    partnumber &= Chr(bytes[i])
  Next
  Return partnumber
End

Private Function decode_ddr3_module_type(bytes As Byte[]) As String

  Dim type As String
  Select bytes[3]
    Case 01
      type = "RDIMM (Registered Long DIMM)"
    Case 02
      type = "UDIMM (Unbuffered Long DIMM)"
    Case 03
      type = "SODIMM (Small Outline DIMM)"
    Default
      type = Null
  End Select
  Return type

End

Private Function decode_ddr4_module_type(bytes As Byte[]) As String

  Dim type As String = "Unknown" ''Default Unknown if no detect
  Select Hex(bytes[3], 2)
    Case "01"
      type = "RDIMM (Registered DIMM)"
    Case "02"
      type = "UDIMM (Unbuffered DIMM)"
    Case "03"
      type = "SODIMM (Small Outline Unbuffered DIMM)"
    Case "04"
      type = "LRDIMM (Load-Reduced DIMM)"
    Case "05"
      type = "Mini-RDIMM (Mini Registered DIMM)"
    Case "06"
      type = "Mini-UDIMM (Mini Unbuffered DIMM)"
    Case "08"
      type = "72b-SO-RDIMM (Small Outline Registered DIMM, 72-bit data bus)"
    Case "09"
      type = "72b-SO-UDIMM (Small Outline Unbuffered DIMM, 72-bit data bus)"
    Case "0c"
      type = "16b-SO-UDIMM (Small Outline Unbuffered DIMM, 16-bit data bus)"
    Case "0d"
      type = "32b-SO-UDIMM (Small Outline Unbuffered DIMM, 32-bit data bus)"
    Default
      type = Null
  End Select
  Return type

End

Private Function decode_ddr3_module_speed(bytes As Byte[]) As String
  ' Dim ctime As Float
  ' Dim ddrclk As Float
  ' Dim tbits, pcclk As Integer
  ' Dim mtb As Float = 0.125
  '
  ' If (bytes[10] == 1 And bytes[11] == 8) Then mtb = 0.125
  ' If (bytes[10] == 1 And bytes[11] == 15) Then mtb = 0.0625
  ' ctime = mtb * bytes[12]
  ' ddrclk = 2 * (1000 / ctime)
  '
  ' tbits = 64
  ' Select bytes[8]
  '   Case 1
  '     tbits = 16
  '   Case 4
  '     tbits = 32
  '   Case 3
  '   Case 0
  '     tbits = 64
  ' End Select
  '
  ' pcclk = ddrclk * (tbits / 8)
  ' pcclk -= pcclk % 100
  '
  ' Return Subst("DDR3-&1Mhz PC3-&2", CInt(ddrclk), pcclk)

  Dim divisor As Integer = bytes[10]
  Dim dividend As Integer = bytes[11]
  Dim ratio As Integer = bytes[12]

  If dividend = 0 And divisor = 0 And ratio = 0 Then
    Return "DDR3-Unknown Mhz"
  Else
    Return Subst("DDR3-&1Mhz", ((2000 * dividend) / (divisor * ratio)))
  Endif

End

Private Function decode_ddr4_module_speed(bytes As Byte[]) As String

  Dim mincycle As Integer = bytes[18]
  Dim fineadjust As Integer = Bytes[125]
  Dim frequency As Integer

  frequency = (2000000 / (mincycle * 125 + fineadjust))
  Return Subst("DDR4-&1Mhz", frequency)

End

Private Function decode_ddr3_module_size(bytes As Byte[]) As String

  Dim size As Integer
  ' Dim sdr_capacity As Integer = Lsl(256, Hex(bytes[4]) And &hF)
  ' Dim sdr_width As Integer = Lsl(4, Hex(bytes[7]) And &h7)
  ' Dim bus_width As Integer = Lsl(8, Hex(bytes[8]) And &h7)
  ' Dim ranks As Integer = 1 + Lsr(3, Hex(bytes[7]) And &h7)
 
  ' Print "sdr_capacity = " & Lsl(256, Bytes[4])
  ' Print "sdr_width = " & Lsl(4, bytes[7])
  ' Print "bus_width = " & Lsl(8, bytes[8])
  ' Print "ranks = " & (Lsr(3, bytes[7]) + 1)
 
  ' size = sdr_capacity / 8 * bus_width / sdr_width * ranks
 
  size = ((Hex(bytes[4]) And &h0f) + 28) + ((Hex(bytes[8]) And &h7) + 3)
  size -= (Hex(bytes[7]) And &h7) + 25
  size = (Lsl(1, size)) * (Lsr(3, bytes[7] And &h1f) + 1)
  Return Subst("Module size: &1", size / 1024)

End

Private Function decode_ddr4_module_size(bytes As Byte[]) As String
  Dim sdram_width As Integer
  Dim ranks As Integer
  Dim signal_loading As Integer
  Dim die_count As Integer
  Dim cap As Integer
 
  sdram_width = 4 * CInt(2 ^ (bytes[12] And &h07))
  ranks = ((bytes[12] \ CInt(2 ^ 3)) And &h07) + 1
  signal_loading = (bytes[6] And &h03)
  die_count = ((bytes[12] \ CInt(2 ^ 4)) And &h07) + 1
  cap = (256 * CInt(2 ^ (bytes[4] And &h0f))) / 8
  cap *= (8 * CInt(2 ^ (bytes[13] And &h07))) / sdram_width
  cap *= ranks
  If signal_loading = &h02 Then
    cap *= die_count
  Endif
  ' Print "sdram_width: " & sdram_width
  ' Print "ranks: " & ranks
  ' Print "signal_loading: " & signal_loading
  ' Print "die_count: " & die_count
  ' Print "cap: " & cap
 
  Return Subst("&1", cap)
 
End
' # Size computation
'   my $sdram_width = 4 << ($bytes->[12] & 0x07);
'   my $ranks = (($bytes->[12] >> 3) & 0x07) + 1;
'   my $signal_loading = $bytes->[6] & 0x03;
'   my $die_count = (($bytes->[6] >> 4) & 0x07) + 1;
'   my $cap = (256 << ($bytes->[4] & 0x0f)) / 8;
'   $cap *= (8 << ($bytes->[13] & 0x07)) / $sdram_width;
'   $cap *= $ranks;
'   $cap *= $die_count if $signal_loading == 0x02;    # 3DS
'   printl("Size", $cap . " MB");

Private Function decode_ddr3_voltage(bytes As Byte[]) As String
 
  Return If(bytes[6] = 4, "1.25V ", "") & If(bytes[6] = 2, "1.35V ", "") & If(bytes[6] = 1, "", "1.5V")
 
End

Private Function decode_ddr3_module_manufacturer(bytes As Byte[]) As String
 
  Return decode_ddr34_manufacturer(bytes[117], bytes[118])
 
End

Private Function decode_ddr3_module_dram_manufacturer(bytes As Byte[]) As String

  Return decode_ddr34_manufacturer(bytes[148], bytes[149])
 
End

Private Function decode_ddr4_module_manufacturer(bytes As Byte[]) As String

  Return decode_ddr34_manufacturer(bytes[320], bytes[321])
 
End

Private Function decode_ddr4_module_dram_manufacturer(bytes As Byte[]) As String

  Return decode_ddr34_manufacturer(bytes[350], bytes[351])
 
End

Private Function decode_ddr34_manufacturer(count As Byte, code As Byte) As String

  Dim Manufacturer As String
  Dim bank As String
  Dim index As String

  bank = Hex(count And &h7f, 1)
  index = Hex(code And &h7f, 2)
  Manufacturer = CMemVendors.MemVendors[bank][index]
 
  If Manufacturer = Null Then
    index = LCase(index)
    Manufacturer = CMemVendors.MemVendors[bank][index]
  Endif
 
  If Manufacturer = Null Then
    index = LCase(Hex(code))
    Manufacturer = CMemVendors.MemVendors[bank][index]
  Endif
  Return Manufacturer

End

Private Function decode_ddr3_module_date(syear As Byte, sweek As Byte) As String
  'Print syear; " "; sweek
  syear = Hex(syear)
  sweek = Hex(sweek)
  'Print syear; " "; sweek
  If (syear And &hf0) <= &h90 Or (syear And &h0f) <= &h09 Or (sweek And &hf0) <= &h90 Or (sweek And &h0f) <= &h09 Then
   
    Return Subst("&1&2 W&3", IIf(syear >= &h80, 19, 20), syear, sweek)
   
  Else If (syear <= 99 Or sweek >= 1 Or sweek <= 53) Then
   
    Return Subst("&1&2 W&3", IIf(syear >= 80, 19, 20), syear, sweek)
 
  Else
 
    Return Subst("&1 W&2", syear, sweek)
   
  Endif
  Return "UNKNOWN"
End

Private Function decode_ddr4_module_date(Optional bytes As Byte[], Optional spd_size As Long, syear As Byte, sweek As Byte) As String
  'Print "DDR4 Byte"; syear; " "; sweek
  syear = Hex(syear)
  sweek = Hex(sweek)
  'Print "DDR4 Hex"; syear; " "; sweek
  If (spd_size < 324) Then
    Return "Unknown"
  Endif
  If bytes[323] = &h0 Or bytes[323] = &hff And If bytes[324] = &h0 Or bytes[324] = &hff Then
    Return "Unknown"
  Endif

  Return Subst("&1&2 W&3", IIf(syear >= 80, 19, 20), syear, sweek)
 
End

Private Function decode_ram_type(bytes As Byte[]) As Integer

  If bytes[0] < 4 Then
    Select bytes[2]
      Case 1
        Return DIRECT_RAMBUS
      Case 17
        Return RAMBUS
    End Select
  Else
    Select bytes[2]
      Case 1
        Return FPM_DRAM
      Case 2
        Return EDO
      Case 3
        Return PIPELINED_NIBBLE
      Case 4
        Return SDR_SDRAM
      Case 5
        Return MULTIPLEXED_ROM
      Case 6
        Return DDR_SGRAM
      Case 7
        Return DDR_SDRAM
      Case 8
        Return DDR2_SDRAM
      Case 11
        Return DDR3_SDRAM
      Case 12
        Return DDR4_SDRAM
    End Select
    Return UNKNOWN
  Endif

End