Jump to content

apersson850

Members
  • Posts

    2,027
  • Joined

  • Last visited

  • Days Won

    2

apersson850 last won the day on January 20 2022

apersson850 had the most liked content!

1 Follower

Profile Information

  • Gender
    Male
  • Location
    Traryd, Sweden
  • Interests
    Orienteering, photography, technology, the old TI 99/4A.

Recent Profile Visitors

8,122 profile views

apersson850's Achievements

River Patroller

River Patroller (8/9)

2.6k

Reputation

  1. Well, if you need that speed, then sure. That's the best way. I have problems seeing a more complex game, written in Pascal, which can take advantage of such a screen update concept at such speeds that your design is necessary. For such purposes I would imagine the RAMdisk concept would be quick enough, or a larger part of the game has to run in assembly. But I have no real experience from exactly this. It's just a hunch. Regarding the feasibility of making a large RAMdisk - I checked the directory structure and all block numbers are integers. Thus you can have 32768 blocks, or 16 megabytes of memory on a single disk. Only 77 files, but if you map a memory expansion into one file, you don't need any more.
  2. Most probably that they could reuse quite a lot of the handling of the instructions if they behaved in the same way, byte or word. As you also are into in your post, just more detailed.
  3. Oddly enough, it's explained in detail in the TI-99/4A console and peripheral expansion system technical data, 1049717-1. Here's a copy of section B.1.2.1 READ before WRITE considerations There are different READ and WRITE addresses for most of the memory-mapped devices (MMDs). This is because the TMS 9900 does a READ operation at the destination address prior to writing to it. Many of the MMDs have internal address registers that autoincrement after either a READ or a WRITE operation. This autoincrement characteristic of the MMD may not produce the desired results if it is not taken into consideration when designs or modifications are made. The READ before WRITE exists because the TMS 9900 is a word-oriented machine from the memory access standpoint. The several byte-oriented instructions are carried out by the machine in a word execution format, and the other byte in the word must not be altered. The machine itself must save the unaltered byte, concatenate the new byte to it, and return the word to memory. The internal logic of the TMS 9900 is designed this way because it was to the designers distinct advantage to do this same READ before WRITE on both byte and word moves. Another thing I noticed in that document may shed some light on the discussion we've had about the usefulness of LIMI 2 when LIMI 1 does the same job. This is about how to design a card to be used in the expansion box. There are two levels on which to interrupt, bu the TI-99/4A supports only one (INTA*). THIS IS THE ONE YOU MUST USE. Interrupt level status bits are defined by the Personal Computer PCC at Texas Instruments, and for the moment are not sensed by the TI-99/4A. If they were to be sensed, the TI-99/4A would cause a line to go low (SENILA*), which tells the PCB logic to gate its status bit to the system data bus. I don't know, but there could be a reason for LIMI 2 being used buried here, since they obviously at some time had two interrupt levels in consideration. Reading this it sounds very much as somebody planned more computers than just the TI-99/4A to be able to use the expansion box.
  4. Yes, I have such a design in my console. The 64 K RAM can be mapped over all 8 K segments in the console, one at a time. If you map out the console ROM you have to map it in before returning from your assembly program, or you die... But you can copy all of the ROM to RAM and then for example modify the interrupt vectors if you want to do something with the TMS 9901, for example. If works fine to use the RAM over the console ROM for some buffer storage. Enable, store, disable or enable, read, disable. The DSR space complicate things further if you, like @Vorticon want's to use SAMS together with Pascal, as the p-code card occupies this space too.
  5. Yes, it does. The instructions that have byte variants all read before write, just because that was easiest when the logic in the CPU was designed. But a Load Immediate doesn't read the register first, before it stores a value there, as there is no Load Immediate Byte version. If you check the number of memory accesses by MOV and MOVB you'll see that they are the same, four. Read instruction, read destination, read source, write destination.
  6. I see. Yes, my own memory expansion, which can show up anywhere in the address space, is indeed installed by modifications inside the console. The p-system uses the DSR space itself almost always. My feeling is that the p-system is easiest to expand with a RAMdisk.
  7. When I've used extra memory for the p-system I've used cartridge space addresses, 6000-7FFFH, since they aren't used at all by the p-system. Can you map SAMS to present memory there, or is it limited to show it at the normal memory expansion addresses, 2000-3FFFH and A000-FFFFH?
  8. The difference between new and varnew is that with new, you allocate memory to hold a pre-declared type. With varnew you specify the size of the variable at that moment. In both cases you get a pointer to the beginning of the variable. If the area you are requesting is reasonable in size, you can just use varnew. If you, on the other hand, are interested in getting a buffer as large as conditions will permit, then you should check with varavail what you can get. Don't forget to list segments involved in system calls, if there are any. And your own program. Subtract a couple of hundred words for safety too. Note that sizeof lists the size in bytes but varnew and varavail work with words. Cauttion! You must use vardispose with the same size to return an allocated area! If you don't do that, or try to just dispose it, disaster will strike. If arrpoint is a pointer to ^vararray and buffer an integer, then you can do buffer := warnew(arrpoint, 100) to get an array with 100 words or 200 bytes. If the array is word-indexed you can use indexes in the range 0..99 inside the array. If you go to 100 or above you are accessing memory outside the array. Since the declared size is just one element range checking must be off. If buffer wasn't 100 after the call it failed.
  9. Depends on the procedure. If you are calling an external procedure then there's no requirement that a parameter must have a type declaration. If it's a Pascal procedure you need to send a pointer to the array and a size specification to your subroutine. When specifying the size you may have use for the sizeof function, which returns the size of the parameter. The unit is bytes. So sizeof(an integer) will return 2. Don't forget about the intrinsics moveleft, moveright and fillchar when handling variable size arrays. When creating variable size arrays you may also find varnew, varavail and vardispose useful. Depending on how you declare your pointer, you may also need to turn range checking off in the surbroutine. Use the directive (*$R-*). When having a variable length array it's rather common to declare it as an vararray = array[0..0] of integer. Then the compiler will know how to index words into the array, but you'll get a out of range error as soon as you try to index outside zero. You can use vararray = packed array[0..0] of char if you want to index by byte.
  10. And the other god invented the ability to have multiple workspaces.
  11. I've never worked with SAMS, but it looks like it's at 4000h, so yes, p-code had to turn off. You must save and restore R12 too. The PME uses R8-R15 in Pascalws.
  12. I agree. I would not use that Compare instruction for this purpose unless my available memory is -2 bytes.
  13. It autoincrements R2 twice, so the same as AI R2,4. Or INCT R2 INCT R2. But in one word of memory. Then it generates status bits you don't use, provided the purpose is just to increment R2 by 4.
  14. Well, the most important thing is that we discuss. If we have different opinions it's in a way just better, because it puts light on the fact that depending on what you want to do, you can rate the usefulness of different tools differently. I didn't have the same point of view when I created a sorting routine which can sort a thousand integers in less than half a second, compared to when I did support for Extended BASIC to store a large number of text strings using the memory image format on cassette tape. So when (if) somebody write AI 2 I'll remark that INCT is faster, but AI 4 is better than INCT INCT. That's not to argue, it's just to show there is a different way.
  15. Of course a computationally intense game is sensitive to microseconds. The aren't the general case, though. If you write assembly support for Extended BASIC to do something that can't be done in BASIC alone, then even a full second may not be important. Very few instructions are completed in 10 cycles, so yes, quite a lot of cycles are used even for the simplest of them. That's why adding a few more cycles to use a more "fancy" addressing mode is better than accomplishing it in a different way. Finally, everything I write is my opinion. Frequently I also explain why. Which gives you all you need to make a more informed decision yourself. Myself, I don't use BLWP very often, mainly BL. I use BLWP when I feel it makes things better.
×
×
  • Create New...