Welcome, Guest. Please login or register.

Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Messages - JSP

Pages: [1] 2
Other topics / Re: Enterprise news in the Amiga Forever magazine
« on: 2019.November.15. 09:44:02 »
Aehm......... Right! I got the name mixed up with Enterprise Forever. :lol:


Other topics / Enterprise news in the Amiga Forever magazine
« on: 2019.November.14. 09:59:13 »
In case anyone is interested....

In the Amiga Forever magazine issue 141 just issued there is a section on games published on other platforms. On page 6 and 7 are evaluations of two Enterprise 128 games among the items in the section.

Nigel Mansell's Grand Prix



Here is a snapshot with the BASIC code.

I forgot to mention, that the program stops, if you press <ESC>.

A brief explanation of one of the features... The ability to reRUN the  program from within the program in one of two graphic resolutions, is based on using one of the system variables as a flag. System variable 28 manages the BIAS value. But since this value has no meaning with only 4 colours active, it can be set to any value, and will retain that value between multiple RUNs of the program. Then it is a matter  of simply scaling values horizontally.

Some of the procedures, like the event_handler, are not required for this specific program, but are introduced, so I can add features later on, managed by the event.flag variable. I have also used procedures to group code like in 'init_arrays', 'init_vpages' and 'init_vars'. This adds readability and structure to the program. All variables are explicitly declared at the start of the program. This is a good idea, when you use ZZZIP, as otherwise you may have problems with variables, that are initialized inside procedures. To improve speed, all things, that can be precalculated, are precalculated. The size of the visible displays are managed by the three constants vpage.x (start of display), vpage.wid (display width) and vpage.hgt (number of scan line blocks). These can be found in the INIT_VARS procedure. The main sprite is made from 2 x 3 bytes put together in 4 patterns.

When you run the program - have patience. It takes several seconds in BASIC to initialize everything, and the ship only moves once every three seconds :) Without ZZZIP it would all be rather useless.


Programming / Sprites and BASIC (with some help from ZZZIP)
« on: 2019.May.20. 16:42:40 »
A month or two ago I asked myself the question - can you make a reasonable 'sprite' based game in BASIC and then compiled with ZZZIP. To produce a satisfying result some requirements needed to be satisfied:

- Flicker free.
- Pixel precise collision check.
- Ability to move in front of or behind objects on the background.
- A reasonable frame rate (+10 fps)

In other words, similar features to what you would expect from a MC program - except for the frame rate. This is after all BASIC even if speed enhanced by being run through a compiler.

I included some other feature, that might be of interest, even if they are not essential.

- Restart (RUN) the program in more than one resolution dynamically.
- Stop the program if the sprite reaches the right border zone. This was so I could test the frame rate speed, which clocked in at about 155 frames in 14 secondes, or 11 FPS with a standard 4 MHz EP128 machine.

The controls are laid out as follows:

Cursor keys: Increase or decrease speed in four directions. 4 speed levels.
<1> RUN program in graphics mode 5, colour mode 1.
<2> RUN program in graphics mode 1, colour mode 1.
<3> Fly behind other objects on the display.
<4> Collide with other objects on the display.
<5> Fly in front of other objects on the display.

When the ship reaches the border it stops in that direction - except for the right border, where the program stops, and running time is displayed.

I use a three-buffer display. Two buffers for alternating the graphics and a third for collision check. The advantage is that I can draw in any of the four colours on the two first displays and yet be sure that if pixels of the ship overlaps the mask on the third display, it will trigger a collision, because the mask is all ones (made with colour 3), so BAND'ing the ship with the mask returns a value different from zero, if there is any overlap. Another advantage of this approach is that since I repaint foreground and background directly for any changes and do not use a generic CLEAR channel command, I can maintain a complex background.

Just load the demo image and START the program.

As you can see all of the targets listed, are fulfilled at about 11 FPS. So for some types of games you could use BASIC. Some kind of game, where you don't need 50 FPS. like a submarine simulator at the same level as the first Silent Service game from Microprose.

Unfortunately there are some limitations about BASIC that limits the number of frames, I can generate.

First of all I have to do a lot of extra calculations because each of the three video pages may have addresses crossing a 16 Kb border, and since I use SPOKE extensively, I need to calculate the addresses as well as the page for each byte I poke. In fact, it takes about three seconds per frame in BASIC without ZZZIP. Fortunately ZZZIP can speed calculation and SPOKES up by at least a factor 50, since the operations are close to their MC code equivalents. I am sure a way can be found to make sure that memory used for each video page all stays within a 16 Kb page, and this would save a lot of calculations. Some other day perhaps....Suggestions are welcome.

BASIC only supports 2-dimensional arrays. This is a problem, because if I want to write routines, that can handle multiple objects flying around, I really need 3 dimensions, because I have to include the objects number as one of the parameters. It is possible to 'flatten' two or more dimensions into one dimension, but it quickly gets rather complicated, when you have to maintain meta-data about how data is stored to be able to work with the data. This also makes it hard to create standard routines, that can be used as a library for others wanting to create games using the routines as a backbone.

A third issue is the limitations causes by an integer compiler like ZZZIP, where addresses are limited in scope to 15 bit and where you only have integers available.

Still, I think the result proves, that it is possible to make some simple animations at a reasonable speed including such features as collision-check and depth-sensitivity.


VIDEO: / Re: GraCha Sprite System
« on: 2019.April.23. 13:47:29 »

Yes, thanks to the support in BASIC for the NICK chip and its ability to have multiple video pages, you can do a buffered display to avoid flickering. This is still kind of slow in pure BASIC, but practical with the aid of ZZZIP because spokes and speeks execute so darn fast.

The first program used attribute mode, which is not the best choice speedwise. I am currently testing a similar approach using LORES or HIRES pixel mode. And it looks very promising. A pure ZZZIP compiled plot test of an object made of 3 scan-lines reached at least 50 FPS. But of course that is without any game logic like testing for keyboard etc.

Maybe I should start another topic, since this appears to be of interest to others, and further discussion will sort of hi-jack the original topic, that we are hooked in to, which is not polite :)


VIDEO: / Re: GraCha Sprite System
« on: 2019.April.19. 20:24:41 »

Well, the code was a sort of 'proof of concept' to test if it is possible to make reasonable sprites in BASIC, and within limits this seems to be the case.

The main trick for speeding up the code is to avoid arrays if possible and to precalculate everything once before using the results in the main loop and plot routine. Common sense really, and it improves the speed by about 50%! You also have to rewrite a few address specifications to get them to work with ZZZIP. All peeking and poking is done using speek/spoke. This minimizes the limitations from ZZZIPs integer code and results in very fast code in ZZZIP.

The code around line 7000 is just there in case you want to implement some code to react to specific events. In the code example below, there are no such events, but you might implement a collision check or whatever, and put it there.

Anyway, here is the BASIC code, if you feel like trying it out.


    1 PROGRAM "spr_test.bas"
    2 !
    5 TEXT 80
   10 NUMERIC GFX1(1 TO 9) , OFFX1 (1 TO 9,0 TO 8) , OFFX2 (1 TO 9,0 TO 8)
   65 STRING T$*1,ESC$*1,LEFT$*1,RIGHT$*1,UP$*1,DOWN$*1,T1$
   81 LET OX=1:LET OY=1
   99 !
  998 LET T1$=TIME$
  999 !
 1000 DO
 1010   LET T$=INKEY$
 1012   IF T$<>"" THEN
 1015     SELECT T$
 1020     CASE ESC$
 1021       PRINT T1$,TIME$
 1025       EXIT DO
 1030     CASE LEFT$
 1035       LET ODX=MAX(ODX-1,-SP)
 1040     CASE RIGHT$
 1045       LET ODX=MIN(ODX+1,SP)
 1050     CASE UP$
 1055       LET ODY=MAX(ODY-1,-SP)
 1057     CASE DOWN$
 1060       LET ODY=MIN(ODY+1,SP)
 1065     END SELECT
 1070   END IF
 1080   LET CH=1-(CH=1)
 1095 LOOP
 1105 END
 1199 !
 6001   CLEAR #CH
 6020   LET CL=IP((OX-1)/8)+WID*ZY-WID
 6021   LET KOX=MOD(OX-1,8)
 6022   FOR K=1 TO OHGT
 6023     LET CLX=LD2(CH)+CL+(K-1)*WID
 6025     LET M1=OFFX1(K,KOX)
 6027     LET M2=OFFX2(K,KOX)
 6035     SPOKE LD2PAGE(CH),CLX,M1
 6040     SPOKE LD2PAGE(CH),CLX+1,M2
 6045   NEXT
 6050 END DEF
 6099 !
 6105   LET LPTLOW=SPEEK(255,16372)
 6110   LET LPTHIGH=SPEEK(255,16373)
 6120 END DEF
 6199 !
 6200 DEF GETLD1
 6205   LET LD1LOW=SPEEK(255,LPT+16*LBLOCK+4)
 6210   LET LD1HIGH=SPEEK(255,LPT+16*LBLOCK+5)
 6215   LET LD1PAGE(CH)=252+IP((LD1HIGH*128)/8192)
 6220   LET LD1(CH)=LD1LOW+MOD(LD1HIGH*128+LD1HIGH*128,16384)
 6225 END DEF
 6299 !
 6300 DEF GETLD2
 6305   LET LD2LOW=SPEEK(255,LPT+16*LBLOCK+6)
 6310   LET LD2HIGH=SPEEK(255,LPT+16*LBLOCK+7)
 6315   LET LD2PAGE(CH)=252+IP((LD2HIGH*128)/8192)
 6320   LET LD2(CH)=LD2LOW+MOD(LD2HIGH*128+LD2HIGH*128,16384)
 6325 END DEF
 6399 !
 7005   LET GET_EVENT=0
 7010 END DEF
 7099 !
 7105   PRINT "Event! ";
 7110 END DEF
 8099 !
 9005   RESTORE 9500
 9010   FOR I=1 TO 9
 9015     READ GFX1(I)
 9020   NEXT
 9025   FOR I=1 TO OHGT
 9030     FOR J=0 TO 8
 9033       LET OFFX1(I,J)=IP(GFX1(I)/2^J)
 9036       LET OFFX2(I,8-J)=MOD(GFX1(I)*2^J-(2^(8-J)-1)*256,256)
 9040     NEXT
 9045   NEXT
 9050   LET ESC$=CHR$(27):LET LEFT$=CHR$(184):LET RIGHT$=CHR$(188):LET UP$=CHR$(176):LET DOWN$=CHR$(180)
 9090 END DEF
 9099 !
 9105   SET VIDEO MODE 15
 9125   OPEN #1:"VIDEO:"
 9130   OPEN #2:"VIDEO:"
 9135   FOR CH=1 TO 2
 9145     SET #CH:BIAS 168
 9160   NEXT
 9165   LET CH=1
 9180 END DEF
 9199 !
 9500 DATA 255,129,129,129,129,129,129,129,255

VIDEO: / Re: GraCha Sprite System
« on: 2019.April.18. 20:54:39 »

As a comment to your discussion about sprites in a BASIC environment... I recently wrote some code in pure BASIC to see if I could make a reasonably good sprite in BASIC without resorting to MC code.  I was also looking at using attribute mode in BASIC. So I combined the two things in the included test program. The end result, after compiling it with ZZZIP, was actually kind of useful with nearly 10 fps in a double buffer display using two video pages, which surprised me a bit.

You can fly the sprite in all directions using the cursor keys, and stop the program using the ESC key. It will only fly as far as the borders and then reduce the speed in the current direction to 0. Acceleration is done by repeatedly pressing a cursor key. Max speed is 4 pixels in any direction.

Just load the image and press START.

Of course you cannot run many sprites this way, unless they are very thin in height. You have to plot each scan-line in a cell (in attribute mode anyway). So the current sprite, which is 9 scanlines high and 2 cells wide, requires 18 spokes. The two video pages used are cleared before each update, which also takes some time, especially if you want a large page display. Therefore I limited it to 20 x 10.

You can avoid clearing the displays constantly, if you systematically erase the cells you used from the previous sprite plotting. In this case it requires another 18 spokes. So if you use this method, it slows the system severely, if you have more than 2-3 sprites. The good news is then, that you do not have to redraw the background, except where you erased the plots.

In flew the sprite from left to right (160 pixels( in about 18 seconds in 1 pixel steps in the ZZZip version. In BASIC it is about 5-6 times slower.


Programming / Re: Using SET BIAS
« on: 2019.February.14. 20:34:16 »

Thanks! I am familiar with that page, which is all you need for normal use. What it does not tell you is why the colours are in the order they are (How they are defined and constructed). I hope this discussion has clarified that.

This knowledge may also have a practical application. Assume that you need to have a specific colour among your 16 available colours. Ideally the BIAS fixed part of your palette  (ink 8-15) should include as many of the colours you need as possible, so you can use the variable ink (0-7) colours freely by assigning colour numbers to them. With the knowledge we have gained in this discussion, we can decide on a colour with a specific combination of intensities, find its number and which of the 32 BIAS groups of 8 numbers, that i is a part of, and which number (0-7) it has in this group, and make sure the group is selected for BIAS. Then just add 8 to the number it has in the BIAS group and you have the INK number. (Between 8-15)


Programming / Re: Using SET BIAS
« on: 2019.February.14. 15:24:52 »

Ups! Sorry! Calling people by the wrong name.... I stand corrected :-)

Wrong number. The correct line is...
08         00001000      .29-.42      2

When I started to look at how colours work, I expected a table of values somewhere in memory for the 256 colours. But it seems that colours do not need a table if the bits in the colour number are used, as thet are in the Enterprise. The bit pattern provides the RED, GREEN and BLUE intensities that define the colour. Therefore colours 0-7 have their intensity definitions made from their matching bit patterns 00000000 - 00000111. So colour 7 is made from RED(1), GREEN(1) and BLUE(1).

The 256 colours are divided into 32 parts, each of 8 consecutive numbers. 0-7, 8-15, ...248-255. If you want the location of colour 14 (00001 110) it is item 6 (items indexed from 0-7) in part 1 (the second part)  among the colour groups. I call these groups for sets.

I think colours are implemented in this way, because you only have 256 colours, and it turns out you can save 256 bytes of memory if you can represent the intensities with every third bit instead of the first three bits for RED, the next 3 bits for GREEN and the last 2 for BLUE. Thus a colour's number doubles as the intensity definition, and you don't need to store anything explicitly. It is all very clever.

Programming / Re: Using SET BIAS
« on: 2019.February.14. 09:50:05 »

Well... In fact I think I do understand how the RGB function works. But it is very convoluted. The values you specify between 0.0 and 1.0 are translated to intensities based on their bit patterns. You therefore have to understand how bit patterns are translated to intensities - discussed in some earlier mails in this debate. But if you know the bit pattern used to specify intensities and therefore the colour, you already have the answer (the colour number) and do not need an RGB function. So the function is nearly useless. It would have made sense if you had entered the intensity values directly like this RGB(3,3,0) with values ranging from 0-7 for RED and GREEN and 0-3 for BLUE.

Here are the patterns created by the RED component.

Return value  Bit pattern   Decimal      Intensity
for RED       return value   spec. in   
          for RED      RGB func.   
00         00000000     .00-.14      0
64         01000000    .15-.28      4
08         00001000      .29-.42      3
72         01001000     .43-.57      6
01         00000001     .58-.71      1
65         01000001     .72-.85      5
09         00001001     .86-.99      3
73         01001001     1.00              7

Similar patterns with other bits provides the GREEN and BLUE component. These three patterns are then OR-ed and the resulting bit pattern is the colour number you can use in a COLOUR or INK or PALETTE command.


Programming / Re: Using SET BIAS
« on: 2019.February.13. 16:31:38 »
Thanks for clearing my somewhat muddled thoughts :-)

Using the Enterprise Colours Scheme is a simple and convenient way of selecting a colour. A very nice program....

However here is my task:

I want to use the BIAS set, where there is a colour mixed from RED (3) and GREEN (3) and BLUE (0). The bit pattern for this colour is:

00011011 = 27

As ergoGnomics describes in his mail, the top 5 bits (00011) translates into the BIAS set number and the low 3 bits provides the index of the colour in the BIAS set.

00011 = 3 (That is BIAS set 3).
011 = 3 (Colour in BIAS set).

A set has 8 colours, so for instance colour 8-15 are members of set 1. So you have to multiply the set number with 8 to get a number within that set. And as the 8 colours from a set are mapped to palette colour 8-15 you have to add 8 to the index of the colour in the set when specifying your ink.

Here is some code, that demonstrates how it works.

100 PROGRAM "a:biastest.bas"
120 LET BIAS_NO = 3
130 LET COL_NO = 3
150 SET INK COL_NO + 8
170 PLOT 100,100; 300,100; 300,200; 100,200; 100,100, 200,150, PAINT

The cool thing is that the bit pattern for the number of the colour also implicitly has information about the intensity of the RGB colours used to mix it, as well as information about BIAS sets and colours. So knowing any of the three facts can be used to deduce the others.

And yes, on second thoughts I don't understand the RGB function either :-)


Programming / Using SET BIAS
« on: 2019.February.11. 20:08:42 »

I am investigating the capabilities of the EP128 Basic. Just now I play with colours, and I would appreciate, if someone could confirm my understanding of how SET BIAS works. Here is how I think it works...

The Enterprise 128 can display up to 256 colours, but the reasonable compromise between resolution and number of colours, when doing graphics, is MODE 4. In this mode we have 16 colours. The first 8 colours can be modified to represent any combination of 8 of the 256 colours available using the PALETTE command. However for the other 8 colours you can only choose between 32 sets of 8 predefined colours. The first set is represented by the numbers 0-7, the next by 8-15, and so on up to 255. The trick is, that there is no physical memory location with the color code. The bit pattern of a number defines what colour it represents. There are 8 bits in the number. Three of those bits represent a value for red intensity between 0-7. Those are bit 6 ,bit 3 and bit, 0 with bit 6 as the most significant bit. Three other bits represent the green intensity. Those are bit 7, bit 4, bit 1 with bit 7 as the most significant. Finally blue intensity is held in bit 5 and bit 2. So for instance the value 22 gives a bit pattern like this:

00010110 (bit 7 on the left and 0 on the right) = Red intensity (0*4 + 0*2 + 0*1 = 0), green intensity (0*4 + 2*1 + 1*1 = 3), blue intensity (0*2 + 1*1 = 1) That is a mix of medium intensity green and weak intensity blue.

You can specify a colour using the RGB function. But i find using the BIN function more easy to use in this situation. Specifying colour intensity in 0.15 intervals between each level is messy as done within the RGB function.

You specify a set by writing:
SET #10: BIAS b

where b is any number in the b interval. So for instance to activate interval 1, you could set b to any value between 8-15. Also notice that the channel number is not really needed, since only one bias value can be active at any time no matter how many displays you have activated.

Is there more to SET BIAS than what I have described?


Programming / Use of KEYBOARD: device
« on: 2018.April.16. 18:49:19 »

I am a bit curious about how to reopen the KEYBOARD: device in MC code. In my scenario I work from ISDOS. I am aware that only one keyboard channel can be open at any time

Obviously the keyboard driver is initially active via the EDITOR: when working from ISDOS.

First I disable interrupts, then I read the $KEY_EDIT EXOS variable to find the existing keyboard device channel. I use this value to close the keyboard channel. Both actions return code 0 (no error).

Then I attempt to open a new keyboard channel (HL equals bytestring...... 9,"KEYBOARD:"). This fails. Return code is different from 0.

Is there some mechanism that keeps the default keyboard channel open at all times in ISDOS.

I can of  course make EXOS call 5 to read the keyboard by using the channel no from the $KEY_EDIT EXOS variable or use I/O ports directly. I just wanted to try using another channel.

I have seen some examples of code that opened another channel for the keyboard. Yet their code did not close the default channel, and only one channel can be used at any time. So what am I missing?


Programming / Re: Call to ROM during reboot
« on: 2018.April.08. 21:17:59 »

Ahh - Thanks.

I can see there is a lot of interesting information in that book and in those ROM listings. Google Translate will have to do some hard work here. And so will I :-)


Programming / Call to ROM during reboot
« on: 2018.April.08. 17:22:43 »

Like everyone else, who are venturing into MC coding on the EP128, I use the SAMPLE.ASM programming example to get started. In my case I look at each line of the program and analyze its purpose to get a feeling for how it works.

There is a section that sets up pages for a reset. It goes like this... (comments as I understand the process)

LD C,40H ; This triggers deallocation of all user RAM during the EXOS Reset (RESET=0)
EXOS RESET ; Afterwards only PAGE0 is defined by the system and pointing to the lowest RAM segment (0F8H on my EP128)

LD A,1 ; So we initialize Page3 (port 0B3H) to point to segment 1 (ROM segment)
OUT (0B3H),A

Then comes the question...

LD A,6

The comments in the program refer to the 6 function=Enterprise logo screen and make a call to a (fixed) address in the ROM in Page 3. Offset 0DH from the start address of memory mapped to Z80 space 0C00H-0FFFFH (Page3)

... Where can I find documentation that tells me I need to jump to this specific address with this particular value. Any help is appreciated, please.

I have the English  version of the Kernal Specification 2.1, but I have no manuals or articles discussing ROMS and their layout. If such documentation exist in English, it is preferable. If it exists in Hungarian... well, Google Translate will point me in the right direction though it obviously has issues and translates word into English words, where you need a little bit of vertical thinking to decode the actual meaning. :-)


Pages: [1] 2