Jump to content
IGNORED

Assembly->XB link project


Opry99er

Recommended Posts

So, I know we've talked about this at one point, but I can't seem to find the thread. How much space is available for machine code when in the XB environment? If I remember correctly, it's something like 8k. Much of the low memory available on the /4a gets devoured by the XB architecture---

 

This is what Matthew went through while building his sound player--- I have re-read his journal entry about the development and have some questions... So Matthew, if you're reading, here's my idea, perhaps you can help.

 

I want to load 4 704 byte maps into low memory at a time along with the sound player and a soundlist. Each screen map is 704 bytes, since two full rows are used for stats and will not be re-drawn.

 

The goal: take a SPRITE across the screen, when the SPRITE reaches the edge, call an assembly routine to draw the "next" screen. I will not need to have 4 in memory for every circumstance, but 4 is the most I will need at any time. I'll diagram my requirements later... In the meantime, I'll continue doing research and if you guys can give me an idea about space limitations beyond what Matthew cited in his XB sound player notes, I'd be appreciative!!

Edited by Opry99er
Link to comment
Share on other sites

I have a method of creating INTERNAL format representations of my maps... Adamantyr helped make this work. =) Thanks for that....

 

I have attached a DSK1 zip folder... Inside that are 8 TIFILES files. The listing is below

 

1

2

3

4

5

6

LOAD

TOGGLE

 

The files named "1"-"6" are data files, "LOAD" is just a LOAD program for "TOGGLE". "TOGGLE" is the business end of it. You can read in the listing below what it does. It is basically very simple. It does the following things:

 

1) CALL SCREEN BLACK

2) CALLs COLORs for the display

3) CALLs CHARs for the display

4) READs DATA from the DATA files on the disk

5) Writes INTERNAL format DATA to the screen

 

I have posted the code below. Anyway, this is a demonstration of the method I want to use. Right now, it just toggles through all 6 DATA files and then starts at the beginning again. Works best under Classic99 in "CPU Overdrive" mode.

 

Now, imagine if (instead of toggling through), you controlled a SPRITE and moved towards a screen border... Upon arriving there, and depending on WHICH border you touch, the program would go to this routine and call up the required file to draw to the screen. In XB, it is a bit slow. But it would be quite simple to do it in assembly, simply reach into the VDP RAM and draw 704 bytes to the screen quickly. (In the attached file, I write all 768 screen positions, but it is not necessary-- as there is a border)

 

So using this method, it is my intent to do this with Calimari Carl...

 

This is the collapsed codebox showing what the "TOGGLE" program looks like.

 

 

 

90 CALL SCREEN(2)
100 RESTORE 1110 :: FOR S=1 TO 14 :: READ F,B :: CALL COLOR(S,F,B) :: NEXT S
110 RESTORE 500 :: FOR C=1 TO 22 :: READ CN,CC$ :: CALL CHAR(CN,CC$) :: NEXT C
140 CALL CLEAR
145 FOR X=1 TO 6
146 SC$="DSK1."&STR$(X)
150 OPEN #1:SC$,INPUT,INTERNAL
160 FOR R=1 TO 24 :: INPUT #1:R$ :: CALL HCHAR(R,1,ASC(SEG$(R$,1,1))) :: CALL HCHAR(R,2,ASC(SEG$(R$,2,1)))
170 DISPLAY AT(R,1):SEG$(R$,3,28) :: CALL HCHAR(R,31,ASC(SEG$(R$,31,1))) :: CALL HCHAR(R,32,ASC(SEG$(R$,32,1)))
180 NEXT R :: CLOSE #1
184 FOR DELAY=1 TO 1000 :: NEXT DELAY
185 NEXT X
190 GOTO 145
500 DATA 96,"FFFF00000000FFFF",97,"C3C3C3C3C3C3C3C3",98,"FFFFC0C0C0C0C3C3",99,"C3C3C0C0C0C0FFFF"
510 DATA 100,"FFFF03030303C3C3",101,"C3C303030303FFFF",102,"38606E334979018F",103,"FFFDBFFBFFDFFEFF"
520 DATA 104,"C3241800C3241800",112,"181C36315E448212",113,"1818FFFF18181818",114,"0018382464D08202"
530 DATA 115,"03070E9C7830D0C8",120,"070F1F1C1C1F1F1F",121,"E0F0F83838F8F8F8",122,"8080F0888880C0E0"
540 DATA 123,"01010F1111010307",128,"000E7BF9BFFC1C1E",129,"FFFFFFFFFFFFFFFF",136,"8104002002882200"
550 DATA 137,"380AD1C988087337",138,"00E0A0BFA5E50100"
1110 DATA 2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,11,1,6,5,15,1,2,11,13,4,2,3

 

 

 

DL the attached file if you'd like. I am using the screenshots from my early "Forest World" development from "Beryl Reichardt".

DSK1.zip

Link to comment
Share on other sites

So Matthew, if you're reading, here's my idea, perhaps you can help.

 

Heh, "if I'm reading"?

 

LOOP    BL  @READ_AA
       CI  @MATEO,>DEAD
       JNE LOOP
       BL  @GOODBAD
       C   R0,@GOOD
       JNE BAD
       B   @HEAVEN
BAD     B   @HELL
       END

 

You have 8K in the lower memory, minus the memory taken up but the routines loaded when you CALL LINK. I can't remember how much that is, but 2K sounds about right. Four 704-byte screens is 2816 bytes, which will easily fit. I don't remember how big the sound player is, but the routine to draw the screen will be small, so it comes down to how much room you want for sounds.

 

Is the sprite reaching the edge going to be handled by XB code, or do you want that in the assembly code as well? Having assembly do it will complicate the code, but mostly because of all the parameters that would have to be passed. Maybe the parameter code for the sound player could be reused? I'll have to review the code to see.

 

I suggest you stay away from trying to use VRAM. Even though there is plenty of VRAM for exactly this kind of thing when writing code exclusively in assembly (I think you could actually store 8 "screens" in available VRAM and simply "flip" to one), XB uses VRAM so heavily and dynamically that you will most likely crash. Tursi and I could not get a stable sound player working in VRAM, so I don't have any desire to try that route again.

 

Matthew

Link to comment
Share on other sites

Gotcha....

 

Everything in this program will be XB except for screen draws and music. All the screen draw routine will do is take a value passed from XB and draw the necessary bytes to the screen, then pass control back to XB. Imagine "Zelda". Player reaches right side of screen, assembly draws the next screen, player SPRITE is transported to the left side of the screen, repeat game loop.

 

:)

Edited by Opry99er
Link to comment
Share on other sites

Pseudo-code below

 

100 CALL SCREEN(2)
110 Draw screen in XB
120 CALL SPRITE(#1)
130 CALL JOYST
140 Move sprite according to JOYST input
150 CALL POSITION
160 IF SPRITE is at left side of the screen then X=1
170 IF SPRITE is at top of the screen, then X=2
180 IF SPRITE is at right side of the screen, then X=3
190 IF SPRITE is at bottom of screen, then X=4
200 Pass value to assembly routine, CALL LINK
210 Move SPRITE to opposite side of the screen
220 GOTO 130

 

This is sloppy and inaccurate, but it is the general idea. Like I said, Zelda-ish. =)

Link to comment
Share on other sites

  • 2 weeks later...

Here's the way this works in my estimation....

100 CALL INIT
110 CALL LOAD(-28672,2)
120 CALL LOAD("DSK1.MAPDRW")
130 CALL LINK("DRAW")

This would place the value of >02 at memory address >9000, then branch to "DRAW" which will do something like

DRW2
     LI R4,@>9000
     CI R4,2
     JNE DRW3
     LI R0,0
     LI R1,MAP2
     LI R2,768
.
.

print 768 bytes
     B,*R11

 

Well.... I think I'm on the right track-- I'll test tomorrow sometime and see. :)

Edited by Opry99er
Link to comment
Share on other sites

Problems:

 

1. Address >9000 is not RAM.

2. You are trying to set up a parameter prior to even loading your code.

3. Yes, passing values from XB to the assembly code is a pain in the ass, but I worked it all out in the sound player, so you should really look at that code.

 

An easier way to choose what map to draw would be to simply set up an entry point for each map:

 

      DEF  MAP1,MAP2,MAP3,MAP4

VDPWD  EQU  >8C00          ; VDP write data
VDPWA  EQU  >8C02          ; VDP set read/write address

MAP1   LI   R1,MDATA1
      JMP  MDRAW
MAP2   LI   R1,MDATA2
      JMP  MDRAW
MAP3   LI   R1,MDATA3
      JMP  MDRAW
MAP4   LI   R1,MDATA4

* Direct VMBW
MDRAW
      LIMI 0              ; Must disable interrupts for any VDP access
      CLR  R0             ; Screen name table base address
      LI   R2,768

*      This code takes advantage of the fact that R0 is zero.
      MOVB R0,@VDPWA      ; Send low byte of VDP RAM write address (zero)
      ORI  R0,>4000       ; Set read/write bits 14 and 15 to write (01)
      MOVB R0,@VDPWA      ; Send high byte of VDP RAM write address (zero)
LP     MOVB *R1+,@VDPWD    ; Write byte to VDP RAM
      DEC  R2             ; Byte counter
      JNE  LP             ; Loop if not done

      LIMI 2              ; Enable interrupts
      B    *R11           ; Return to XB

MDATA1 DATA . . .

MDATA2 DATA . . .

MDATA3 DATA . . .

MDATA4 DATA . . .

      END

 

To use from XB:

 

CALL INIT
CALL LOAD("DSK1.MAPDRAW")

IF MAP=1 THEN CALL LINK(MAP1)
IF MAP=2 THEN CALL LINK(MAP2)
IF MAP=3 THEN CALL LINK(MAP3)
IF MAP=4 THEN CALL LINK(MAP4)

 

Matthew

Link to comment
Share on other sites

Yea... that looks pretty sweet. I used just the address I found in Lottrup... I wasn't being very specific.

 

Good stuff, I'll try to do this tomorrow sometime if I get the time. First I need to put borders on the baby steps program. But I always thought if I could figure out how to link up assembly with my XB stuff, I could make it so much faster. Honeycomb Rapture could draw in zero seconds flat as opposed to the 7 seconds it takes to draw in XB... tons of DISPLAY ATs and the like. =)

 

Again, thank you Matthew... your assembly reading materials are great. When I return to the forum tomorrow, I will have borders done in the baby steps program and I will have successfully linked an XB and assembly program. Much obliged, sir.

Link to comment
Share on other sites

  • 2 weeks later...

Well, I've had to re-order my schedule because I didn't want to let this sit for too long. I've re-configured a portion of my Beryl Reichardt Forest world... Using the same tilesets, I completely re-organized my priorities AND the world all at once. Currently, I have 6 sections of a large map which I am displaying one at a time. Each section is 26x12 tiles, so DISPLAY AT will work while I test this out. Here's the big picture (zoomed out)

 

fullforest1.jpg

 

 

 

 

I have taken this and divided it up into 6 equally sized 26x12 sections, two of which I have shown below INSIDE the display port.

 

forest2.jpg

 

forest1.jpg

 

 

So.... since these new "maps" are only 284 bytes a piece, I imagine I could store at least 10 in low memory and use Matthew's suggestion of:

 

IF A=1 THEN CALL LINK(MAP1)
.
.
.

 

 

This is a pretty cool project to work on. Thanks to Marc Hull, I have a borrowed copy of Lottrup's book which teaches how to link TMS9900 assembly with BASIC. =) I should be able to knock this out during the football games today. =) Thanks to you all for your suggestions--- I will post updates as I make progress.

 

 

***edit***

 

I'll be adding more diversity to these maps, but for now, I'm using these 6 maps (making up the big map) just to test. I had to re-organize tilesets and eliminate some stuff since I will not be using all the character sets available in assembly. I'm down to bare bones. =)

Edited by Opry99er
Link to comment
Share on other sites

Okay.... check these out...

 

VSBW EQU  >2020
VMBW EQU  >2024

 DEF  DRAW
 
 
DRAW LI  R0,300
 LI  R1,MAP
 BLWP @VSBW
 CLR  @>837C 		*clear status BYTE
 B  *R11   		*return to BASIC
 
MAP  DATA >E000

 END

 

This is a simple program to draw a box on the screen... here is the accompanying X-BASIC program.

 

10 CALL INIT
20 CALL LOAD("DSK1.DRAWO")
100 CALL CLEAR :: CALL CHAR(128,"FFFFFFFFFFFFFFFF")
105 CALL COLOR(13,5,1)
110 CALL LINK("DRAW")

 

 

Should work... source assembled well, link seems to work up just fine, but no blue box. I'll keep slugging... I'm sure it's an oversight

 

 

Attached is the zipfile including source, object, and XB program.

 

 

***edit***

I tried changing MAP to

 

MAP 	BYTE >E0

 

but it didn't affect the results.

 

>E0 is the ASCII character for 128 (after factoring in the BASIC/asm offset)

LBAS.zip

Edited by Opry99er
Link to comment
Share on other sites

@sometimes99er....

 

Well, on your suggestion, I made the following modifications...

 


100 CALL INIT
110 CALL LOAD("DSK1.DRAWO")
120 CALL CLEAR :: CALL CHAR(128,"FFFFFFFFFFFFFFFF")
130 CALL COLOR(13,5,1,1,11,11)
140 CALL LINK("DRAW")
150 GOTO 150

 

This works nicely... but I wonder why the colorset problem exists? It's as if my CALL COLOR for the colorset corresponding with CHAR 128 (charset 13) isn't taking the color I'm assigning... dark blue. I'll need to figure this out... any ideas? Perhaps I should move the color re-definitions to AFTER the CALL LINK?

 

***edit***

 

had no effect on the outcome

Edited by Opry99er
Link to comment
Share on other sites

Screen position "300" is (9,12) in XB...

 

CALL GCHAR(9,12,A)

PRINT A

 

the character is 32... space.... but it does not change with the rest... which leads me to believe something is wrong with one or more of my components... I'll test further

Nah, can't be 32 (I set all those to yellow, and we saw you plotted something at screen location 300.

 

300/32 = 9.375 ... Line 9 in assembler is line 10 in Basic. Away with the 9. 0.375*32 = 12 ... Column 12 in assembler is column 13 in Basic.

 

 

Edit: Just changed the European comma to a US period. Basic uses them, bla bla bla

Edited by sometimes99er
Link to comment
Share on other sites

ASCII 197

 

thats fargin strange... I'll offset it accordingly

 

 

***edit***

 

THANKS SOMETIMES!

 

I had been used to using labels for VMBW. I got it now. =) Now I just need some kind of program to change Magellan output for assembler to work with the XB offset.

 

lbaspic.jpg

Edited by Opry99er
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...