passing file name and array name so it can be loaded

Started by Baggey, October 23, 2021, 18:48:50

Previous topic - Next topic

Baggey

Not even sure if this is even possible  :o

I have a type decleared as Memory. In the Memory are 8 arrays Memory banks within it ie [256] bytes long. Im trying to create a function where i pass the file name and the name of the Array. Then the function loads 256 bytes into the array.

Totally confused and running around in circles ???

Is this possible  :-[ :-X :-\

Baggey
Running a PC that just Aint fast enough!? i7 Quad core 16GB ram 1TB SSD and NVIDIA Quadro K620 . DID Technology stop! Or have we been assimulated!

ZX Spectrum 48k, C64, ORIC Atmos 48K, Enterprise 128K, The SID chip. Im Misunderstood!

col

Hiya,

Not sure that I completely understand the memory bank setup but I'll have stab that you have 8 banks x 256 bytes in 1 x Memory type? If not then it will be a stake in the ground for correction :)

Do you mean something like this?


SuperStrict

Type Memory
Method New()
Banks = New Byte[][8]              ' 8 Banks
For Local i:Int = 0 Until 8
Banks[i] = New Byte[256] ' Each bank is 256 bytes
Next
EndMethod

Field Banks:Byte[][]
EndType

Function Load(Filename:String, Bank:Byte[])
' load 256 bytes from file in to Bank
' get the bank size via Sizeof(Bank), which will be 256 in this example
EndFunction

Local Mem:Memory = New Memory
Load("MyFile.dat", Mem.Banks[0])
Load("MyFile.dat", Mem.Banks[1])
Load("MyFile.dat", Mem.Banks[2])
' ...
Load("MyFile.dat", Mem.Banks[7])
https://github.com/davecamp

"When you observe the world through social media, you lose your faith in it."

Baggey

Quote from: col on October 23, 2021, 19:40:13
Hiya,

Not sure that I completely understand the memory bank setup but I'll have stab that you have 8 banks x 256 bytes in 1 x Memory type? If not then it will be a stake in the ground for correction :)

Do you mean something like this?


SuperStrict

Type Memory
Method New()
Banks = New Byte[][8]              ' 8 Banks
For Local i:Int = 0 Until 8
Banks[i] = New Byte[256] ' Each bank is 256 bytes
Next
EndMethod

Field Banks:Byte[][]
EndType

Function Load(Filename:String, Bank:Byte[])
' load 256 bytes from file in to Bank
' get the bank size via Sizeof(Bank), which will be 256 in this example
EndFunction

Local Mem:Memory = New Memory
Load("MyFile.dat", Mem.Banks[0])
Load("MyFile.dat", Mem.Banks[1])
Load("MyFile.dat", Mem.Banks[2])
' ...
Load("MyFile.dat", Mem.Banks[7])


Emm  :o Thats F*****g Spot ON!  :-X

Just need to adapt!  8)

Baggey
Running a PC that just Aint fast enough!? i7 Quad core 16GB ram 1TB SSD and NVIDIA Quadro K620 . DID Technology stop! Or have we been assimulated!

ZX Spectrum 48k, C64, ORIC Atmos 48K, Enterprise 128K, The SID chip. Im Misunderstood!

Baggey

This is what im trying to do :-

I cant seem to pass the Field array name to my Function Load_Memory. And i cant seem to find any example's for this situation! :(

For Example C64_MEMORY.BASICROM is not being passed to Function Load_Memory(path:String, Memory:Byte[])

Embarrassing someone might see my error!  ;D I think it needs a Pointer soloution :-X

I need to be able to do this as the PLA chip looks at address;s in memory and switches different banks of memory in and out using the bits at address $0001! In BOOT up it holds default $37

The C64 has two or three banks of memory in the same place. BUT depending on the value held at Address $0001 we can then use the appropriate Rom Bank, which is then read by the address on the BUS. So im selecting the write ROM to READ or WRITE from/to.

Code (Blitzmax) Select
'
SuperStrict
'
  Type C64_Memory
  '
    Field RAM       :Byte[65536] ' $10000
    Field COLORRAM  :Byte[4096]  ' $1000
    Field KERNALROM :Byte[8192]  ' $2000
    Field BASICROM  :Byte[8192]  ' $2000
    Field CHARROM   :Byte[4096]  ' $1000
    Field EXTROM    :Byte[16385] ' $4001
  '
  End Type
  '
'
  Global Memory:C64_Memory = New C64_Memory
'
  Function Init_Memory()
'
    ' Load ROMs
    Load_Memory("roms\C64_BasicRom.rom",     C64_MEMORY.BASICROM)
    Load_Memory("roms\C64_CharacterRom.rom", C64_MEMORY.CHARROM)
    Load_Memory("roms\C64_Kernal.rom",       C64_MEMORY.KERNALROM)
'
  End Function
'
  Function Load_Memory(path:String, Memory:Byte[])
'
    ' Load Appropriate Rom with file here!
'
  End Function



Okay! Done some searching and found this snipet of code using Static Arrays!? Commenting this line out seems to make no difference? 'Framework BRL.StandardIO
Code (blitzmax) Select
SuperStrict

'Framework BRL.StandardIO

Local StaticArray arr:Int[10]
process(arr)
For Local i:Int = 0 Until arr.Length
    Print i + " = " + arr[i]
Next

Function process(StaticArray arr:Int[10])
    For Local i:Int = 0 Until arr.Length
        arr[i] = i
    Next
End Function


Looking like this maybe of help. So ill try and adapt.

Resistance Is Futile! The code will be assimulated!

Baggey
Running a PC that just Aint fast enough!? i7 Quad core 16GB ram 1TB SSD and NVIDIA Quadro K620 . DID Technology stop! Or have we been assimulated!

ZX Spectrum 48k, C64, ORIC Atmos 48K, Enterprise 128K, The SID chip. Im Misunderstood!

Henri

Hi,

there seems to be an error in your init function: C64_MEMORY.BASICROM should be Memory.BASICROM as the Memory global variable holds the reference to your memory type.

Framework keyword reduces the size of executable. You can then import only those libraries that you need. By default Blitzmax imports all the core libraries.

-Henri
- Got 01100011 problems, but the bit ain't 00000001

Derron

function pointers or "brl.reflection", both can be used to kinda "pass around" what function to actually call


bye
Ron

Baggey

Quote from: Henri on October 24, 2021, 09:41:06
Hi,

there seems to be an error in your init function: C64_MEMORY.BASICROM should be Memory.BASICROM as the Memory global variable holds the reference to your memory type.

Framework keyword reduces the size of executable. You can then import only those libraries that you need. By default Blitzmax imports all the core libraries.

-Henri

Oh yeah! Sometimes i cant see the Wood through the tress so to speak :-[

How to i find the name off the array that has been passed? finding the Size/Length is easy ie, Memory.length

But Memory.name Dosen't Is there a list for the Syntax to be used somewhere? ie, What are all the .EXTENSIONS that could be used?

Code (blitzmax) Select
'
SuperStrict
'
  Type C64_Memory
  '
    Field RAM       :Byte[65536] ' $10000
    Field COLORRAM  :Byte[4096]  ' $1000
    Field KERNALROM :Byte[8192]  ' $2000
    Field BASICROM  :Byte[8192]  ' $2000
    Field CHARROM   :Byte[4096]  ' $1000
    Field EXTROM    :Byte[16385] ' $4001
  '
  End Type
  '
'
  Global Memory:C64_Memory = New C64_Memory
'
  Init_Memory()
'
  Function Init_Memory()
'
    ' Load ROMs
    'Load_Memory("roms\C64_BasicRom.rom",     MEMORY.BASICROM[])
'End
    Load_Memory("roms\C64_CharacterRom.rom", MEMORY.CHARROM[])
End
    Load_Memory("roms\C64_Kernal.rom",       MEMORY.KERNALROM[])
'
  End Function
'
  Function Load_Memory(path:String, Memory:Byte[])
'
    ' Load Appropriate Rom with file here!
Print "path is :- "+ path
Print "Array Length is :- "+ Memory.Length
Print "Array name is :- "+ Memory.name     ' This line dosen't work!
'
  End Function
'
Running a PC that just Aint fast enough!? i7 Quad core 16GB ram 1TB SSD and NVIDIA Quadro K620 . DID Technology stop! Or have we been assimulated!

ZX Spectrum 48k, C64, ORIC Atmos 48K, Enterprise 128K, The SID chip. Im Misunderstood!

Baggey

Quote from: Derron on October 24, 2021, 10:39:35
function pointers or "brl.reflection", both can be used to kinda "pass around" what function to actually call


bye
Ron

"brl.reflection"

I have no idea what your talking about?  :-[  Im just a Hobby programmer :-X  Is there a link that explains this in depth?

Kind Regards Baggey
Running a PC that just Aint fast enough!? i7 Quad core 16GB ram 1TB SSD and NVIDIA Quadro K620 . DID Technology stop! Or have we been assimulated!

ZX Spectrum 48k, C64, ORIC Atmos 48K, Enterprise 128K, The SID chip. Im Misunderstood!

Derron

https://blitzmax.org/docs/en/api/brl/brl.reflection/

Reflection allows to retrieve some stuff via their "names".
So you know your enemy is "Type TEnemy" and there is a function in this type called "function Shoot()" ?

Code (Blitzmax) Select

Type TEnemy
  Function Shoot()
    print "Shooting!"
  End Function
End Type

Local t:TTypeID = TTypeID.ForName("TEnemy")
if t
  local f:TFunction = t.FindFunction("shoot") 'not case sensitive :-)
  if f Then f.Invoke()
endif


Similar stuff also works for "methods" ... so you search for a method, but this time you pass the "instance" as first object (the "self"). Also you can retrieve the "TTypeID" for an object, not just the name (so you can eg ask what "Type" is passed):

Code (Blitzmax) Select

Type TEnemy
  Field name:String

  Method New(name:String)
    self.name = name
  End Method

  Method Shoot()
    print name + " is shooting!"
  End Method
End Type

Local e1:TEnemy = new TEnemy("Big Boss")
Local e2:TEnemy = new TEnemy("Henchman")

Local t:TTypeID = TTypeID.ForObject(e1)
if t
  Local f:TMethod = t.FindMethod("shoot")
  if f Then f.Invoke(e2) 'we pass e2 here, not e1 ;-)
endif


So retrieving a "method" returns the method for the type the "e1" is of. It here works when passing "e2" then ... because they are the same type. If you had another type and passed an instance of it ... it will fail.
So better pass what was used in the "ForObject()".


Next to Methods and Functions you can also retrieve Fields etc.


bye
Ron

Derron

Regarding function callbacks - I think we already talked about this in the emulator thread ... for this retro thing. There already function pointers and "arrays of function pointers" were described ... simply use them.


Reflection allows a more dynamic approach - as the params are passed as an "object array". But you could always have your functions defined similar - which adds a bit of inconveniences :)

Code (BlitzMax) Select

Function Test1(args:object[]); print "Test 1 ..." + string(args[0]) + ", " + string(args[1]); End Function
Function Test2(args:object[]); print "Test 2 ..." + args.length; End Function
Function Test3(args:object[]); print "Test 3 ..." + args.length; End Function

Type TFunctionWrapper
  Field func(args:object))

  Method New(f:(args:object))
    func = f
  End Method
 
  Method Call(args:object)
    if func then func(args)
  End Method
End Type


Local functionPointers:TStringMap = new TStringMap
functionPointers.Insert("Test1", new TFunctionWrapper(Test1) )
functionPointers.Insert("Test2", new TFunctionWrapper(Test2) )
functionPointers.Insert("Test3", new TFunctionWrapper(Test3) )


'call
TFunctionWrapper(functionPointers.ValueForKey("Test1")).Call(["Hello World", object(string(12345))])


All codes untested ... but might show approaches to your problem.


bye
Ron

col

QuoteHow to i find the name off the array that has been passed? finding the Size/Length is easy ie, Memory.length

How about creating a type called Bank that has an ID Field and the byte array as it members? You could use strings or enum for the ID. Just a suggestion  ;)

Type Bank
    Field Id:String
    Field Data:Byte[]

    Method New(Id:String, BankSize:UInt)
        Self.Id = Id
        Self.Data = New Byte[BankSize]
    End Method
End Type

Type Memory
    Field RAM:Bank = New Bank("RAM", 65536)
    Field COLORRAM:Bank = New Bank("ColorRAM", 4096)
    ...
EndType

Function LoadData(Filename:String, RamBank:Bank)
    Print RamBank.Id
EndFunction
https://github.com/davecamp

"When you observe the world through social media, you lose your faith in it."

Baggey

Quote from: col on October 24, 2021, 12:31:13
QuoteHow to i find the name off the array that has been passed? finding the Size/Length is easy ie, Memory.length

How about creating a type called Bank that has an ID Field and the byte array as it members? You could use strings or enum for the ID. Just a suggestion  ;)

Type Bank
    Field Id:String
    Field Data:Byte[]

    Method New(Id:String, BankSize:UInt)
        Self.Id = Id
        Self.Data = New Byte[BankSize]
    End Method
End Type

Type Memory
    Field RAM:Bank = New Bank("RAM", 65536)
    Field COLORRAM:Bank = New Bank("ColorRAM", 4096)
    ...
EndType

Function LoadData(Filename:String, RamBank:Bank)
    Print RamBank.Id
EndFunction


How does one call the function LoadData(Filename:String, ???)

Baggey
Running a PC that just Aint fast enough!? i7 Quad core 16GB ram 1TB SSD and NVIDIA Quadro K620 . DID Technology stop! Or have we been assimulated!

ZX Spectrum 48k, C64, ORIC Atmos 48K, Enterprise 128K, The SID chip. Im Misunderstood!

Baggey

Okay! Answered my own Question  8)

So, Now does Anyone know if i could use Tbank's then lockBank  for even faster access with a byte ptr?  ???

Thanks Everyone for help so far  ;)

Code (blitzmax) Select

SuperStrict

Global C64_Memory:Memory = New Memory

init_Memory()


Type Bank
    Field Id:String
    Field Data:Byte[]

    Method New(Id:String, BankSize:UInt)
        Self.Id = Id
        Self.Data = New Byte[BankSize]
    End Method
End Type


Type Memory
    Field RAM:Bank = New Bank("RAM", 65536)
    Field COLORRAM:Bank = New Bank("ColorRAM", 4096)
    '... more Declerations Here!
EndType


Function Load_Memory(Filename:String, RamBank:bank)
    Print
    Print "name = "+RamBank.Id
    Print "name Length = "+RamBank.Id.length
    Print "BankSize = "+RamBank.Data.length
    Print "Dimensions = "+RamBank.data.numberOfDimensions
    RamBank.data[10]=255 ' Would be 0 with out this line!
    Print RamBank.data[10]
    Print RamBank.data.elementTypeEncoding[0]
    Print "I can only assume that 98 means Byte!"
    ' Note you can use this as well?
    'Rambank.Id[10]=255
    'Print Rambank.Id[10]
EndFunction


Function Init_Memory()
    '
    ' Load ROMs
    'Load_Memory("roms\C64_BasicRom.rom",     MEMORY.BASICROM[])
    'End
    Load_Memory("roms\C64_CharacterRom.rom", C64_Memory.ram)
    Load_Memory("roms\C64_ColorRam.rom", C64_Memory.ColorRam)
    End
    'Load_Memory("roms\C64_Kernal.rom",       MEMORY.KERNALROM[])       
    '
End Function


Kind Regards Baggey
Running a PC that just Aint fast enough!? i7 Quad core 16GB ram 1TB SSD and NVIDIA Quadro K620 . DID Technology stop! Or have we been assimulated!

ZX Spectrum 48k, C64, ORIC Atmos 48K, Enterprise 128K, The SID chip. Im Misunderstood!

col

Is a TBank going be faster?
If you are thinking of issuing a LockBank call then there will be at least a function call overhead to consider.

Accessing a byte from an array will be direct access to the memory of the array itself - very little overhead except...
I would also expect that in a debug build you will have an array bounds check which can be quite helpful, but in a release build that bounds check should be removed.
https://github.com/davecamp

"When you observe the world through social media, you lose your faith in it."

Midimaster

with TBank you can use the same RAM with BYTE acces but also with INTEGER or LONG access. This could be used for clearing, copying, moving blocks of Bank RAM.

This code clears the first 4000 bytes in a Bank
Code (BlitzMax) Select

' fill the bank with something
Global RAM_Bank:TBank = LoadBank("test.ram")

'Then clean it again:
FastClear RAM_Bank, 4000

Function FastClear(Bank:TBank, size:Int)
     local Start:Long Ptr = Long Ptr( LockBank(Bank) )
     For local i%=0 to size/4
          Start[i]=0
     Next



Even a BYTE array can be manipulated via TBANK for fast actions:

Code (BlitzMax) Select

Global RAM_ARRAY:Byte[65536]

LoadArray (RAM_ARRAY, "test.ram")

Function LoadArray (Array:Byte[], FileName$)
     Local RAM_Bank:TBank = CreateStaticBank(Byte Ptr(ARRAY), ARRAY.Length)
     Local Source:TBank = LoadBank(FileName)
     CopyBank Source, 0, RAM_Bank, 0, ARRAY.Length
End Function
...back from Egypt