Unified graphic format

ZXNet echo conference «code.zx»

From Alexander Bondarenko To All 23 April 2004

*** Also sent to ZX.GRAFIX (Like graphon) *** Also sent to CODE.ZX (For those who know how to code...) *** Also sent to ZXNET.SOFT (Softina...) Hello, All! There is an idea to create a subject on Spec. Approximately this is - pictures of any size (smaller or larger than the screen), with any number (1, 2, or 3) of plans, with or without attributes. You can don’t even get hung up on Spec’s attributes, but do multicolor option. Here you just need to come up with a header standard for this format and publish a library for its use. Who's in favor? Best regards, Alexander.

From Kirill Frolov To Alexander Bondarenko 5 May 2004

Press RESET immediately, Alexander Bondarenko! On Fri, 23 Apr 04 22:57:14 +0400, Alexander Bondarenko wrote: AB> Here you just need to come up with a header standard for this format AB> and publish a library for its use. AB> Who's in favor? Down with formats, XML is everything! No, really a parser for spec It's easy to do. Only getch() is needed, nothing else. Another allocator memory. There are problems with this...

From Aleksey Senilov To Kirill Frolov 6 May 2004

Hello, _/Kirill/_! 05 May 2004 19:34, Kirill Frolov wrote to Alexander Bondarenko: KF> Down with formats, XML is everything! No, well, really a parser for spec KF> is easy to do. Only getch() is needed, nothing else. More KF> memory allocator. There are problems with this... A memory allocator would actually be very nice, I’ve already invented it myself several times, for different purposes. There are actually two options - either a table blocks, or the blocks themselves have 3-byte headers (which is not entirely convenient when small blocks). And the question is whether to drag in the upper memory here, or on it your page allocator. In the case of processes, we must also take into account who takes the memory, as well as critical sections. But this is for the OS, not programs. See you again! Best regards, Thann.

From Kirill Frolov To Aleksey Senilov 9 May 2004

Press RESET immediately, Aleksey Senilov! On Thu, 06 May 04 11:38:17 +0400, Aleksey Senilov wrote: KF>> Down with formats, XML is everything! No, well, really a parser for spec KF>> is easy to do. Only getch() is needed, nothing else. More KF>> memory allocator. There are problems with this... AS> A memory allocator would be really nice, I invented it myself AS> several times already, for different purposes. There are actually two options - either AS> block table, or the blocks themselves have 3-byte headers (which is not quite AS> convenient for small blocks). Both. The one with the table is convenient for selecting blocks fixed and relatively large size. But it is not necessary that the allocated space is continuous. Traditional C malloc() operates on a heap, where all allocated parts have different and more often small size. No, in fact, the most profitable is the combined one. approach, it will be more profitable to allocate very small areas of memory on a stack organized inside one larger block... By the way, I get 6 bytes per block: byte purpose 0, 1 mark, sign of the beginning of a block (for greater foolproofness)2, 3 size in bytes 4..N+4 data... N+5, N+6 size in bytes, negative (to iterate through the heap in the opposite direction, behind these two bytes lies the next block and they are addressed relative to its beginning) Another option is possible, with pointers. Minimum -- 4 bytes per block (doubly linked list, pointer to next and previous). With a tag and it is very useful for preventing errors, there will be 6. You can also have a singly linked list, but then the heap will be looked through always from one place, from the beginning - this is bad. Usually a bunch every time is viewed from the next block, cyclically, this prevents accumulation of a large number of small blocks / and unused memory / with one edge of the heap. AS> And the question is whether to drag the upper memory here, or onto it AS> your page allocator. Page-wise or block-by-block. This is better for page memory, because it is often very desirable to allocate some part of memory It is impossible to give away the whole thing and not a single byte. And inside the blocks selected using a block-by-block allocator, you can create heaps to allocate smaller ones pieces of unfixed size. AS> In the case of processes, you also need to take into account who takes the memory, as well as AS> critical sections. But this is for the OS, not programs. I'll tell you how to make a semaphore for 8 positions: scf rl (hl) jr nc, free ; busy (all 8) free: ... ... or a rr(hl); released the resource. something like this... For the binary version, the trigger value == -2.

From Alexander Bondarenko To Aleksey Senilov 10 May 2004

*Hello, Aleksey!* Catch my ideas about the subject “Unified Graphic Format”, about which your foot wrap to comrade cracked on May 6, 2004. Kirill Frolov. KF>> Down with formats, XML is everything! No, well, really a parser for KF>> it’s easy to make a speck. Only getch() is needed, nothing else. KF>> Another memory allocator. There are problems with this... AS> A memory allocator would actually be very nice, just one AS> has already been invented several times, for different purposes. Options actually AS> two - either a table of blocks, or 3-byte headers in the blocks themselves AS> (which is not very convenient for small blocks). And the question is whether to drag AS> top memory here, or its own page allocator. B AS> in the case of processes, you also need to take into account who takes the memory, as well as AS> critical sections. But this is for the OS, not programs. Well, I’m telling you - everything depends on the AXIS.... /That’s all, Aleksey, you can scroll further.../

From Ivan Roshin To Kirill Frolov 11 May 2004

Hello, Kirill! 9 May 2004 you wrote: KF> Another option is possible, with pointers. Minimum -- 4 KF> bytes per block (doubly linked list, pointer to next KF> and previous). A doubly linked list can be implemented using for each elements are not pointers to the previous and next elements, but only one variable of the same length as the pointer. That is in this case, you can spend not 4 bytes per list element, but only 2. Best regards, Ivan Roshchin.

From Kirill Frolov To Ivan Roshin 12 May 2004

Press RESET immediately, Ivan Roshin! On Tue, 11 May 04 04:26:06 +0400, Ivan Roshin wrote: KF>> Another option is possible, with pointers. Minimum -- 4 KF>> bytes per block (doubly linked list, pointer to next KF>> and previous). IR> A doubly linked list can be implemented using for each IR> elements are not pointers to the previous and next elements, but IR> only one variable of the same length as the pointer. That is IR> in this case you can spend not 4 bytes per list element, but IR> only 2. In this case, an XOR of pointers to the previous and next is stored. blocks, right? This method is only applicable for sequential search elements in one direction - in this case the pointer to the previous (next) element, and the address of the next (previous) one can be calculate it by "proxying" it with the address of the current element. But in case when, for an element selected at random from a list, you need to find and next and previous elements, for example to exclude the current one from the chain (when freeing the block), this method is unacceptable. In fact, a list organized by this method is not doubly linked.is. In fact, it is simply connected, but in two directions at the same time...

From Kirill Frolov To Alexander Bondarenko 12 May 2004

Press RESET immediately, Alexander Bondarenko! On Sun, 09 May 04 23:29:21 +0400, Alexander Bondarenko wrote: KF>>> Down with formats, XML is everything! No, well, really a parser for KF>>> it’s easy to make a speck. Only getch() is needed, nothing else. KF>>> Another memory allocator. There are problems with this... AS>> A memory allocator would actually be very nice, just one AS>> has already been invented several times, for different purposes. Options actually AS>> two - either a table of blocks, or 3-byte headers in the blocks themselves AS>> (which is not very convenient for small blocks). And the question is whether to drag AS>> top memory here, or your own page allocator for it. B AS>> in the case of processes, you also need to take into account who takes the memory, as well as AS>> critical sections. But this is for the OS, not programs. AB> Well, I’m telling you - everything rests on the AXIS.... For compatibility with TR-DOS programs, it can be suggested to allocate them memory in... RAM disk. The allocated memory is simply represented by a file in the directory, and is thus protected from changes by other programs, both using a RAM disk and simultaneously solving the problemmemory allocation. With sufficient RAM disk capacity, even "multitasking" as it was in MagOS (for Scorpion). Typically, memory within 128KB is used completely by programs, and everything beyond often allocated for a RAM disk. For example, in KAY it’s like this, but only with the exception that memory in excess of 256KB is allocated for the RAM disk. And returning to the question about the allocator, I wanted to say then, there there must be at least 3 arguments: the requested minimum size allocated memory area (required argument), physical address memory (optional argument), valid address, from and to, for microprocessor (optional argument). The second is needed for special cases, such as a driver for some hardware. Third - because there is significantly more memory than the addresses of the Z80, and sometimes it is required that the allocated memory did not overlap at addresses, in other words, it was simultaneously accessible without the need to switch pages.

From Ivan Roshin To Kirill Frolov 13 May 2004

Hello, Kirill! 12 May 2004 you wrote: KF>>> Another option is possible, with pointers. Minimum -- 4 KF>>> bytes per block (doubly linked list, pointer to next KF>>> and previous). IR>> A doubly linked list can be implemented using for IR>> of each element are not pointers to the previous and next IR>> elements, but only one variable of the same length as IR>> pointer. That is, in this case you can spend not 4 IR>> bytes per list element, but only 2. KF> In this case, the XOR of pointers to the previous one is saved KF> and the next blocks, right? When implemented in Z80 assembler, it is apparently more convenient to save not XOR, but the sum or difference of pointers, because addition commands and subtractions can work immediately with 16-bit operands, unlike XOR. KF> This method is applicable only for sequential search KF> elements in one direction - always known KF> pointer to the previous (next) element, and address KF> next (previous) can be calculated by “proxying” it KF> with the address of the current element. That is, if pointers to two adjacent elements are known, You can move through the list in any direction. KF> But in the case when for randomly selected from the list The KF> element needs to be found both next and previous KF> elements, for example to exclude the current one from the chain KF> (when freeing a block), this method is unacceptable. If only the address of this element is known, then yes. KF> In fact, the list is organized using a similar method KF> is not doubly connected. Essentially it is simply connected, but KF> simultaneously in two directions... Best regards, Ivan Roshchin.

From Aleksey Senilov To Kirill Frolov 14 May 2004

Hello, _/Kirill/_! May 09, 2004 12:00, Kirill Frolov wrote to Aleksey Senilov: AS>> A memory allocator would actually be very nice, just one AS>> has already been invented several times, for different purposes. Options AS>> actually two - either a table of blocks, or in the blocks themselves AS>> headers are 3-byte (which is not very convenient for small blocks). KF> Both. The one with the table is convenient for selecting blocks KF> of a fixed and relatively large size. But it is not necessary that KF> the allocated space is contiguous. Traditional C malloc() KF> operates on a heap, where all allocated parts have different and more often KF> small size. No, in fact, the most profitable combination is KF> approach, so it will be more profitable to allocate very small areas of memory KF> on a stack organized inside one larger block... KF> By the way, I get 6 bytes per block: And I got 5. Bytes for the busy flag + owner, 2 bytes length, and 2 byte address of the previous block. Yes, regardless of the structure, the interface remains the same - setting toheap location and initialization (init), alloc, free and realloc. KF> Another option is possible, with pointers. Minimum -- 4 bytes per block KF> (doubly linked list, pointer to next and previous). With the tag KF> and it is very useful for preventing errors, it will be 6. KF> You can also have a singly linked list, but then the heap will be scanned KF> always from one place, from the beginning - this is bad. Yes, simply connected is definitely bad. As for preventing errors, you can (although this is also longer in speed) check the previous and next blocks to see if they converge lengths/pointers. Then you don't need a tag. KF> Usually a bunch every time KF> is viewed from the next block, cyclically, this prevents KF> accumulation of a large number of small blocks /and unused memory/ with KF> one edge of the heap. That is, the address of the last allocated block is remembered, and at the next alloc is it searched not first, but after it? Yes, that's probably true. AS>> And the question is whether to drag the upper memory here, or onto it AS>> your page allocator. KF> Page-wise, or block-by-block. This is better for page memoryKF> because it is often very desirable to allocate some part of memory KF> cannot be given entirely and not a single byte. And inside the selected blocks KF> using a block-by-block allocator, you can create heaps to allocate smaller ones KF> pieces of non-fixed size. Then it turns out that the allocator functions also need to pass the address/size heaps. Isn't it too much? And the fact that the upper memory is page-by-page is, yes, the most convenient and least resource-intensive option. Occupancy table - bit mask, or if necessary owners are taken into account, then byte per page. AS>> In the case of processes, you also need to take into account who takes the memory, and AS>> are also critical sections. But this is for the OS, not programs. KF> I'll tell you how to make a semaphore for 8 positions: KF> scf KF> rl (hl) KF> jr nc, free KF> ; busy (all 8) KF> free: KF> ... KF> ... KF> or a KF> rr (hl) ; released the resource. KF> something like this... For the binary version, the trigger value == -2.This is all understandable, but why was it said? What does this have to do with critical sections? By To me, it’s better not a binary counter, but a simple one-byte counter. If it is 0, then free. See you again! Best regards, Thann.

From Aleksey Senilov To Kirill Frolov 14 May 2004

Hello, _/Kirill/_! May 09, 2004 12:00, Kirill Frolov wrote to Aleksey Senilov: AS>> A memory allocator would actually be very nice, just one AS>> has already been invented several times, for different purposes. Options AS>> actually two - either a table of blocks, or in the blocks themselves AS>> headers are 3-byte (which is not very convenient for small blocks). KF> Both. The one with the table is convenient for selecting blocks KF> of a fixed and relatively large size. But it is not necessary that KF> the allocated space is contiguous. Traditional C malloc() KF> operates on a heap, where all allocated parts have different and more often KF> small size. No, in fact, the most profitable combination is KF> approach, so it will be more profitable to allocate very small areas of memory KF> on a stack organized inside one larger block... KF> By the way, I get 6 bytes per block: And I got 5. Bytes for the busy flag + owner, 2 bytes length, and 2 byte address of the previous block. Yes, regardless of the structure, the interface remains the same - setting toheap location and initialization (init), alloc, free and realloc. KF> Another option is possible, with pointers. Minimum -- 4 bytes per block KF> (doubly linked list, pointer to next and previous). With the tag KF> and it is very useful for preventing errors, it will be 6. KF> You can also have a singly linked list, but then the heap will be scanned KF> always from one place, from the beginning - this is bad. Yes, simply connected is definitely bad. As for preventing errors, you can (although this is also longer in speed) check the previous and next blocks to see if they converge lengths/pointers. Then you don't need a tag. KF> Usually a bunch every time KF> is viewed from the next block, cyclically, this prevents KF> accumulation of a large number of small blocks /and unused memory/ with KF> one edge of the heap. That is, the address of the last allocated block is remembered, and at the next alloc is it searched not first, but after it? Yes, that's probably true. AS>> And the question is whether to drag the upper memory here, or onto it AS>> your page allocator. KF> Page-wise, or block-by-block. This is better for page memoryKF> because it is often very desirable to allocate some part of memory KF> cannot be given entirely and not a single byte. And inside the selected blocks KF> using a block-by-block allocator, you can create heaps to allocate smaller ones KF> pieces of non-fixed size. Then it turns out that the allocator functions also need to pass the address/size heaps. Isn't it too much? And the fact that the upper memory is page-by-page is, yes, the most convenient and least resource-intensive option. Occupancy table - bit mask, or if necessary owners are taken into account, then byte per page. AS>> In the case of processes, you also need to take into account who takes the memory, and AS>> are also critical sections. But this is for the OS, not programs. KF> I'll tell you how to make a semaphore for 8 positions: KF> scf KF> rl (hl) KF> jr nc, free KF> ; busy (all 8) KF> free: KF> ... KF> ... KF> or a KF> rr (hl) ; released the resource. KF> something like this... For the binary version, the trigger value == -2.This is all understandable, but why was it said? What does this have to do with critical sections? By To me, it’s better not a binary counter, but a simple one-byte counter. If it is 0, then free. See you again! Best regards, Thann.

From Aleksey Senilov To Alexander Bondarenko 14 May 2004

Hello, _/Alexander/_! May 10, 2004 00:29, Alexander Bondarenko wrote to Aleksey Senilov: AB> Well, I’m telling you - everything rests on the AXIS.... So what is stopping you from creating it? The burden of past software? Disjointed attempts writing? See you again! Best regards, Thann.

From Kirill Frolov To Aleksey Senilov 15 May 2004

Press RESET immediately, Aleksey Senilov! On Fri, 14 May 04 14:26:05 +0400, Aleksey Senilov wrote: KF>> cannot be given entirely and not a single byte. And inside the selected blocks KF>> a block-by-block allocator can create heaps to allocate smaller ones KF>> pieces of non-fixed size. AS> Then it turns out that the allocator functions must also be passed AS> heap address/size. Isn't it too much? One pointer to a heap object, in which everything that is needed is stored. KF>> I'll tell you how to make a semaphore for 8 positions: KF>> scf KF>> rl (hl) KF>> jr nc, free KF>> ; busy (all 8) KF>> free: KF>> ... KF>> ... KF>> or a KF>> rr (hl) ; released the resource. KF>> something like this... For the binary version, the trigger value == -2. AS> This is all clear, but why was it said? What does it have to do with the critical ones? AS> sections? A more traditional method involves disabling interrupts.Not acceptable when counting time based on a frame interrupt (it can easily be skip) and is difficult to implement when working with connected modems according to the Kondratiev scheme (there is NMI, it is prohibited by output to the port...) AS> For me, it’s better not a binary counter, but a simple one-byte counter. If it is 0, AS> means free. The problem is how to check that it is 0, and set it to not 0 if it is was 0... Even for this you will have to either disable interrupts, or use the shift command.

From Aleksey Senilov To Kirill Frolov 17 May 2004

Hello, _/Kirill/_! May 15, 2004 00:54, Kirill Frolov wrote to Aleksey Senilov: AS>> Then it turns out that the allocator functions must also be passed AS>> heap address/size. Isn't it too much? KF> One pointer to a heap object, in which everything that is needed is stored. However, yes... it’s just that this parameter can be entered automatically in the system, before calling alloc directly. AS>> This is all clear, but why was it said? And here AS>> critical sections? KF> A more traditional method involves disabling interrupts. KF> Unacceptable when counting time based on a frame interrupt (it’s easy KF> skip) and is difficult to implement when working with connected modems KF> according to the Kondratiev scheme (there is NMI, prohibited by output to the port...) Then yes, this is the right option. AS>> For me, it’s better not a binary counter, but a simple one-byte counter. AS>> If it is 0, it means free. KF> The problem is how to check that it is 0, and set it to not 0 if it is KF> was 0... Even for this you will have to either disable interrupts, orKF> use the shift command. What about inc/dec(hl) and checking the Z flag? Free value then rather #FF, but still. See you again! Best regards, Thann.