Jump to content
IGNORED

fbForth—TI Forth with File-based Block I/O [Post #1 UPDATED: 06/09/2023]


Lee Stewart

Recommended Posts

Hi guys,

 

When I look at this BASIC code I am wondering what generated the data in the STRATDAT file?

 

 

I occurs to me that we could put all this in a block or two as text and compile it directly into VDP

 

-OR-

 

Maybe better, take the raw VDP data and put it into a block as a binary image with VMBR, and just BLIT it back into VDP in milli-seconds with VMBW.

OPEN #1:"DSK1.STRATDAT",INPUT,INTERNAL

// Define colors
FOR I=1 TO 14::
	INPUT #1: S,F,B::
	CALL COLOR(S,F,B)::
NEXT I

CALL SCREEN(13)

// Define characters
FOR I=1 TO 108::
	INPUT #1: CH,CDEF$::
	CALL CHAR(CH,CDEF$)::
NEXT I

Link to comment
Share on other sites

Yes. I think everything can be loaded from blocks—even the splash screen. Though, I am inclined to do the splash screen from files as I did in the PM—mainly, because that is the only bitmap graphics in the game and it is pretty simple to splash the screen for either a specified time or after a user keystroke and, then, blank the screen, change graphics modes and on with the game setup and play.

 

...lee

  • Like 1
Link to comment
Share on other sites

Re using files to load the splash screen: I should add that it is much faster than Forth blocks because I am using LOAD (opcode = 5), which does not require OPEN and loads binary code straight to the relevant VRAM tables. If we use Forth blocks, the blocks file is opened, blocks are loaded into RAM blocks buffers via VRAM via the disk DSR and, then, copied to the relevant VRAM tables—not nearly as efficient.

 

...lee

  • Like 3
Link to comment
Share on other sites

Re using files to load the splash screen: I should add that it is much faster than Forth blocks because I am using LOAD (opcode = 5), which does not require OPEN and loads binary code straight to the relevant VRAM tables. If we use Forth blocks, the blocks file is opened, blocks are loaded into RAM blocks buffers via VRAM via the disk DSR and, then, copied to the relevant VRAM tables—not nearly as efficient.

 

...lee

To that point then I suppose the entire character set and color table could be loaded in a similar fashion.

  • Like 1
Link to comment
Share on other sites

Okay... Here in the spoiler is my first pass at converting a block of XB CALL SOUND() statements to an fbForth 2.0 sound table:

 

 

\ Create a sound table from XB CALL SOUND() commands.
\ First, do the following:
\  1. Replace CALL SOUND() with SND[  ]SND
\  2. Replace commas with spaces
\  3. Surround all SND[ ... ]SND to be in sound table with
\     SOUND_TABLE[  ]SOUND_TABLE

HEX
0 VARIABLE SDUR   \ sound duration
0 VARIABLE SCNT   \ sound byte count
0 VARIABLE SCADR  \ sound byte  count address in sound list
0 VARIABLE TGEN   \ tone generator
0 VARIABLE NGEN   \ noise generator flag

: SOUND_TABLE[  ( -- addr )   HERE  ;  \ leave address of sound table
: ]SOUND_TABLE  ( -- )  
   4 C, 09F C, 0BF C, 0DF C, 0FF C, 00 C, \ mute all generators
   00 C,          \ add a final 0 count byte
   ALIGN  ;       \ insure HERE is on a word boundary
: FCONST  ( -- d )   \ frequency constant = ~111860.8
   B4F5 1  ;         \ rounded to 111861
: >FCODE  ( 0abc -- 00ab 000c ) \ massage fcode for byte output
   DUP 4 SRL SWAP    \ S:00ab 0abc
   0F AND  ;         \ S:00ab 000c
: HZ>CODE  ( freq -- sb2 sb1 )  \ convert freq to sound tone & data bytes
   FCONST ROT U/ SWAP DROP    \ calculate fcode
   03FF AND 2 MAX             \ insure only 10-bit number > 1
   >FCODE 080 OR  ;           \ convert to a tone byte as sb1

: GETPARAM  ( -- flag )  ( IS:<num> )  \ get next parameter in sound list
   BL WORD        \ get next parameter to HERE as packed string
   HERE 1+ C@     \ get first char
   ASCII ] = IF   \ is it ']'?
      0           \ yes..assume we read ']SND'
   ELSE
      1           \ no..let parameter be processed
   THEN  ;
\ Process parameter at HERE as duration
: DURATION  ( -- )
   HERE NUMBER DROP    \ 16-bit duration to stack
   ABS            \ make positive
   6 64 */        \ convert to 1/60s of a second
   0FF MIN        \ insure < 256
   1 MAX          \ at least 1
   SDUR !  ;      \ store it
\ Process paramter at HERE as frequency or noise
: FREQUENCY  ( -- [freq|noise] flag )
   HERE NUMBER    \ get 32-bit number to stack
   0< IF          \ first cell neg, i.e., noise?
      0           \ false flag for noise
   ELSE
      1           \ true flag for tone
   THEN  ;
\ Process parameter at HERE as volume
: VOLUME  ( -- sb )
   HERE NUMBER DROP    \ 16-bit volume to stack
   1 SRL          \ change Basic's 0-30 to 0-15
   0F AND         \ force one nybble
   090 OR         \ make sb a latch/volume byte
;
: NOISE  ( -n -- sb )  \ convert negative number on stack to noise code
   ABS 1- 7 AND      \ adjust -n to noise code bits
   0E0 OR  ;         \ convert to a latch/noise byte as sb

: ]SND   ( -- )
   SCNT @ SCADR @ C!    \ stash sound byte count
   SDUR @ C,  ;         \ compile sound duration

: SND[   ( -- )
   0 TGEN !       \ zero sound generator number
   0 SCNT !       \ initialize byte count of sound list
   HERE SCADR !   \ store address of sound byte count for current sound list
   0 C,           \ compile 0 to hold place
   GETPARAM DROP  \ get parameter and assume it is the duration number
   DURATION       \ process duration
   BEGIN
      GETPARAM    \ get next frequency/noise
   WHILE          \ did we read ]SND?
      FREQUENCY   \ no..process parameter
      IF          \ frequency?
         HZ>CODE     \ convert to 2 sound bytes
         TGEN @ OR   \ set tone generator
         2 SCNT +!   \ increment sound byte count by 2
         C, C,       \ compile tone bytes
         0 NGEN !    \ reset noise gen flag for volume byte
      ELSE
         NOISE
         1 SCNT +!   \ increment sound byte count by 1
         C,          \ compile noise byte
         1 NGEN !    \ set noise gen flag for volume byte
      THEN
      GETPARAM DROP  \ get parameter and assume it is the volume number
      VOLUME         \ process volume
      NGEN @ IF      \ noise volume?
         60 OR       \ yes..OR generator 3 with sb
      ELSE
         TGEN @ OR   \ no..or current tone generator with sb
         20 TGEN +!  \ increment to next tone generator
      THEN
      1 SCNT +!      \ increment sound byte count by 1
      C,             \ compile volume sound byte
   REPEAT            \ do it again
   ]SND  ;           \ clean up

 

 

 

And, here is a sample:

DECIMAL 
\ Explosion sound from TidBit
\ CALL SOUND(50,788,0,3496,0,1243,0)
\ CALL SOUND(50,788,8,3496,30,1243,
\ CALL SOUND(50,788,16,3496,16,1243,20)
\ CALL SOUND(50,788,24,3496,30,1243,12)
\ CALL SOUND(66,788,20,3496,24,1243,24)
\ CALL SOUND(66,788,28,3496,30,1243,28)
\ CALL SOUND(66,3107,0,5593,0,1670,0)
\ CALL SOUND(66,3107,8,5593,30,1670,
\ CALL SOUND(66,3107,16,5593,16,1670,16)
\ CALL SOUND(66,3107,24,5593,30,1670,20)
\ CALL SOUND(66,3107,20,5593,24,1670,24)
\ CALL SOUND(66,3107,28,5593,30,1670,28)

\ Sound table production code for above XB CALL SOUND() statements
SOUND_TABLE[  
SND[ 50  788  0 3496  0 1243  0 ]SND
SND[ 50  788  8 3496 30 1243  8 ]SND
SND[ 50  788 16 3496 16 1243 20 ]SND
SND[ 50  788 24 3496 30 1243 12 ]SND
SND[ 66  788 20 3496 24 1243 24 ]SND
SND[ 66  788 28 3496 30 1243 28 ]SND
SND[ 66 3107  0 5593  0 1670  0 ]SND
SND[ 66 3107  8 5593 30 1670  8 ]SND
SND[ 66 3107 16 5593 16 1670 16 ]SND
SND[ 66 3107 24 5593 30 1670 20 ]SND
SND[ 66 3107 20 5593 24 1670 24 ]SND
SND[ 66 3107 28 5593 30 1670 28 ]SND  ]SOUND_TABLE 

It gets the job done, but could be a lot cleaner, I am sure. At this point, creating words that play a particular sound table is a manual process—which will be fine for the current project. It would be a touch more complicated to make the relevant words state smart for compilation vs. interpretation, but I do eventually want to make these words more generally useful. We shall see.

 

Meanwhile, are there any questions, suggestions, contributions ...?

 

[Edit: HZ>CODE corrected.]

[Edit #2: Added a final 0 count byte to ]SOUND-TABLE . The Forth ISR I modified seems to need it.]

 

...lee

Link to comment
Share on other sites

After you wrote about working on a SOUND() equivalent I started spinning on it too.

It turns out that emulating the BASIC function is trickier than it appears, but I did get a version running with one difference.

 

I decided up front that putting 4 voices in 1 function was another example of data driven thinking that we see in conventional languages.

So my thought is that each voice should be a separate word in Forth. This also is better for the fact that Forth does not tolerate variable numbers of arguments.

 

When I ran the code on my system that uses 9901 timer for millisecond delays. I had to adjust the timings to make it run the same speed as BASIC.

So that's one area to work on.

 

Also the sound of the two pieces of code is different in terms of the "attack" of the sound. I believe the envelope of the sound is being affect by the speed that BASIC runs.

So each line chops the sound off before the next line starts and that creates a unique effect. :-)



DECIMAL
: EXPLODE ( -- )  \ variable duration :-)
         45 788  0 SND1   45 3496  0 SND2  45 1242  0 SND3
         45 788  8 SND1   45 3496 30 SND2  45 1243  8 SND3
         45 788 16 SND1   45 3496 16 SND2  45 1243 20 SND3
         45 788 24 SND1   45 3496 30 SND2  45 1243 12 SND3
 
         60 788  20 SND1  60 3496 24 SND2  60 1243 24 SND3
         60 788  28 SND1  60 3496 30 SND2  60 1243 28 SND3
 
         60 3107  0 SND1  60 5593  0 SND2  60 1670  0 SND3
         60 3107  8 SND1  60 5593 30 SND2  60 1670  8 SND3
         60 3107 16 SND1  60 5593 16 SND2  60 6167 16 SND3
         60 3107 24 SND1  60 5593 30 SND2  60 1670 20 SND3
         60 3107 20 SND1  60 5593 24 SND2  60 1670 24 SND3
         60 3107 28 SND1  60 5593 30 SND2  60 1670 28 SND3 ;

However when I look at what is going on we see that the same 3 tones are being started and then volume modulated to fade out. This is the only way you can do this in BASIC.

 

In Forth could do this starting the tones and then modulating volume independantly, but that is more work to translate.

 

 

BASIC STRATEGO EXPLODE.mp4

FORTH STRATEGO EXPLODE.mp4

  • Like 1
Link to comment
Share on other sites

Okay... Here in the spoiler is my first pass at converting a block of XB CALL SOUND() statements to an fbForth 2.0 sound table:

 

 

Meanwhile, are there any questions, suggestions, contributions ...?

 

...lee

 

When I look at the code I see blending of the data collection and sound production mixed together.

Would it be simpler to use your existing DATA[ ]DATA words and then create a player that reads that data?

 

This would read clearer

DECIMAL
: FCONST  ( -- d )   \ frequency constant = ~111860.8
   111861.   ;         \ rounded to 111861

Is the clock frequency 111861 or 111761 ?

 

Edit: duh. I was using the wrong value.

Edited by TheBF
Link to comment
Share on other sites

 

When I look at the code I see blending of the data collection and sound production mixed together.

Would it be simpler to use your existing DATA[ ]DATA words and then create a player that reads that data?

 

This would read clearer

DECIMAL
: FCONST  ( -- d )   \ frequency constant = ~111860.8
   111861.   ;         \ rounded to 111861

Is the clock frequency 111861 or 111761 ?

 

Edit: duh. I was using the wrong value.

 

I got the info from the E/A Manual rather than the TMS9919 Manual. The E/A Manual is not error free! That said, 111860.8 is, technically, not the clock frequency, but, rather, the clock frequency/32 or 3579545 Hz/32 —hence the descriptor, frequency constant. The ‘32’ has units related to the tone generator counter, but I could not say what they are.

 

Re use of DATA[ ]DATA —that is what I use in the sound chapter of fbForth 2.0: A File-Based Cartridge Implementation of TI Forth in setting up a sound table for PLAY , which is serviced by the fbForth 2.0 ISR. What I need to do is to create a BYTE[ ]BYTE pair of words because using DATA[ ]DATA just blows! Anyway, with the SOUNDTABLE[ ]SOUNDTABLE and SND[ ]SND coding, I was merely attempting a translator. I did stop short of parsing actual CALL SOUND() statements, however.

 

...lee

Link to comment
Share on other sites

After you wrote about working on a SOUND() equivalent I started spinning on it too.

.

.

.

However when I look at what is going on we see that the same 3 tones are being started and then volume modulated to fade out. This is the only way you can do this in BASIC.

 

In Forth could do this starting the tones and then modulating volume independantly, but that is more work to translate.

 

That looks good and is more in keeping with Forth philosophy, but, as I noted in my last post, I wanted a translator that did not require a lot of manual pre-processing.

 

I really like your last observation. That might make manual processing of those relatively short sound tables worth the effort.

 

Re your example MP4s, the Forth example cannot be correct. The pitch of the second set of tones goes up instead of down, as was the case in XB. That said, my code is DOA. :mad: I need to work on it. The beach is calling my name, so, perhaps, I will take the code with me to work on in the sun. :P

 

...lee

Link to comment
Share on other sites

There is one more thing about CALL SOUND() that complicates translating it to Forth. The noise “frequency” and noise volume pair can be anywhere in the argument list. The order of the three tone generator settings must, of course, be maintained and, even if you only want tone generator #3 (XB), you must include settings for TG1 and TG2, as well.

 

...lee

Link to comment
Share on other sites

There is one more thing about CALL SOUND() that complicates translating it to Forth. The noise “frequency” and noise volume pair can be anywhere in the argument list. The order of the three tone generator settings must, of course, be maintained and, even if you only want tone generator #3 (XB), you must include settings for TG1 and TG2, as well.

 

...lee

 

I was not that aware of that feature in the sound() command.

 

The only way to get that level of compatibility you would have to write an exact replacement. I am happy to work on the translation of the sound lists as a discrete job function.

 

So since it's -3 C here, I have no desire to go the beach so I ported my sound lexicon to FBForth instead. It's just as much fun!

 

How do I send you the text of in the blocks? Just zip up the block file?

 

Here is a video of the code blocks and the sound.

FBFORTH STRATEGO EXPLODE.mp4

Link to comment
Share on other sites

 

 

Re your example MP4s, the Forth example cannot be correct. The pitch of the second set of tones goes up instead of down, as was the case in XB.

 

...lee

 

Strange, I hear the pitch going up on the second set, but there is difference in the attack of the sounds in BASIC. The Forth is a softer attack. Possible due to ISR driven versus non ISR driven methods. (?)

Link to comment
Share on other sites

Yeah...ZIPping it up will work. I do not think AtariAge likes extension-less files.

 

BTW I think I found the error in my code. HZ>CODE has

2 MIN

which should be

2 MAX

I will need to check it later. Did I tell you I am on the beach?

 

...lee

 

Gotta run to my grandaughter's recital, will send you the zip file later today.

  • Like 1
Link to comment
Share on other sites

Yeah...ZIPping it up will work. I do not think AtariAge likes extension-less files.

 

BTW I think I found the error in my code. HZ>CODE has

2 MIN

which should be

2 MAX

I will need to check it later. Did I tell you I am on the beach?

 

...lee

 

That was it! I will correct the post above in a bit corrected post #1506.

 

...lee

Link to comment
Share on other sites

...

 

However when I look at what is going on we see that the same 3 tones are being started and then volume modulated to fade out. This is the only way you can do this in BASIC.

 

In Forth could do this starting the tones and then modulating volume independently, but that is more work to translate.

 

After creating the sound table with SOUND-TABLE[ SND[ ... ]SND ... ]SOUND-TABLE , it was a simple matter to manually remove the redundancies you pointed out and incorporate the result into a DATA[ ... ]DATA structure. The sound table went from 138 bytes down to 78 bytes!:

: EXPLODE  ( -- addr )
DATA[
   098D 0890 AF01 B0C9 05D0 0303 94BF D403 0398 B8DA 0303 9CBF 
   D603 039A BCDC 0303 9EBF DE03 0984 0290 A401 B0C2 04D0 0303 
   94BF D403 0398 B8D8 0303 9CBF DA03 039A BCDC 0303 9EBF DE03 
   049F BFDF FF00 0000
]DATA  DROP  ;

and to play it preemptively, i.e., killing all previously started sound tables:

EXPLODE 1 PLAY

BTW it plays with the same tone progression as the XB code, so something might be awry with your code. :)

 

[Edit: I added a 0 count byte at the end, which needs an extra byte to align properly. It still saves 60 bytes over the previous incarnation.]

 

...lee

  • Like 1
Link to comment
Share on other sites

 

After creating the sound table with SOUND-TABLE[ SND[ ... ]SND ... ]SOUND-TABLE , it was a simple matter to manually remove the redundancies you pointed out and incorporate the result into a DATA[ ... ]DATA structure. The sound table went from 138 bytes down to 78 bytes!:

: EXPLODE  ( -- addr )
DATA[
   098D 0890 AF01 B0C9 05D0 0303 94BF D403 0398 B8DA 0303 9CBF 
   D603 039A BCDC 0303 9EBF DE03 0984 0290 A401 B0C2 04D0 0303 
   94BF D403 0398 B8D8 0303 9CBF DA03 039A BCDC 0303 9EBF DE03 
   049F BFDF FF00 0000
]DATA  DROP  ;

and to play it preemptively, i.e., killing all previously started sound tables:

EXPLODE 1 PLAY

BTW it plays with the same tone progression as the XB code, so something might be awry with your code. :)

 

[Edit: I added a 0 count byte at the end, which needs an extra byte to align properly. It still saves 60 bytes over the previous incarnation.]

 

...lee

 

That's real progress.

 

I believe the problem with my first recording was I was using the wrong freq. for the 9902 clk. I had 111761 not 111861.

 

It sounds correct now. I think you are well on your way using the soundlist method.

 

I am having some fun with creating a BASS and a WHITE routine that lets you do noise source tracking to Osc.3 for BASS and pitched white noise in one command.

This turns some of Walid's sounds from this:

CALL SOUND(125,220,30,220,30,1962,30,-8,18)
CALL SOUND(125,220,30,220,30,2330,30,-8,16)
CALL SOUND(125,220,30,220,30,4661,30,-8,14)

to this:

: GALLOP
         125 1962 18  WHITE
         125 2330 16  WHITE
         125 4661 14  WHITE ;

It's the power of factoring. :-)


: BASS ( dur freq vol -- ) \ steal VOX3 & VOX4 to play low freq
         VOX3 SWAP HZ MUTE
         VOX4 3 NOISETYPE  DB
         DURATION ;

: WHITE ( dur freq vol -- ) \ steal VOX3 & VOX4. Pitched white noise
         VOX3 SWAP HZ MUTE
         VOX4 7 NOISETYPE  DB
         DURATION ;


I am just working on the correct calculation to let me pitch the BASS notes in Hz.

 

Edit: posted final code on CAMEL99 Forth thread

Edited by TheBF
  • Like 2
Link to comment
Share on other sites

Yes. I knew that, and with your new "compression" technique I should think you are all set.

 

Thinking about it however forced me to review my own sound control code so at least I did something useful.

 

It is intriguing to create a little language to do this stuff, but I believe for maximum efficiency the sound lists are the way to go.

 

I do have a sound list compiler *lexicon in a partial state of completion however ... :-)

 

* It lets you write mnemonic text but it creates a playable sound list in memory.

  • Like 2
Link to comment
Share on other sites

Here are all the sounds in the game. I could not discern the meanings of a couple of the sounds so I took their names from where they appeared in the code:

HEX
: CHARGESND  ( -- addr )
   DATA[
      098D 0890 AF01 B0C9 05D0 0303 94BF D403 0398 B8DA 0303 
      9CBF D603 039A BCDC 0303 9EBF DE03 0984 0290 A401 B0C2 
      04D0 0303 94BF D403 0398 B8D8 0303 9CBF DA03 039A BCDC 
      0303 9EBF DE03 049F BFDF FF00 0000
   ]DATA  DROP  ;
: CHARGE   ( -- )   \ preemptively play charging sound
   CHARGESND 1 PLAY  ;

: BOMBSND  ( -- addr )
   DATA[
      02E6 F006 02E6 F406 02E6 F806 02E6 
      FC06 02E6 FE06 049F BFDF FF00 0000
   ]DATA  DROP  ;
: BOMB   ( -- )   \ preemptively play bomb sound
   BOMBSND 1 PLAY  ;

: KEYAGAINSND  ( -- addr )
   DATA[
      0B8C 1F9F AC1F BFC6 09DF E3F0 0104 9FBF DFFF 0000
   ]DATA  DROP  ;
: KEYAGAIN   ( -- )   \ preemptively play key_again sound
   KEYAGAINSND 1 PLAY  ;

: NOGALLOPSND  ( -- addr )
   DATA[
      079F BFC9 03DF E7F9 0705 C003 DFE7 
      F807 05C7 01DF E7F7 0702 DFFF 0000
   ]DATA  DROP  ;
: NOGALLOP   ( -- )   \ preemptively play no-gallop sound
   NOGALLOPSND 1 PLAY  ;

: GALLOPSND  ( -- addr )
   DATA[
      02E6 F003 02E6 F703 02E6 F003 02E6 F703 
      02E6 F003 02E6 F709 049F BFDF FF00 0000
   ]DATA  DROP  ;
: GALLOP   ( -- )   \ non-preemptively play gallop sound
   3 0 DO
      GALLOPSND 0 PLAY
   LOOP  ;
DECIMAL

[Edit: Changed KEY2SND and KEY2 to KEYAGAINSND and KEYAGAIN , respectively.]

 

...lee

  • Like 3
Link to comment
Share on other sites

Here is the initial screen of Stratego just before the random elements of the plain are added:

 

 

\ Stratego initialization
HEX  GRAPHICS  0 0 0 0 07F CHAR  RANDOMIZE  CLS
HERE  \ save place

\ color table
DATA[ 0000 0010 C343 4381 B1B1 B143 1717 1771 B1B1 1010 ]DATA
2 * COLTAB SWAP      \ [S:addr vaddr cnt*2]
VMBW                 \ write color table
0C SCREEN            \ screen color
0A BLOCK 040 +  PDT 0F0 +  0390 VMBW \ write PDT from block #10

\ define characters on block #10, 912 chars at pos 64
\ DATA[ 007C 7C7C 7C7C 7C7C 0000 0000 0000 0000 0000 0000 0000 
\       0000 0010 1010 1010 0010 0248 0114 0148 2004 800A 4000 
\       2C99 0022 0862 3401 4806 5200 2D80 193C 7C3E 1841 0020 
\       5050 2054 4834 0008 0810 0000 0000 0F1F 7FFF FF7F 7F3F 
\       7F7F 3F3F 1F0F 0F03 00E1 F3FF FFFF FFFF FFFF FFFF FFFF 
\       3C08 33FF FFFF FFFF FFFF FFFF FFE7 C3C3 4100 81E3 FFFF 
\       FFFF FFFF FFFF FFFF FFFF EFC3 C3F7 FFFF FFFF FFFF FFFF 
\       FFFF FFFF DF84 F8FC FEFF FFFF FEFE FFFE FEFC FCFC F8F8 
\       0000 0000 FF00 FFFF D0D0 D0D0 D0D0 D0D0 0B0B 0B0B 0B0B 
\       0B0B FFFF FFFF FFFF FFFF 0081 DBFF C7D9 C5D9 6EAD DBE7 
\       E7DB BD7E 0040 6D5F 5153 555E 0002 B6FA AADA AA7A 5F5F 
\       5F5F 5F5F 7F00 FAFA FAFA FAFA FE00 0020 1008 0408 1020 
\       0038 4404 0810 0010 0038 445C 545C 4038 001C 0C14 74BC 
\       64F6 007C A626 3C26 267C 003A 66C2 C0C0 623C 007C A626 
\       7626 267C 00FE 6660 7860 E6FE 00FE 6260 7860 60F8 003A 
\       66C0 CEC2 663C 00EE 6464 FC64 64EE 003C 1818 1818 183C 
\       001E 0C0C 0C4C 4C38 00E6 6468 7868 64E6 0078 3078 3032 
\       367E 00C6 446C 5454 44EE 00C6 6474 544C 44C6 0038 6CC6 
\       D6C6 6C38 007C 2676 267C 2070 0038 6CC6 C6DE 6639 007C 
\       2676 263C 2476 003A 6662 3CC6 E6BC 00FE DA9A 1818 183C 
\       00EE 6464 6464 7C38 00DE 4C48 2828 3830 00C6 C654 546C 
\       6C44 00EE 4438 1028 44EE 00F7 6234 1818 183C 007E 4614 
\       2E18 327E 001E 1818 1818 181E 0000 4020 1008 0400 003C 
\       0C0C 0C0C 0C3C 0000 0000 0F08 0B0B 0000 0000 F010 D0D0 
\       000C 1238 747C 3800 0078 4E7A 4E42 4000 0000 3834 3CBD 
\       7E00 0A05 0618 3C5E FF00 0204 0C1E 2E7E FF00 0808 1C3D 
\       3E5E 7E00 020C 3C74 EC5C 7E00 020C 1E3A 366E 7F00 0018 
\       3C66 DBFF 7E00 0C3E EE76 3A3E 1C00 040C 3E67 79FF 1E00 
\       041C 3E73 CFF8 C000 0099 FF91 D5D5 D5D1 0099 FFC3 FBC3 
\       DFC3 0099 FFC3 FBF3 FBC3 0099 FFF3 EBDB C3FB 0099 FFC3 
\       DFC3 FBC3 0099 FFC3 DFC3 DBC3 0099 FFC3 FBF7 EFDF 0099 
\       FFC3 DBC3 DBC3 0099 FFC3 DBC3 FBFB 0099 FFC7 DBC3 DBC7 
\       0099 FFC3 DFC7 DFDF 0099 FFE3 DFE3 FBC7 0040 6D5F 5F5F 
\       5F5F 0002 B6FA FAFA FAFA 5F5F 5F5F 5F5F 7F00 FAFA FAFA 
\       FAFA FE00 0010 1010 0010 1010 0030 0808 0408 0830 0000 
\       2054 0800 0000 0000 0000 0000 0000 3864 C6C6 C64C 3800 
\       1878 1818 181A 7C00 3C66 660C 103A 6600 3C66 061C 066E 
\       3C00 3830 6C4C FE0C 1E00 667C 607C 0666 3C00 3C66 C0DC 
\       E646 3C00 C6FE 8C0C 1818 1800 78C4 E478 9C8C 7800 78CC 
\       CC74 04C8 7000 F080 8080 0000 0000 0F01 0101 0000 0000 
\       0000 0000 8080 80F0 0000 0000 0101 010F 0000 0000 0000 
\       0000 0000 0000 0000 0000 ]DATA

\ draw initial screen starting with the initial field
0 0 0280 22 HCHAR 0 0 14 20 VCHAR 01F 0 14 20 VCHAR

\ draw random patches \ draw lakes 7 08 GOTOXY ." (*,.02" 7 09 GOTOXY ." )77773" 7 0A GOTOXY ." (77773" 7 0B GOTOXY ." )+-/13" 013 08 GOTOXY ." (*,.02" 013 09 GOTOXY ." )77773" 013 0A GOTOXY ." (77773" 013 0B GOTOXY ." )+-/13" DP ! \ retore dictionary DECIMAL 4 22 GOTOXY KEY DROP TEXT80

 

 

 

The above code is on block #2 of the attached STRATEGO blocks file. STRATEGOfbf.zip

If you have the file on DSK2, you can run it with the following code:

USEBFL DSK2.STRATEGO
2 LOAD

A blinking cursor indicates when the code is done. You may exit by tapping any key.

 

[Edit: Added two VCHAR words to blank first and last columns.]

 

...lee

  • Like 3
Link to comment
Share on other sites

Here is the initial screen of Stratego just before the random elements of the plain are added:

 

 

\ Stratego initialization
HEX  GRAPHICS  0 0 0 0 07F CHAR  RANDOMIZE  CLS
HERE  \ save place

\ color table
DATA[ 0000 0010 C343 4381 B1B1 B143 1717 1771 B1B1 1010 ]DATA
2 * COLTAB SWAP      \ [S:addr vaddr cnt*2]
VMBW                 \ write color table
0C SCREEN            \ screen color
0A BLOCK 040 +  PDT 0F0 +  0390 VMBW \ write PDT from block #10

\ define characters on block #10, 912 chars at pos 64
\ DATA[ 007C 7C7C 7C7C 7C7C 0000 0000 0000 0000 0000 0000 0000 
\       0000 0010 1010 1010 0010 0248 0114 0148 2004 800A 4000 
\       2C99 0022 0862 3401 4806 5200 2D80 193C 7C3E 1841 0020 
\       5050 2054 4834 0008 0810 0000 0000 0F1F 7FFF FF7F 7F3F 
\       7F7F 3F3F 1F0F 0F03 00E1 F3FF FFFF FFFF FFFF FFFF FFFF 
\       3C08 33FF FFFF FFFF FFFF FFFF FFE7 C3C3 4100 81E3 FFFF 
\       FFFF FFFF FFFF FFFF FFFF EFC3 C3F7 FFFF FFFF FFFF FFFF 
\       FFFF FFFF DF84 F8FC FEFF FFFF FEFE FFFE FEFC FCFC F8F8 
\       0000 0000 FF00 FFFF D0D0 D0D0 D0D0 D0D0 0B0B 0B0B 0B0B 
\       0B0B FFFF FFFF FFFF FFFF 0081 DBFF C7D9 C5D9 6EAD DBE7 
\       E7DB BD7E 0040 6D5F 5153 555E 0002 B6FA AADA AA7A 5F5F 
\       5F5F 5F5F 7F00 FAFA FAFA FAFA FE00 0020 1008 0408 1020 
\       0038 4404 0810 0010 0038 445C 545C 4038 001C 0C14 74BC 
\       64F6 007C A626 3C26 267C 003A 66C2 C0C0 623C 007C A626 
\       7626 267C 00FE 6660 7860 E6FE 00FE 6260 7860 60F8 003A 
\       66C0 CEC2 663C 00EE 6464 FC64 64EE 003C 1818 1818 183C 
\       001E 0C0C 0C4C 4C38 00E6 6468 7868 64E6 0078 3078 3032 
\       367E 00C6 446C 5454 44EE 00C6 6474 544C 44C6 0038 6CC6 
\       D6C6 6C38 007C 2676 267C 2070 0038 6CC6 C6DE 6639 007C 
\       2676 263C 2476 003A 6662 3CC6 E6BC 00FE DA9A 1818 183C 
\       00EE 6464 6464 7C38 00DE 4C48 2828 3830 00C6 C654 546C 
\       6C44 00EE 4438 1028 44EE 00F7 6234 1818 183C 007E 4614 
\       2E18 327E 001E 1818 1818 181E 0000 4020 1008 0400 003C 
\       0C0C 0C0C 0C3C 0000 0000 0F08 0B0B 0000 0000 F010 D0D0 
\       000C 1238 747C 3800 0078 4E7A 4E42 4000 0000 3834 3CBD 
\       7E00 0A05 0618 3C5E FF00 0204 0C1E 2E7E FF00 0808 1C3D 
\       3E5E 7E00 020C 3C74 EC5C 7E00 020C 1E3A 366E 7F00 0018 
\       3C66 DBFF 7E00 0C3E EE76 3A3E 1C00 040C 3E67 79FF 1E00 
\       041C 3E73 CFF8 C000 0099 FF91 D5D5 D5D1 0099 FFC3 FBC3 
\       DFC3 0099 FFC3 FBF3 FBC3 0099 FFF3 EBDB C3FB 0099 FFC3 
\       DFC3 FBC3 0099 FFC3 DFC3 DBC3 0099 FFC3 FBF7 EFDF 0099 
\       FFC3 DBC3 DBC3 0099 FFC3 DBC3 FBFB 0099 FFC7 DBC3 DBC7 
\       0099 FFC3 DFC7 DFDF 0099 FFE3 DFE3 FBC7 0040 6D5F 5F5F 
\       5F5F 0002 B6FA FAFA FAFA 5F5F 5F5F 5F5F 7F00 FAFA FAFA 
\       FAFA FE00 0010 1010 0010 1010 0030 0808 0408 0830 0000 
\       2054 0800 0000 0000 0000 0000 0000 3864 C6C6 C64C 3800 
\       1878 1818 181A 7C00 3C66 660C 103A 6600 3C66 061C 066E 
\       3C00 3830 6C4C FE0C 1E00 667C 607C 0666 3C00 3C66 C0DC 
\       E646 3C00 C6FE 8C0C 1818 1800 78C4 E478 9C8C 7800 78CC 
\       CC74 04C8 7000 F080 8080 0000 0000 0F01 0101 0000 0000 
\       0000 0000 8080 80F0 0000 0000 0101 010F 0000 0000 0000 
\       0000 0000 0000 0000 0000 ]DATA

\ draw initial screen
0 0 0280 22 HCHAR       \ initial field
   \ draw random patches
\ draw lakes
7 08 GOTOXY ." (*,.02"   7 09 GOTOXY ." )77773"
7 0A GOTOXY ." (77773"   7 0B GOTOXY ." )+-/13"
013 08 GOTOXY ." (*,.02"   013 09 GOTOXY ." )77773"
013 0A GOTOXY ." (77773"   013 0B GOTOXY ." )+-/13"
DP !  \ retore dictionary
DECIMAL 4 22 GOTOXY KEY DROP TEXT80 

 

 

 

The above code is on block #2 of the attached STRATEGO blocks file. attachicon.gifSTRATEGOfbf.zip

If you have the file on DSK2, you can run it with the following code:

USEBFL DSK2.STRATEGO
2 LOAD

A blinking cursor indicates when the code is done. You may exit by tapping any key.

 

...lee

 

Certainly wakes up quickly. Nice work!

Link to comment
Share on other sites

Lee, are there any pieces of this that you want assistance with.

Happy to help if you see a partition.

I understand that it can seem as much work to manage the other person as just doing the work so no pressure.

 

Here if you need me.

Link to comment
Share on other sites

Lee, are there any pieces of this that you want assistance with.

Happy to help if you see a partition.

I understand that it can seem as much work to manage the other person as just doing the work so no pressure.

 

Here if you need me.

 

Right now I am just futzing around with what might work, what might be easiest, most compact, quickest. For instance, I first thought of slapping the whole screen up the same way I did the the PDT—still might go with that. But, I got to thinking some more [always dangerous :grin:] about the random elements and thought it might be better to paste it up with code. I though the 640-byte, single HCHAR statement was pretty cool, but then I forgot to VCHAR the vertical sides (I will correct that later).

 

Also pondered how to handle restoring background when pieces are moved. Thought of keeping a screen copy in RAM to grab those background pieces—only need 640 bytes. There must be a way to simplify handling this 10x10 board with its 3x2 “squares”—even with its forbidden zones.

 

As you can see, I do not have much of a plan, yet. You may also have noticed that, out of the gate, I have a bad habit of finding the most difficult, tedious or convoluted way of solving a problem. You seem to have a better grasp of the overview, whereas I often get pretty myopic. Working parallel paths can certainly get messy and time-consuming, but can also help to explore all the options. Even though I got us into this mess |:), there is no reason for you to back peddle your ideas. But, I digress ....

 

How is that for direction?

 

...lee

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...