Jump to content
IGNORED

SPECTRA2 development thread


retroclouds

Recommended Posts

GPL Gate

 

ok, I've been thinking about how to call the GPL interpreter from ROM space without having 32K memory expansion.

I want to have a gate into GPL from my spectra2 library. I'm still not certain if it's even worth the effort.

Actually I was mainly interested in the GPL COINC instruction (Sprite/tile colission detection).

But it seems you can only have your mapping tables in GROM so that won't really help me now.

Since this is all about having fun, I thought what the heck.

 

EDIT: I now have an own thread for the GPL Gate here.

Link to comment
Share on other sites

  • 2 weeks later...

scratch-pad memory usage (update 3)

 

 

I came up with some small modifications to the memory setup again.

For storing the spectra2 configuration flags, I've decided to use a register in favour of a memory location.

At the same time I'm moving the cursor YX position from that register into the freed memory location.

 

Reason for this change is that bit flags need to be tested against a register anyway. So I'm now saving a "MOV" operation.

 

I also moved the virtual game keyboard flags (E) from a register into a memory location. Wait a minute, didn't I just did

the exact opposite thing for the configuration flags? Yes, that's true. The thing is that I need a free register for storing

other more important flags. See the updated register usage.

 

The decision of what goes into a register or memory location, depends on what will be used most often and where (at various

code spots, ...)

 

 

Here's the new memory layout:

 

spectra2_scrpad_memlayout_190910.png

 

A) Register workspace

That's obvious right? On the TMS9900 CPU we need a workspace in memory to hold the 16 registers.

 

B) Address of timer table

We can now have multiple timer tables and the timer table can also be relocated. This offers more flexibility compared to the original

SPECTRA implementation where we only had a fixed address.

 

C) Address of sound table (tune)

The built-in sound player will be compatible with the ISR sound format. The tune can either be in VDP memory or ROM/RAM.

This is controlled by one of the bits in (D).

 

D) Cursor YX position

This is new in spectra
2
. We'll have some functions you can use to put tiles & text at specific coordinates

without you having to calculate each individual position.

 

E) Virtual game keyboard flags or keycodes

Already had the concept of a virtual game keyboard in SPECTRA
1
.

The idea is that we have a keyboard (including mapping to joysticks) and each bit represents a game key.

Most likely there will be an additional keyboard scan routine that can hold the typed key and a status flag.

 

F) Loop code + return from stack

This is new in SPECTRA2. It contains some machine code that is copied from ROM on library startup.

We can easily modify the machine code during runtime by overwriting some of the opcodes.

 

 

 

register usage (update 1)

 

I've got some changes to the register usage. Here are the latest updates:

 

!important!

There is a comprehensive set of equates available for addressing all of the below registers. It is strongly advised you use these equates where possible.

It'll allow register reorganization without you having to modify your program big time.

There are also equates available for accessing the high/low bytes of any of the mentioned registers.

 

 

registers       Purpose				
=========	============================================================
R0-R3      A    General purpose registers
R4-R7      B    Temporary registers
R8         C    Return stack and data stack pointer
R9         D    Address of return routine (M3POPR)
R10        E    Highest slot in use + Timer counter
R11        F    Subroutine return address
R12        G    SPECTRA2 configuration register
R13        H    Copy of VDP status byte and internal counter for sound player
R14        I    Copy of VDP write-only register #0 and #1
R15        J    VDP write address
=============================================================================

 

A) General purpose registers (R0-R3)

You can use the registers R0-R3 in your subroutines without any worry. spectra2 will not affect those registers.

 

 

B) Temporary registers (R4-R7)

These registers can be used for storing temporary values. You have to consider that they likely will be overwritten if you

call any of the spectra2 routines. So, it's a good idea to store register values on the stack or in R0-R3 before

calling a routine.

Please use the TMP0..TMP3 equates instead of R4-R7. The registers may be reorganized at a later time. But you are safe if you use TMP0..TMP3

 

C) Stack pointer (R8)

Pointer to both subroutine return stack and data stack. The stack pointer is set by the spectra2 initialisation routine.

For debugging purposes you could set the data stack equate to another register, e.g. R7

 

 

D) Address of return routine (R9)

The address is is set by the spectra2 initialisation routine. It points to the M3POPR machine code in scratch-pad memory.

For exiting a nested subroutine a "B *R9" is to be used.

Benefit: opcode size is only 2 bytes instead of 6 bytes when using "B @>xxxx". Will also be used when a return accross ROM memory banks is required.

 

 

E) Highest slot in use & internal counter for timers (R10)

The high byte of R10 keeps track of the highest slot used in the timer table.

The low byte of R10 is the timer tick counter and is updated every 1/50th or 1/60th of a second.

 

 

F) Subroutine return address (R11)

Same use as in Editor/Assembler. Contains the return address when doing "BL xxxx"

 

 

G) SPECTRA2 configuration register

Flags for controlling and checking various features of the library and your TI-99/4A console.

 

 

H) Copy of VDP status register and internal counter for sound list (R13)

The high byte of R13 contains a copy of the VDP status register. This byte is automatically updated by the timer manager.

The low byte of R13 contains an internal counter used by the sound player.

 

 

I) Copy of VDP register #0 and VDP register #1 bytes(R14)

This is new in spectra2. In SPECTRA1 a copy of the values in VDP write-only registers 0-7 was present in scratch-pad RAM.

To save memory, this feature was rejected in SPECTRA2. It's now returning but only for VDP write-only registers 0-1 as these control

most of the features of the VDP.

 

 

J) VDP write address (R15)

Contains the address of the VDP data window. The address is set by the spectra2 initialisation routine.

This register is heavily used by the built-in functions responsible for VDP communication.

Edited by retroclouds
Link to comment
Share on other sites

Configuration register

 

The configuration register will be used to set/check various options of the spectra2 environment and the TI-99/4A machine it runs on.

 

Here's an overview:

 

bit 15	Sound player tune source	1=ROM/RAM	0=VDP MEMORY
bit 14	<<free>>
bit 13	<<free>>
bit 12	Keyboard mode			1=real		0=virtual
bit 11	<<free>
bit 10	Timer has hyperthread 		1=yes		0=no	
bit 9   <<free>
bit 8   <<free>
bit 7   <<free>
bit 6   <<free>
bit 5   <<free>
bit 4   <<free>
bit 3   V2.2 console                    1=yes       	0=no
bit 2   Speech synth present            1=yes       	0=no
bit 1	VDP9918 PAL version             1=yes(50)   	0=no(60)
bit 0	32K memory expansion		1=yes		0=no

 

The flags 0-3 will be automatically set when the kernel is initialized.

You can use flags 8-15 to control several spectra2 options while the kernel is running.

Link to comment
Share on other sites

Filip... I tried to access your most recent SPECTRA2 documents on ninerpedia but couldn't seem to view them. I am experiencing a bit of web difficulty but I can see other sites. Can you post a file here?

 

Owen, perhaps the site was down for a short period. Just tried and it works now.

Also did some quick updates. Unfortunately my documentation is lagging behind again.

I've done quite some changes, so I really should be doing some documentation updates now.

Link to comment
Share on other sites

Configuration register (update 1)

 

Some adjustment to the config flags. Here's the current overview:

 

bit 15	Sound player: Tune source            1=ROM/RAM	     0=VDP MEMORY
bit 14	Sound player: Loop tune              1=yes           0=no
bit 13	Sound player: on                     1=yes           0=no (or pause)
bit 12	ASM: Motion Table source 	     1=ROM/RAM       0=VDP MEMORY
bit 11	ASM: Automatic Sprite Motion on      1=yes           0=no
bit 10	Timer has fast thread 	 	     1=yes	     0=no	
bit 9   <<free>
bit 8   <<free>
bit 7   <<free>
bit 6   <<free>
bit 5   <<free>
bit 4   <<free>
bit 3   V2.2 console                         1=yes           0=no
bit 2   Speech synth present                 1=yes           0=no
bit 1	VDP9918 PAL version                  1=yes(50)       0=no(60)
bit 0	32K memory expansion		     1=yes	     0=no

 

The flags 0-3 will be automatically set when the kernel is initialized.

You can use flags 8-15 to control several spectra2 options while the kernel is running.

 

Bit 13-15 are used to control the sound player. The sound player uses 4 bytes of scratchpad CPU memory.

If bit 13=0 you can use these 4 bytes for other purposes, even when the player code is running.

Notice bit 11. I'm planning on having a routine for automatic sprite motion.

The motion table can be either in VRAM or RAM. I'll also need a pointer in scratchpad memory pointing to the table.

The pointer will be stored next to the pointer for the sound list. If automatic sprite motion isn't used you'll be

able to use these 2 bytes for other purposes as well.

 

I really have to update my scratchpad memory map.

Edited by retroclouds
Link to comment
Share on other sites

This is coming along nicely. :) I am amazed by how much you can cram into such a small bit of RAM!!!! Truly,

economy of space on the TI has come to it's pinnacle with SPECTRA2. I'm itching to get the full docs and package and start working!!! :)

 

Thanks. A major difference compared to my first trial with SPECTRA1, is that I'm making extensive use

of the register space and at the same I'm reducing stack usage a lot by avoiding push/pop where I can.

I pretty much completed the feature list for the first release. There is still a lot to do, but we're getting there :D

Link to comment
Share on other sites

Here are my thoughts in relation to 8K+ game development and my Strawberry cartridge output.

 

Sound. I think it's pretty essential to game development to have independent control of music and soundeffects (also soundeffects like lasers and explosions occurring at the same time or overlapping). I'd definitely go for 3 sources, but 2 would be fine too. As long as Strawberry tries to cope with TI Basic, one source is fine, but there are plans for easy bulk loads of graphics, color, maps, arrays, sound, music and speech.

 

As for game development I'd rather control the sprites myself. Collision detection, when, where, how and why is pretty individual as I see it. I might even go so far as not supporting automotion (as we know it) with Strawberry.

 

Timers. I think I understand the benefits of threading. I think I would do fine with the "old" game loops and occasional spreading of task over frames. Like with my "Secret Scroll" demo, when I prepare the scroll of the entire screen over 8 frames. Classic99 doesn't run this very smooth. Win994a runs pretty smooth. MESS can be made to run smooth (synchronizing things). I guess a timer could count to 8 and do the different parts. Also I guess your system supports some kind of prioritizing. Turning things on and off are also nice. I usually do that using control bits/variables.

 

The other bits are very nice to have, but did you consider methods returning the state instead. Then you wouldn't need allocate ScrathPad. If I'm "already running" on a V2.2, then fine, but I wouldn't use the information. Speech is probably the most useful. Speech routines could return CPU if not attached. With Speech and 32K one could quit if not present, or ask nicely for the devices to be attached(/selected). I don't see myself doing something I wouldn't do just because the 32K is available. I mean, I've already coded what I want with either ScratchPad only or 32K in mind.

 

Generally I don't care for GPL and/or disk operations. I think they tend to mess things up a bit. I feel I haven't even begun to explore within the 8K limit, and since 64K and 256K bankswitching are becoming available, and maybe soon even GROM as placeholder for further data, and all in a true to original design/console style, - well, then I don't "have time to look back" (at GPL or disk). You know you have to concentrate/know your niche sometimes.

 

Sorry if any of this sounds negative. It's only supposed to be constructive input. The decisions with Spectra are yours. Also, I am of course putting these things forward since I could be interested in using Spectra with both game development, demos and Strawberry.

 

I know Mark has custom speech running on the interrupt, and I've glanced his code, and failed somewhat at my previous attempts. Would be nice if you would add routines for dealing with interrupt driven speech.

 

Does the assembler only incorporate Spectra routines that are referenced in the user code ? Or what assembler are you using ?

 

Take care.

 

:cool:

Edited by sometimes99er
Link to comment
Share on other sites

Thanks for your feedback. I really do appreciate it. First of all, it's not sounding negative so no worries :)

 

Well, due to the fact that my documentation is lagging behind a bit and also because I didn't release anything yet,

there might be some questions on what spectra2 will be.

 

I have a pretty clear picture of what I want spectra2 to become. So let me go through the details.

 

Basically spectra2 will act like a miniature OS for the unexpanded TI-99/4A. It's specifically designed

for running new games from the cartridge space with only having 256 bytes of scratch-pad memory to your disposal.

 

What it definitely will not be, is a collection of high-level routines for things as pixel scrolling, super duper graphic effects, etc.

 

As mentioned before, the thing is that such high-level routines abstract too much and also put too many

constraints on the developer. I'll leave it up to the imagination of the developer for implementing such routines :)

 

Spectra2 concentrates on some of the low level stuff and also provides a program structure

you can use in your games. In other words, you don't have to start from scratch.

 

 

Utility

* Bank-switching routine

* random generator

* ...

 

I/O low level

* Routines for copying memory: CPU memory<->VDP memory, GROM->VDP memory, GROM->CPU memory, etc.

* RLE decompression to CPU memory, VDP memory

* Implementation of a "virtual game keyboard". Basically a routine that scans the keyboard matrix and does the required mapping on a virtual game keyboard. That way you for example do not specifically have to check if joystick 1 was moved left or key 'S' was pressed.

 

Timers

* Scheduler for running "threads" synchronized by the VDP interrupt. A very important part of the library.

I see this more as a design pattern really.

* Possiblity to run isolated threads outside the VDP memory window. This is meant for tasks that do not need any VRAM access.

e.g. do calculations, speech, ...

 

Graphics

* Possibility to load a video mode table

* Dispaying tiles in a box, show text at certain position, ...

* Support for multiple VDP PNT base addresses.

* Sprite Automation support

* Collision detection

 

Sound & speech

* A sound player with a sound format that is compatible to the ISR sound player.

It currently supports sounds lists stored in ROM/RAM and VRAM. With the recent hardware development, I am seriously

considering adding GROM as sound source.

 

* Speech player with support for data stored in CPU memory, GROM. Not sure if playing from VDP memory would be possible

Still have to investigate on that.

 

 

Regarding to your remarks. I think we aren't that far apart ;)

Myelf I'm the kind of developer that hardly uses any libraries at all, unless I write them myself.

It's kinda hard to find the right balance of how far one has to go in the support functions.

If you want full controll, then yes it's best to handle everything yourself.

At the same time for new TMS9900 assembly developers having such functions is indeed a help.

 

That is why I spent quite some time thinking how I can offer best of both worlds.

By that I mean if you don't want to use a function, then it shouldn't clutter memory or take (too much) ROM memory.

Also I try having the same calling convention in all my subroutines.

This means I can either call a function with DATA parameter or pass parameters via registers.

 

As far as GPL is concerned. I have given that some more thought this week and I have decided that the functionality will

not be included in the default runtime library. It's putting too many constraints on scratch-pad memory

for being useful. I'm not dumping the idea, because with the GROM support in development one could write his own

GPL program for doing basic program setup, etc. The code is there, so I'll probably wrap it in an optional library.

 

As far as disk access is concerned; If all turns out well I might get some help from someone who is very talented in

that area. I'm not interested in floppy disk access. But with all those CF7+ and nanopebs floating arround it would

be cool to have some support for it.

You have a good point about targetting your audience, e.g. why would I do something differently just because I have 32K

memory to my disposal. Perhaps we'll see a few of the flags go, in favour of other control flags ;)

 

The idea for speech, is that you run the speech player as a thread. This is the same way I've implemented the sound player.

 

Regarding the assembler; I'm currently still using winasm as cross assembler. I've started working on "booster", my custom assembler.

But that project has to wait until spectra2 is done.

Link to comment
Share on other sites

Here's a minimal example for a thread.

The example shows a blinking "Hello World" on the screen.

 

 

********@*****@*********************@**************************
       AORG  >6000
*--------------------------------------------------------------
* Cartridge header
*--------------------------------------------------------------
GRMHDR  BYTE  >AA,1,1,0,0,0
       DATA  PROG
       BYTE  0,0,0,0,0,0,0,0
PROG    DATA  0
       DATA  KERNEL
HW      BYTE  12
       TEXT  'HELLO WORLD!'
*--------------------------------------------------------------
* Include required files
*--------------------------------------------------------------
       COPY  "F:\Projekte\spectra2\tms9900\runlib.a99"
***************************************************************
* Main 
********@*****@*********************@**************************
MAIN    BL    @FILV
       DATA  >0380,>F0,16          ; Set color table
       BL    @LDFONT
       DATA  >900                  ; Load title screen font
       LI    R0,>8370
       MOV   R0,@WTIMER            ; Our timer table
       BL    @MKSLOT
       DATA  >000F,BLINK,0         ; thread in slot 0 must run every 15 ticks
       MOVB  @BDIG1,@>8369
       B     @TMGR                 ; Run thread scheduler 
***************************************************************
* Thread
********@*****@*********************@**************************        
BLINK   MOV   R11,R0                ; Save
       NEG   @>8368
       JLT   BLIN2
BLIN1   BL    @PUTYX
       DATA  >050A,HW              ; Show "Hello World!" message
       JMP   BLIN3
BLIN2   BL    @HCHAR
       BYTE  >05,>0A,32,12         ; white space x 
BLIN3   MOV   R0,R11                ; Restore
       B     *R11        
       END

 

Here's the 8K rom image hw.zip

Comes with no warranties, I only tried it in classic99 :D

Link to comment
Share on other sites

Thanks for feedback.

 

I can't get the rom image to work. Nothing shows up on the menu selection screen. - I don't think it's this, but sure you're not generally missing an EVEN after the TEXT ?

 

Regarding "outside the VDP memory window". You're not saying that the CPU can't access the VDP outside this window ? (see post #24)

 

:)

Link to comment
Share on other sites

Thanks for feedback.

 

I can't get the rom image to work. Nothing shows up on the menu selection screen. - I don't think it's this, but sure you're not generally missing an EVEN after the TEXT ?

 

Regarding "outside the VDP memory window". You're not saying that the CPU can't access the VDP outside this window ? (see post #24)

 

:)

 

ok, it took me a moment to figure out why this didn't work in MESS. The problem is not the ROM image itself.

The problem is that the filename of the rom image in the rpk file is "invalid". I created a layout.xml with the below definition and it didn't work.

 

<?xml version="1.0" encoding="utf-8"?>
<romset version="1.0">
  <resources>
     <rom id="romimage1" file="hw.bin"/>
  </resources>
  <configuration>
     <pcb type="standard">
        <socket id="rom_socket" uses="romimage1"/>
     </pcb>
  </configuration>
</romset>

 

The strange thing is that I checked the ROM area at >6000 using the memory editor of the MESS debugger and I could see my program was there.

However the TI-99/4A could not find it. I just renamed the rom image file to hwc.bin and changed the layout.xml accordingly, et voila :)

Still, I think that's a bug in MESS. It should fully rely on the name as specified in the rom tag of the XML.

I've updated my zip file accordingly.

Edited by retroclouds
Link to comment
Share on other sites

The strange thing is that I checked the ROM area at >6000 using the memory editor of the MESS debugger and I could see my program was there.

However the TI-99/4A could not find it. I just renamed the rom image file to hwc.bin and changed the layout.xml accordingly.

Yeah, that's strange. The new file format for MESS shouldn't care about the naming of the files (other than the rpk). It also used to crash when I supplied a *c.bin after then change to rpk, but I think Michael Zapf is allowing them again.

Link to comment
Share on other sites

scratch-pad memory usage (update 4)

 

I did some changes to the memory layout today. I thought that I should have everything stabilized by now.

That's true for the most part, but some modifications were necessary. So let's take a closer look.

 

spectra2_scrpad_memlayout_061010.png

 

A) Register workspace

That's obvious right? On the TMS9900 CPU we need a workspace in memory to hold the 16 registers.

 

B) Loop code

This is new in SPECTRA2. It contains some machine code that is copied from ROM on library startup.

We can easily modify the machine code during runtime by overwriting some of the opcodes.

I dropped the part that is responsible for returning from the stack. This saves 4 bytes.

 

C) Address of timer table

We can now have multiple timer tables and the timer table can also be relocated. This offers more flexibility compared to the original

SPECTRA implementation where we only had a fixed address.

 

D) PNT base address
**new**

This is new in spectra
2
. It contains the base address of the pattern name table.

We can set the value here and then use it in several derived calculations.

 

E) Cursor YX position

This is new in spectra
2
. We'll have some functions you can use to put tiles & text at specific coordinates

without you having to calculate each individual position.

 

F) Virtual game keyboard flags or keycodes

Already had the concept of a virtual game keyboard in SPECTRA
1
.

The idea is that we have a keyboard (including mapping to joysticks) and each bit represents a game key.

Most likely there will be an additional keyboard scan routine that can hold the typed key and a status flag.

 

G) Sound player - Address of sound table (tune)

The built-in sound player will be compatible with the ISR sound format. The tune can either be in VDP memory or ROM/RAM.

This is controlled by one of the bits in (D).

 

H) Sound player - temporary use
**new**

2 bytes required while running the sound player. By using these bytes I enhance the functionality of the sound player.

It's now possible to loop a tune or chain multiple tunes.

 

The memory locations are now aligned in such way that they can be reused if some of the functions aren't used

(e.g. keyboard scanning or sound player).

 

 

 

register usage (update 2)

 

Yes, I'm changing register allocation again. Here are the latest updates.

 

!important!

There is a comprehensive set of equates available for addressing all of the below registers. It is strongly advised you use these equates where possible.

It'll allow register reorganization without you having to modify your program big time.

There are also equates available for accessing the high/low bytes of any of the mentioned registers.

 

 

registers       Purpose				
=========	============================================================
R0-R3      A    General purpose registers
R4-R8      B    Temporary registers
R9         C    Stack pointer
R10        E    Highest slot in use + Timer counter
R11        F    Subroutine return address
R12        G    SPECTRA2 configuration register
R13        H    Copy of VDP status byte and internal counter for sound player
R14        I    Copy of VDP write-only register #0 and #1
R15        J    VDP write address
=============================================================================

 

A) General purpose registers (R0-R3)

You can use the registers R0-R3 in your subroutines without any worry. spectra2 will not affect those registers.

 

 

B) Temporary registers (R4-R8)

These registers can be used for storing temporary values. You have to consider that they likely will be overwritten if you

call any of the spectra2 routines. So, it's a good idea to store register values on the stack or in R0-R3 before

calling a routine.

Please use the TMP0..TMP4 equates instead of R4-R8. The registers may be reorganized at a later time. But you are safe if you use TMP0..TMP4

 

 

C) Stack pointer (R9)

The stack pointer is set by the spectra2 initialisation routine.

 

 

D) Highest slot in use & internal counter for timers (R10)

The high byte of R10 keeps track of the highest slot used in the timer table.

The low byte of R10 is the timer tick counter and is updated every 1/50th or 1/60th of a second.

 

 

E) Subroutine return address (R11)

Same use as in Editor/Assembler. Contains the return address when doing "BL xxxx"

 

 

F) SPECTRA2 configuration register

Flags for controlling and checking various features of the library and your TI-99/4A console.

 

 

G) Copy of VDP status register and internal counter for sound list (R13)

The high byte of R13 contains a copy of the VDP status register. This byte is automatically updated by the timer manager.

The low byte of R13 contains an internal counter used by the sound player.

 

 

H) Copy of VDP register #0 and VDP register #1 bytes(R14)

This is new in spectra2. In SPECTRA1 a copy of the values in VDP write-only registers 0-7 was present in scratch-pad RAM.

To save memory, this feature was rejected in SPECTRA2. It's now returning but only for VDP write-only registers 0-1 as these control most of the features of the VDP.

 

 

I) VDP write address (R15)

Contains the address of the VDP data window. The address is set by the spectra2 initialisation routine.

This register is heavily used by the built-in functions responsible for VDP communication.

Link to comment
Share on other sites

The main modification done to the register usage, is basically adding an additional temporary register TMP4 (R8).

I shifted the stack pointer from R8 to R9 while dropping the original usage of R9 (address of return routine).

We now have the temporary register TMP4 to our disposal and this further reduces the need for stack manipulation.

The goal is that the routines in spectra2 won't require any stack usage at all.

 

You'll also notice that I grouped most of the memory variables into "memory area 2".

This means that if you are not using stuff like the virtual keyboard or built-in sound player, you'll have 12 additional bytes to your disposal.

 

Current status of the project is that I have the virtual keyboard working, but some further debugging will be necessary.

Next up are speech synthesizer support and some pending utility routines. After that we should be ready for a first official release.

 

It's about time because I wanna go back to actual game development :)

Edited by retroclouds
Link to comment
Share on other sites

No auto-sprite movement! Say what ?!!

 

This morning I woke up and it was clear that I'm not gonna implement auto-sprite movement. There are several reasons for that.

Moving sprites in a linear way is not what I have in mind when I think about advanced games.

Sure, they're ok for Frogger style games (in that case I would go for a tile based solution instead of sprite based one though).

I also don't want to re-implement Extended Basic functionality, so I'll leave the moving of sprites to the developer.

 

The way it looks I'll be making some more changes to the memory layout again. If you go through the development thread, you'll notice there were a lot of changes to the memory layout lately. This layout is very important because after doing the initial release I can't change it much anymore. Also something that looks perfectly clear at one moment, makes you wonder just a few days or weeks later.

 

The memory allocation changes I have to do, are mainly related to the thread scheduler. In one of my earlier posts I mentioned that

R0-R3 will be available to the developer without having to worry that spectra2 messes with those registers.

Well the thread scheduler does exactly that. It means if you run anything as a thread and use R0-R3 you have to push/pop them to the stack.

As threads are a core concept of spectra2 and I don't want the push/pop overhead, I have to change the implementation of the thread scheduler, hence the memory changes.

 

All in all I'm pretty pleased with the results so far. I have been giving this project a lot of thought in the last few months.

It's like a big puzzle and I have to fit the pieces together in such way that the routines work in an efficient way in terms of memory and code size. The library may not use more than 64 bytes of scratchpad memory and 2000 bytes of ROM.

 

A few bytes of RAM could be spared by using some clever equates. I'm already using equates where possible. However in this case it's a tradeof. It would cost both flexibility and make it a lot harder for the developer to actually use the library.

I think I have found a good balance between memory requirements and flexibility.

For new developers it means they just include the "runlib.a99" file and are ready to start writing games that run from the cartridge space

with a built-in sound/speech player and virtual keyboard to your disposal.

Advanced programmers are still available to override core functionaly, by changing two pointers in scratchpad memory.

 

I've also decided that I won't be using any of the routines that are in the monitor OS. Reasons for that are the way scratchpad memory needs to be setup in order to do monitor calls. The only thing I will be accessing from the (g)roms in the TI-99/4A is the character set data.

 

I've also still have to implement the trampoline code, this will also take a few bytes of scratch-pad memory in "memory area 2" (the optional memory ara). It means if you're not using bank-switching you'll have that memory to your disposal as well.

 

That's it for now folks ;)

Link to comment
Share on other sites

A few bytes of RAM could be spared by using some clever equates. I'm already using equates where possible.

 

Indeed!

 

TurboForth actually refers to the same memory locations under different names in some parts of the code. This is because, under some circumstances, routines can share memory addresses (say, for temporary storage) without interfering with each other. For example, the Editor stores its X & Y coordinates in the same place as the cursor coordinates for the command line system, since, upon exit from the editor, the screen is cleared, zeroing the X & Y for the command line. Thus, they can happily share the same memory address.

 

It's possible to refer to the same memory address under a different name:

 

EditX
CmdX  BSS 2  ; reserve two bytes for EditorX and Command Line X coordinates

Simple as that. Obviously, this takes no extra code space, and you get the added benefit of being able to refer to a memory location in it's proper context at the appropriate points in your code.

Link to comment
Share on other sites

How about dropping the VDP shadow registers and functions, and simply supply a good bunch of equates ? Wouldn't it save a few bytes both in RAM and ROM ?

Thanks. Yes, it would save 8 bytes in RAM. On the other hand I could lose some of the flexibility for the subroutines I have in mind.

Considering that we only have 256 bytes to play with, I'd say being able to save 8 bytes is a lot.

Excellent. ;)

 

And I won't mention more than one sound source anymore - I guess it could potentially destroy your beauty sleep. :D

Link to comment
Share on other sites

If the game developer decides not to use a stack, then he can use the stack pointer(R9) as temporary register TMP5.

At this time I only have 1 remaining spectra2 routine that makes use of the stack, and it can easily be rewritten.

I've almost finished doing all required modifications to the thread scheduler. I'm quite pleased with it so far.

 

Next up are (in no particular order): speech synthesizer, bank-switching & utility, random.

 

I now have a pretty good picture of what will be part of the spectra2 release.

It means I can start working on the documentation soon.

Link to comment
Share on other sites

Excellent! Did you do also implement speaking words from the synths built in ROM? That takes a bit more work...

 

That's the one I am going to work on first, as it's the harder of the two. Well, it's not that it's harder - just more to it, that's all!

Link to comment
Share on other sites

Excellent! Did you do also implement speaking words from the synths built in ROM? That takes a bit more work...

 

That's the one I am going to work on first, as it's the harder of the two. Well, it's not that it's harder - just more to it, that's all!

 

Didn't work on that yet. Speaking words from the built-in ROM is definetely on my list for the first release though. I really want to have that available.

The thing is that I need to work on sound & speech development at home. I don't wanna bother people

with garbled speech or crashing sounds at work (lunch break) or in the train :)

 

Most likely I'll be doing work on some small utility functions first :)

Link to comment
Share on other sites

Here's a little speech demo I did. I recorded my own voice using Audacity and then followed Marks' instructions to generate the required LPC data with QBOX.

Didn't spend too much time on it and it sounds rather rough :lol:

Then spectra2 was used for playing the speech sample.

 

 

********@*****@*********************@**************************
       AORG  >6000
*--------------------------------------------------------------
* Cartridge header
*--------------------------------------------------------------
GRMHDR  BYTE  >AA,1,1,0,0,0
       DATA  PROG
       BYTE  0,0,0,0,0,0,0,0
PROG    DATA  0
       DATA  RUNLIB
HW      BYTE  12
       TEXT  'HELLO WORLD!'
*--------------------------------------------------------------
* Include required files
*--------------------------------------------------------------
       COPY  "D:\Projekte\spectra2\tms9900\runlib.a99"
***************************************************************
* Main 
********@*****@*********************@**************************
MAIN    BL    @FILV
       DATA  >0380,>F0,16          ; Set color table
       BL    @LDFONT
       DATA  >900                  ; Load title screen font
       LI    R0,>8370
       MOV   R0,@WTITAB            ; Our timer table
       BL    @MKSLOT
       DATA  >000F,BLINK,0         ; Run thread every 15 ticks
       BL    @SPPREP               ; 
       DATA  ROCK,SPOPT1           ; Speech player on / Speak external
       MOVB  @BDIG1,@>8369
       B     @TMGR                 ; Run scheduler 
***************************************************************
* Thread
********@*****@*********************@**************************        
BLINK   MOV   R11,R0                ; Save
       NEG   @>8368 
       JLT   BLIN2
BLIN1   BL    @PUTYX
       DATA  >0A0A,HW              ; Show "Hello World!" message
       JMP   BLIN3
BLIN2   BL    @HCHAR
       BYTE  >0A,>0A,32,12         ; white space x 
BLIN3   B     *R0                   ; Exit
ROCK    BYTE TALKON
       BYTE >00,>E0,>80,>E2,>3B,>13,>50,>DC,>64,>00,>AA,>E9,>3C,>69
       BYTE >53,>1B,>EE,>9E,>F8,>E4,>55,>4D,>BA,>75,>9A,>53,>54,>DD
       BYTE >65,>5E,>AD,>0F,>90,>6C,>45,>01,>AA,>CE,>08,>40,>15,>1D
       BYTE >01,>68,>AA,>3C,>00,>55,>97,>17,>20,>F9,>D6,>63,>67,>3B
       BYTE >61,>39,>49,>4F,>5A,>75,>65,>45,>66,>3D,>40,>B6,>ED,>0B
       BYTE >C8,>BA,>35,>01,>D9,>8C,>25,>A0,>9A,>F6,>00,>64,>37,>91
       BYTE >80,>18,>46,>8E,>9B,>5D,>87,>E5,>64,>39,>4E,>D1,>D5,>EE
       BYTE >DD,>EE,>00,>D9,>B5,>0F,>A0,>E8,>8A,>04,>14,>53,>11,>80
       BYTE >6A,>3A,>1C,>50,>7C,>FB,>F1,>8B,>99,>34,>EF,>24,>C7,>2D
       BYTE >B6,>53,>B3,>DB,>1C,>A7,>AA,>CA,>CA,>6C,>77,>80,>EC,>27
       BYTE >1A,>90,>6D,>67,>02,>B2,>9F,>74,>40,>89,>1B,>06,>C8,>6E
       BYTE >FC,>84,>55,>77,>99,>76,>9D,>E3,>57,>DD,>ED,>52,>75,>4E
       BYTE >55,>EC,>94,>79,>D5,>3E,>76,>53,>53,>A1,>13,>E7,>D8,>4D
       BYTE >F5,>B8,>55,>EA,>00,>54,>3D,>61,>80,>6C,>27,>15,>50,>54
       BYTE >B7,>00,>8A,>EE,>2A,>66,>13,>5D,>A9,>55,>FB,>D8,>55,>F7
       BYTE >98,>76,>DD,>63,>57,>55,>1D,>52,>55,>8E,>D9,>D4,>A6,>EB
       BYTE >34,>69,>40,>51,>13,>0E,>A8,>62,>CA,>00,>55,>6D,>08,>A0
       BYTE >C9,>CD,>14,>2C,>55,>BD,>EA,>49,>47,>52,>E5,>94,>47,>26
       BYTE >39,>6E,>D3,>D3,>E6,>59,>F7,>98,>55,>6F,>69,>54,>DD,>63
       BYTE >57,>37,>29,>D1,>71,>8F,>DD,>F5,>B4,>C9,>26,>59,>79,>57
       BYTE >DB,>E1,>D1,>7A,>F4,>5D,>4F,>9B,>D6,>92,>92,>2F,>E3,>5D
       BYTE >16,>6D,>92,>35,>64,>75,>49,>36,>71,>E6,>54,>39,>6D,>DE
       BYTE >B4,>99,>C5,>4E,>4A,>56,>9C,>63,>56,>33,>25,>D1,>4D,>8E
       BYTE >5B,>F4,>B4,>E4,>C4,>39,>5E,>D1,>D3,>E6,>5D,>E7,>78,>5D
       BYTE >4E,>05,>77,>5D,>07,>54,>31,>A1,>80,>AA,>36,>05,>50,>F9
       BYTE >25,>03,>AA,>E8,>20,>40,>91,>E5,>02,>88,>A9,>E4,>78,>55
       BYTE >4F,>99,>55,>DD,>E3,>35,>D5,>ED,>5A,>75,>8F,>57,>4D,>B7
       BYTE >FA,>D4,>3D,>5E,>55,>57,>1A,>1D,>F5,>B8,>55,>6D,>B9,>55
       BYTE >D5,>E3,>56,>33,>6D,>3A,>75,>8F,>5B,>ED,>94,>69,>D5,>3D
       BYTE >6E,>71,>53,>6A,>5D,>F7,>B8,>D5,>4C,>9B,>76,>D5,>E3,>55
       BYTE >3D,>ED,>56,>55,>8F,>57,>75,>77,>68,>57,>3D,>5E,>31,>53
       BYTE >61,>53,>F5,>78,>55,>75,>A7,>F6,>94,>E3,>55,>5D,>1B,>3A
       BYTE >55,>8F,>DB,>55,>76,>69,>35,>3D,>6E,>55,>35,>A1,>35,>E7
       BYTE >B8,>4D,>E5,>86,>D6,>94,>E3,>36,>95,>93,>9A,>53,>8E,>57
       BYTE >75,>4D,>58,>4D,>39,>5E,>D5,>DD,>EE,>3D,>FB,>78,>45,>4F
       BYTE >BB,>F7,>EC,>E3,>17,>B3,>65,>D1,>73,>8E,>5F,>CD,>B4,>E9
       BYTE >D4,>3D,>41,>B5,>DB,>66,>55,>F7,>04,>D5,>6D,>A9,>55,>DD
       BYTE >13,>56,>BB,>AD,>DE,>49,>4F,>58,>ED,>B4,>5A,>27,>3D,>51
       BYTE >D5,>5B,>E6,>5D,>F7,>C4,>D5,>6C,>69,>74,>D3,>93,>54,>73
       BYTE >A9,>5E,>4D,>4F,>52,>D5,>96,>7A,>27,>3D,>49,>D5,>97,>9A
       BYTE >95,>F4,>24,>D5,>6C,>9A,>67,>93,>93,>56,>B3,>69,>5E,>4D
       BYTE >4E,>5A,>DC,>B9,>45,>D5,>39,>59,>71,>E7,>1A,>D9,>E4,>E4
       BYTE >C5,>5C,>B8,>67,>9D,>93,>57,>79,>6E,>51,>95,>03,>90,>DC
       BYTE >8A,>00,>22,>2F,>21,>80,>93,>05,>CE,>1C,>72,>3C,>C5,>6C
       BYTE >07,>73,>E9,>4D,>0F,>95,>55,>CC,>A5,>B7,>DD,>DD,>8E,>01
       BYTE >2A,>75,>32,>C0,>E4,>29,>06,>18,>7A,>D4,>00,>53,>B7,>3B
       BYTE >60,>E8,>76,>07,>4C,>5D,>E9,>80,>A9,>32,>0C,>30,>55,>98
       BYTE >01,>96,>CE,>54,>C0,>70,>6D,>02,>E8,>C2,>99,>00,>95,>3B
       BYTE >11,>20,>51,>23,>50,>40,>57,>E1,>01,>98,>2A,>A2,>01,>53
       BYTE >67,>2C,>60,>69,>CF,>05,>6C,>1D,>35,>80,>25,>CB,>03,>B0
       BYTE >58,>B8,>03,>A6,>CC,>50,>C0,>10,>65,>02,>18,>C4,>EC,>04
       BYTE >CD,>A7,>9B,>6B,>97,>53,>34,>9F,>1A,>E6,>6D,>4E,>D6,>63
       BYTE >8B,>66,>26,>39,>7E,>8F,>45,>96,>B9,>BA,>01,>59,>9B,>06
       BYTE >20,>3B,>66,>03,>14,>C3,>A4,>80,>6A,>8D,>19,>50,>9D,>53
       BYTE >02,>6E,>F0,>68,>C0,>B2,>E5,>C7,>5C,>71,>C2,>CC,>64,>1F
       BYTE >6B,>E8,>54,>33,>53,>7C,>CC,>12,>43,>C3,>D9,>DD,>31,>4B
       BYTE >34,>F7,>E0,>2E,>27,>28,>29,>D3,>C5,>D7,>9E,>B0,>E8,>09
       BYTE >77,>DF,>7A,>CC,>A6,>26,>CC,>A3,>ED,>31,>9B,>E8,>90,>CA
       BYTE >35,>C7,>1C,>3A,>4B,>D5,>1A,>2F,>7B,>CA,>08,>57,>69,>D2
       BYTE >EC,>65,>B2,>CA,>C5,>4D,>B2,>86,>AA,>08,>F1,>B5,>C1,>EC
       BYTE >66,>3A,>4C,>9B,>86,>B0,>E9,>2E,>57,>6D,>5B,>80,>2D,>32
       BYTE >07,>30,>54,>DB,>29,>46,>E9,>30,>65,>37,>27,>EF,>2D,>C3
       BYTE >8D,>35,>9F,>AC,>F9,>08,>0D,>51,>7B,>B2,>66,>3D,>AD,>58
       BYTE >CB,>49,>9B,>F6,>D6,>24,>2F,>27,>AB,>D2,>DB,>92,>93,>9C
       BYTE >AC,>28,>EB,>2C,>AC,>75,>F2,>62,>64,>C7,>C1,>F5,>CA,>93
       BYTE >A9,>8D,>04,>2F,>AB,>88,>A6,>37,>0A,>62,>0F,>33,>29,>9F
       BYTE >18,>72,>B8,>CC,>68,>B2,>35,>25,>CF,>31,>53,>B0,>94,>90
       BYTE >3E,>C7,>AA,>51,>9D,>4B,>DA,>1F,>AB,>7B,>75,>49,>6D,>7B
       BYTE >AC,>E9,>25,>AC,>B4,>ED,>B1,>86,>D6,>96,>B4,>B5,>C7,>EA
       BYTE >CA,>5A,>22,>56,>1F,>BB,>0B,>1F,>55,>EF,>7A,>9C,>26,>A3
       BYTE >5D,>AC,>DB,>71,>9B,>F0,>0E,>D6,>AC,>C7,>2B,>3A,>5B,>44
       BYTE >BA,>9C,>A0,>9A,>4C,>31,>D5,>BA,>C2,>62,>23,>38,>C4,>E9
       BYTE >0A,>8B,>89,>A0,>52,>A7,>C7,>2F,>3E,>82,>8A,>DC,>1E,>B7
       BYTE >7A,>73,>6F,>EC,>72,>AC,>64,>33,>A2,>B4,>EF,>31,>BB,>9A
       BYTE >CA,>D0,>34,>C7,>EC,>6A,>C6,>C2,>B6,>1E,>AF,>CB,>6D,>8D
       BYTE >58,>7A,>8A,>A6,>A6,>34,>72,>E9,>C9,>AA,>99,>96,>A8,>75
       BYTE >C7,>AE,>A6,>46,>B2,>B7,>9E,>A4,>84,>0E,>A9,>68,>7D,>BC
       BYTE >1A,>36,>38,>22,>ED,>B0,>9A,>EC,>F6,>CA,>36,>CD,>EE,>BA
       BYTE >3A,>2C,>DA,>06,>A0,>71,>F5,>04,>4C,>AD,>56,>80,>E9,>3A
       BYTE >8F,>B9,>53,>47,>8A,>4A,>3E,>E6,>4A,>1D,>0A,>DA,>E4,>98
       BYTE >A3,>76,>20,>79,>E2,>63,>8E,>D6,>46,>1A,>69,>4F,>D0,>9B
       BYTE >AB,>78,>6C,>3D,>7E,>B5,>66,>1E,>BE,>F5,>78,>D5,>94,>07
       BYTE >5B,>DF,>93,>16,>51,>99,>21,>6B,>8F,>5B,>79,>95,>A6,>AC
       BYTE >3B,>49,>15,>93,>1A,>BA,>EE,>D8,>55,>6F,>9A,>C9,>BA,>63
       BYTE >17,>3B,>E9,>A2,>DB,>4E,>5C,>DC,>A6,>A9,>AE,>3B,>49,>55
       BYTE >93,>66,>DA,>EE,>24,>59,>4C,>AA,>FB,>BA,>93,>67,>DA,>93
       BYTE >C9,>4B,>56,>91,>D9,>B4,>85,>4E,>19,>76,>61,>55,>66,>52
       BYTE >67,>D8,>59,>54,>85,>71,>94,>65,>67,>51,>55,>8E,>75,>8E
       BYTE >99,>45,>55,>18,>2D,>3D,>45,>91,>D3,>1E,>34,>FB,>14,>55
       BYTE >74,>4B,>DA,>EC,>93,>4D,>1E,>23,>29,>4B,>4E,>DA,>55,>64
       BYTE >26,>AD,>3E,>69,>37,>99,>E9,>B4,>EA,>64,>5D,>4E,>4B,>CA
       BYTE >E2,>93,>37,>BD,>C3,>E1,>AB,>4F,>DE,>D4,>B4,>BA,>2D,>3E
       BYTE >79,>93,>DD,>EA,>B6,>EA,>64,>43,>D4,>48,>E8,>A2,>93,>77
       BYTE >51,>ED,>A1,>8B,>4E,>3E,>58,>8F,>BA,>CF,>39,>C5,>E4,>31
       BYTE >11,>7C,>FB,>94,>55,>4D,>9B,>FA,>AB,>53,>65,>3B,>AD,>92
       BYTE >8F,>4E,>9D,>C2,>16,>6B,>3D,>3E,>66,>76,>DB,>2C,>F9,>E4
       BYTE >98,>D1,>4F,>89,>F6,>9B,>63,>26,>33,>2D,>52,>CF,>8E,>9D
       BYTE >F4,>8C,>6A,>BC,>3B,>6E,>52,>33,>CA,>B9,>EE,>78,>49,>CD
       BYTE >28,>FB,>FA,>E3,>67,>DE,>6B,>64,>EB,>4E,>98,>F9,>AE,>A2
       BYTE >2D,>3D,>71,>E6,>BB,>8A,>B6,>F4,>C4,>99,>EF,>18,>DA,>DA
       BYTE >93,>64,>B1,>23,>18,>4B,>4E,>D2,>50,>4C,>09,>B7,>1D,>69
       BYTE >21,>DD,>01,>BE,>65,>64,>15,>4D,>06,>C4,>E6,>96,>55,>1A
       BYTE >95,>E0,>AB,>47,>DE,>85,>94,>73,>38,>6E,>45,>63,>E6,>26
       BYTE >6E,>37,>14,>89,>A6,>2B,>47,>DB,>96,>6D,>15,>2A,>EA,>B6
       BYTE >57,>BA,>54,>9A,>8A,>DB,>1B,>69,>95,>A5,>2E,>B5,>64,>A4
       BYTE >55,>86,>05,>D7,>92,>96,>35,>51,>1A,>1C,>8B,>5A,>3E,>79
       BYTE >58,>91,>37,>2A,>E5,>10,>A5,>89,>9E,>28,>E5,>43,>8E,>3A
       BYTE >79,>A2,>90,>4D,>19,>D2,>EC,>B6,>5C,>32,>54,>9A,>A3,>3B
       BYTE >22,>80,>A1,>EE,>00,>00,>00,>00,>00,>00,>00,>00,>00,>00
       BYTE >00,>00,>00,>00,>00,>00,>00,>F0     
       BYTE TALKOF 
       END

 

 

Here's the ROM image for classic99 and MESS.

Again this comes without warranties.

It was tested on classic99 and on a real TI-99/4A with speech synth.

 

hw.zip

  • Like 1
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...