OO Language

Pagina 4/5
1 | 2 | 3 | | 5

Van badsector

Rookie (27)

afbeelding van badsector

10-10-2017, 22:49

@assembler: Thanx, but I'm actually looking for something with classes, Inheritance and memory management.
Although "MSLOOPX" seems great for building games, I think it would not really be useful for creating applications.

Van Grauw

Ascended (10713)

afbeelding van Grauw

11-10-2017, 15:15

I use OOP extensively in my assembly MSX projects. Most of the supporting code is in a shared library project.

For example, look at FileReader.asm, it shows calling convention (“this” in ix, or iy if _IY suffix), constructors, destructors, inheritance, super calling, class definitions… Here’s some code from gunzip which shows instantiation. And here’s my allocator. For my class definitions I rely on a Glass feature to access symbols inside macro definitions as offsets.

Often I also use a lite-version of this class system without dynamic instantiation, and just rely fully on static instantiation, so it uses just the macros and calling conventions and doesn’t need the Class or Heap objects. That’s the case in VGMPlay. In this particular example you can also see some objects stored by reference, and some by value.

I also use the class system quite extensively with generated code btw, embedded in the objects. The downside is that when dynamically allocating you need to make sure the code snippets are relocatable, or fix them up during construction, so it’s easier to use statically. (But gunzip uses it dynamically and gets most of its high performance from that.)

About inheritance; the only difference from composition is that because it comes first in the class definition macro, the ix / iy pointers do not need to be adjusted before calling methods on the base class. Polymorphism I usually implement through either a jp xx as the first content of the class so I can call using jp ix (with the limitation that you can only do this once), or as a simple function reference member which subclasses can override (at the cost of some space each object). A vtable would be simple to do, but it requires some more indirect lookups and so far I haven’t really had the need for it.

I would want to implement some feature in Glass in the future which can do code generation for you (akin to C++ templates), so that e.g. if you want to call a method on a member object, rather than offsetting ix / iy, you can call it like “call Header_Construct(ix + VGM.header)”, which would generate a version of Header_Construct which replaces all instances of ix with ix + VGM.header. But for now this isn’t possible.

I’m curious to hear about your experiences and the choices you’ve made, what works well for you and what doesn’t, etc. Maybe get some new ideas as well.

Van Louthrax

Prophet (2436)

afbeelding van Louthrax

11-10-2017, 16:42

I was wondering if anybody already tried to use a "C++ to C" convertor and then compile the code with a Z80 C compiler?

I have this in mind for a while now but have not really searched for the way to convert C++ to C (doesn't GCC or LLVM allow that?).

Van badsector

Rookie (27)

afbeelding van badsector

11-10-2017, 19:46

@Grauw: What I want to build is more than just a way to implement OO in assembly. I'm building a framework that could serve as the base of every MSX project I do, (and possibly for other people too in the future). It's optimized for speed but also to minimize memory usage. It uses a MemoryMapper with 256 byte (or more) blocks for each Object. Each Object has it's own variables and is identified by a 16 bit ObjectId. Classes can inhered functions from a parent class.

I've currently build the following classes / techniques: Object, String, Array, File, VDP, Application, Form, FormControl, Mouse & Keyboard events (on Application, Form or FormControl). Each class having about 20 different functions on average.
I have a priority based MessageQueue for asynchronous execution. And about every function (if possible) has Unit Testing.
It's about 380 files now but compiles down to about 8kb.

So It's been quite a lot of work so far, but I'm fairly pleased with the results so far. I'm not yet ready to publish, but my plans are to make this framework public in the near future and provide the necessary documentation to use it.

Van Grauw

Ascended (10713)

afbeelding van Grauw

11-10-2017, 20:06

Nice, looking forward, even if in unfinished state, to get some inspiration.

Basically that’s what “neonlib” is for me. I have some unit testing as well Smile, but only for some critical classes (like Heap). I generally build stuff as I need it, e.g. File is something on my wishlist (to abstract away the difference between DOS1 and DOS2), VDP currently is a pretty plain static function library but I have a proper object for VDPCommand. I’m also going to be needing coroutines and memory contexts pretty soon for VGMPlay.

One challenge I am thinking about currently is the TPA space; it’s very limited as you know, or at least that’s something I’m running in to a lot lately. I’m thinking about organising code in blocks or modules or something, and having some type of far call, but it’s not crystal clear in my mind yet what to do, especially because I don’t want to add too much hassle in terms of assembling (I fear I may need to implement some assembler support for it).

One example of a difficult case; gunzipping in VGMPlay needs a 32K decompression window buffer (in page 1 & 2), however I also need to read from something. Currently page 0 contains the code and page 3 contains the heap, and in page 0 I’ve got read buffer as well which works when reading straight from disk, however if I want to read from a mapped buffer I can only page it in as a whole 16K block… which I don’t have space for anymore. Pff.

Van ToriHino

Paladin (828)

afbeelding van ToriHino

11-10-2017, 20:23

Juggling with the mapper pages is always one of the challenging things for me too. There's only so much room to page in the memory, and not always room for calls or routines that 'take forever' Tongue . Some good abstraction which still performs quite well could be a great help for this.

Van badsector

Rookie (27)

afbeelding van badsector

11-10-2017, 21:52

What I do is place the framework (and most of the code) in Page 0 which is always on the same segment. Also Page 3 is fixed and holds a lot of (global and system) variables and about 4-8k of code. Page 2 is used as Object data and is switched (potentially for each Object) a lot. Page 1 can be used for additional code, but is mostly used when data from 1 object needs to be copied or compared to another Object in Page 2.
Using this principle I haven't had any mapper issues at all. And performance isn't bad.
Splitting Code and Data helps to minimize the size a block of code uses, so 16K can get you very far.

Van hit9918

Prophet (2927)

afbeelding van hit9918

11-10-2017, 22:40

far calls. what about labels beyond 64k.
one day I saw some ROM source that looked like it knows some big addresses, I dont know whether there are assemblers who do it.

it would be nice if the assembler doesnt really solve specific cases, but have general purpose mechanism to make all cases.
an address hi hi byte could be a segment. or a slotID.
the assembler needs just big numbers in labels, nothing else

org 0xFF0000
label:
ld a,>>label ;a = 255. second hi byte

org 65536*variable
with -D variable and multiple assembler runs a tool can see which opcode fields change and create lists.

hl,mapper,slotID makes 32bit, assembler needs 32bit numbers
hl,mapper,playsoniq mapper hi byte, slotID, need 40bit numbers Big smile

oh maybe one could get the VDP port relocatible the same way
ld a,port98
one time run with -D port98=0, the other time with -D port98=1, opcode fields change, a tool can detect it

I got codes relocatible 256 byte wise in 64k.
at the start of the BIN is code to relocate itself
to make z80 able of pc-relative addressing (get at the tail of the BIN) I poked pop hl : jp (hl) to USR9
CALL that code is like ld hl,pc

Van Grauw

Ascended (10713)

afbeelding van Grauw

11-10-2017, 22:58

Yeah, hit9918, that’s a good start. Glass currently gives a warning when the address exceeds FFFFH, that needs to go Smile. Though, it’s still not the complete story, since compilation address != bank address. I kinda don’t want to add a file-pointer magic variable ($$), looking for alternatives (explicitly defining banks on sections maybe and being able to determine which bank I am in currently), but maybe in the end I should.

Van hit9918

Prophet (2927)

afbeelding van hit9918

11-10-2017, 23:21

I didnt understand "file-pointer magic variable ($$)"?
mhm segment 0 = sysarea, maybe one can hardwire codes to segments 1,2,3 without relocation.
I just liked to think of dynamic library loading scenarios
And the only need I see on the assembler side is bigger variables
the low 16bit used the usual way, while about the upper bits the assembler doesnt know the use
it depends on external tools and on the opcodes used
ld a,>>variable
it could be a mapper segment, it could be a slotID
depends on the package

Pagina 4/5
1 | 2 | 3 | | 5