Jump to content
IGNORED

Assembly BYTE and more questions


jchase1970

Recommended Posts

This might be a dumb question... more often than not the Lottrup book (while brilliant) confuses the shit out of me unnecessarily.

 

The character table... assuming I want to change the definition of character 128 or character >80, is there a simple way to determine how to address that particular 8 byte chunk? A reference for each location? For instance, according to the Lottrup book, character #35 starts at >0918, increasing by 8 bytes for each character definition. If I wish to redefine character 128, I take >0918 and add 93*8 to it? Is this correct?

 

Or am I totally missing the point.....

 

This is very much an issue of me thinking in dec and not hex

Link to comment
Share on other sites

This might be a dumb question... more often than not the Lottrup book (while brilliant) confuses the shit out of me unnecessarily.

 

The character table... assuming I want to change the definition of character 128 or character >80, is there a simple way to determine how to address that particular 8 byte chunk? A reference for each location? For instance, according to the Lottrup book, character #35 starts at >0918, increasing by 8 bytes for each character definition. If I wish to redefine character 128, I take >0918 and add 93*8 to it? Is this correct?

 

Or am I totally missing the point.....

 

This is very much an issue of me thinking in dec and not hex

 

Yes, that is correct. A better way to think of it is like this:

 

Address of character = Starting address + ( character value * 8 )

 

In assembly, you can do this by having an equated label to the address. A code snippet is below:

 

CHRPAT EQU  >0800
.
.
.
* Read a character pattern into BUFFER, @CHAR contains character to read
      LI   R0,CHRPAT
      MOV  @CHAR,R1
      SLA  R1,3
      A    R1,R0
      LI   R1,BUFFER
      LI   R2,8
      BLWP @VMBR

 

Does that clear it up?

 

Adamantyr

Edited by adamantyr
Link to comment
Share on other sites

Ugh... man, I tell ya... As much as I try--- as many times as I've tried to write in assembly, it still just makes my brain explode. I've been sitting here staring at this book and trying a hundred different things and it's just not happening. I'm trying to work on a little something for Keith and his Dead Station game, but it's frustrating beyond description. It's such a simple thought... redefine ONE character, change ONE character set color, draw the 768 bytes I have already onto the screen. Drawing is easy.

 

DEF START
REF VMBW
START

LI 	R0,0
LI 	R1,MD0
LI 	R2,768
BLWP   @VMBW
LP LIMI   2
JMP	LP

 

Tables just confuse me. I don't know...

 

And my syntax and spacing got screwed up in the above example... I am aware the labels, instructions and operands are not spaced correctly...

Edited by Opry99er
Link to comment
Share on other sites

Ugh... man, I tell ya... As much as I try--- as many times as I've tried to write in assembly, it still just makes my brain explode. I've been sitting here staring at this book and trying a hundred different things and it's just not happening. I'm trying to work on a little something for Keith and his Dead Station game, but it's frustrating beyond description. It's such a simple thought... redefine ONE character, change ONE character set color, draw the 768 bytes I have already onto the screen. Drawing is easy.

 

DEF START
REF VMBW
START

LI 	R0,0
LI 	R1,MD0
LI 	R2,768
BLWP   @VMBW
LP LIMI   2
JMP	LP

 

Tables just confuse me. I don't know...

 

Think of it like this... the VDP is just data storage. There's nothing there BUT data. All you need to know is where to find it, and what order it's in.

 

Also, doing BASIC/Assembly cross-over work is seriously brain-hemorrhaging hard stuff. I tried to do it myself back in my teens, and couldn't grok it at all. I wondered how on earth anyone learned assembly programming that way.

 

Adamantyr

Link to comment
Share on other sites

I am writing just an assembly routine. EA3. It's just all the figuring of where the data needs to go, offsets, buffers, bytes words.... It's the whole concept. I understand WHY it all works and even HOW it works.... It's the execution of it that makes my eyes bleed. I've never thought this way... I've only ever coded in BASIC languages, TI and bAtari. I wish it were intuitive to me, as it seems to be for so many of my colleagues here. I'll keep reading and trying. Nothing to it but to do it, right?

Link to comment
Share on other sites

Each tile (character) requires 8 bytes to define the pattern (which I assume you know by now). First find the start of the tile you wish to change. Since there are 256 tiles (numbered 0 to 255), you multiple the tile number you are looking for by 8:

 

Tile  Bytes
0     0 - 7 (total of 
1     8 - 15
2     16 - 23
.
128    1024 - 1031
.
255    2040 - 2047

 

The tile bytes are numbered 0 to 2047, for a total of 2048 (2K or >0800) bytes for all 256 tile patterns.

 

That is the first step. Now that you know the starting byte to the tile you want to change, you need to add that to the starting address of the PDT (pattern descriptor table). Thus your "tile number" becomes an "offset" into the PDT, which will be located in VDP RAM at some location determined by VDP Register-4. If the PDT happens to be set to start at VRAM address zero (>0000), then your tile number (index) can be used directly, since 0 + tile_num = tile_num.

 

Since the VDP registers are write-only, you can't find out what address the PDT is set to, so you have to set it to make sure it is at a known location. And, since *you* are setting the PDT start address, you know where it is, and you can use an EQUate in your code to find tile pattern locations at assembly-time or run-time.

 

It does not matter if you do the math in decimal or hex. In assembly, and computers in general, it is typical to represent addresses and memory sizes with hex notation.

 

Let me know if you need some examples.

 

Matthew

Link to comment
Share on other sites

I am writing just an assembly routine. EA3. It's just all the figuring of where the data needs to go, offsets, buffers, bytes words.... It's the whole concept. I understand WHY it all works and even HOW it works.... It's the execution of it that makes my eyes bleed. I've never thought this way... I've only ever coded in BASIC languages, TI and bAtari. I wish it were intuitive to me, as it seems to be for so many of my colleagues here. I'll keep reading and trying. Nothing to it but to do it, right?

 

It isn't an easy transition from an imperative language like BASIC, I'll agree. I didn't quite grasp it myself as a teen either. I kept thinking "What's the command to do this?" It wasn't until I was back in college years later that I had my "Eureka!" moment.

 

Maybe the best way to try and approach it is to think of the command in BASIC/extended BASIC you want to use, and then ask yourself "Now how would that command actually work? What would it actually do in assembly?" Start with something simple, CALL COLOR.

 

Adamantyr

Link to comment
Share on other sites

Thanks guys... maybe today's not my day. I've been beating my head in for the last 2 hours with absolutely no success whatsoever. All I've done is create Keith's Dead Station graphic on my end. Here's what it looks like on my editor:

 

keith.jpg

 

So, my map data looks like this:

 

 

 

MD0	DATA >2020,>2020,>2020,>2020	;
  	DATA >2020,>2020,>2020,>2020	;
  	DATA >2020,>2020,>2020,>2020	;
  	DATA >2020,>2020,>2020,>2020	;
* -- Map Row 1 --                   	
  	DATA >2020,>2020,>2020,>2020	;
  	DATA >2020,>2020,>2020,>2020	;
  	DATA >2020,>2020,>2020,>2020	;
  	DATA >2020,>2020,>2020,>2020	;
* -- Map Row 2 --                   	
  	DATA >2020,>2020,>2020,>2020	;
  	DATA >2020,>2020,>2020,>2020	;
  	DATA >2020,>2020,>2020,>2020	;
  	DATA >2020,>2020,>2020,>2020	;
* -- Map Row 3 --                   	
  	DATA >2020,>2020,>2020,>2020	;
  	DATA >2020,>2020,>2020,>2020	;
  	DATA >2020,>2020,>2020,>2020	;
  	DATA >2020,>2020,>2020,>2020	;
* -- Map Row 4 --                   	
  	DATA >2020,>2020,>2020,>2020	;
  	DATA >2020,>2020,>2020,>2020	;
  	DATA >2020,>2020,>2020,>2020	;
  	DATA >2020,>2020,>2020,>2020	;
* -- Map Row 5 --                   	
  	DATA >2020,>2020,>2020,>2020	;
  	DATA >2020,>2020,>2020,>2020	;
  	DATA >2020,>2020,>2020,>2020	;
  	DATA >2020,>2020,>2020,>2020	;
* -- Map Row 6 --                   	
  	DATA >2020,>2020,>2020,>2020	;
  	DATA >2020,>2020,>2020,>2020	;
  	DATA >2020,>2020,>2020,>2020	;
  	DATA >2020,>2020,>2020,>2020	;
* -- Map Row 7 --                   	
  	DATA >2020,>2020,>2080,>8080	;
  	DATA >8080,>8080,>8080,>8080	;
  	DATA >8080,>8080,>8080,>8080	;
  	DATA >8080,>8020,>2020,>2020	;
* -- Map Row 8 --                   	
  	DATA >2020,>2020,>2080,>2020	;
  	DATA >8020,>2080,>2020,>2020	;
  	DATA >8020,>2080,>2020,>2020	;
  	DATA >2020,>8020,>2020,>2020	;
* -- Map Row 9 --                   	
  	DATA >2020,>2020,>2080,>2020	;
  	DATA >8020,>2020,>2020,>2020	;
  	DATA >2020,>2080,>2020,>2020	;
  	DATA >2020,>8020,>2020,>2020	;
* -- Map Row 10 --                  	
  	DATA >2020,>2020,>2080,>2020	;
  	DATA >8020,>2020,>2020,>2020	;
  	DATA >2020,>2080,>2020,>8080	;
  	DATA >8020,>8020,>2020,>2020	;
* -- Map Row 11 --                  	
  	DATA >2020,>2020,>2080,>2020	;
  	DATA >8080,>2020,>8080,>2020	;
  	DATA >8080,>8080,>2020,>8080	;
  	DATA >8020,>8020,>2020,>2020	;
* -- Map Row 12 --                  	
  	DATA >2020,>2020,>2080,>2020	;
  	DATA >2020,>2020,>2020,>2020	;
  	DATA >2020,>2020,>2020,>2020	;
  	DATA >2020,>8020,>2020,>2020	;
* -- Map Row 13 --                  	
  	DATA >2020,>2020,>2080,>2080	;
  	DATA >8020,>2020,>2020,>2020	;
  	DATA >2020,>2080,>8020,>8080	;
  	DATA >8080,>8020,>2020,>2020	;
* -- Map Row 14 --                  	
  	DATA >2020,>2020,>2080,>2080	;
  	DATA >2020,>8020,>8020,>2020	;
  	DATA >8020,>2080,>8020,>8080	;
  	DATA >8080,>8020,>2020,>2020	;
* -- Map Row 15 --                  	
  	DATA >2020,>2020,>2080,>2080	;
  	DATA >8020,>2020,>2080,>2080	;
  	DATA >2020,>2020,>2020,>2020	;
  	DATA >2020,>8020,>2020,>2020	;
* -- Map Row 16 --                  	
  	DATA >2020,>2020,>2080,>2080	;
  	DATA >2020,>8020,>2020,>2020	;
  	DATA >2020,>2080,>8020,>2020	;
  	DATA >2020,>8020,>2020,>2020	;
* -- Map Row 17 --                  	
  	DATA >2020,>2020,>2080,>2080	;
  	DATA >8020,>2020,>8080,>2080	;
  	DATA >8020,>2080,>8020,>8020	;
  	DATA >8020,>8020,>2020,>2020	;
* -- Map Row 18 --                  	
  	DATA >2020,>2020,>2080,>2080	;
  	DATA >2020,>8020,>2020,>2020	;
  	DATA >2020,>2020,>2020,>8020	;
  	DATA >8020,>8020,>2020,>2020	;
* -- Map Row 19 --                  	
  	DATA >2020,>2020,>2080,>2080	;
  	DATA >8020,>2020,>8080,>8080	;
  	DATA >8080,>2020,>2020,>2020	;
  	DATA >2020,>8020,>2020,>2020	;
* -- Map Row 20 --                  	
  	DATA >2020,>2020,>2080,>2020	;
  	DATA >2020,>2020,>2020,>2020	;
  	DATA >2020,>2020,>2020,>8080	;
  	DATA >8020,>8020,>2020,>2020	;
* -- Map Row 21 --                  	
  	DATA >2020,>2020,>2080,>2020	;
  	DATA >8020,>8020,>2080,>2020	;
  	DATA >8020,>2080,>8020,>8080	;
  	DATA >8020,>8020,>2020,>2020	;
* -- Map Row 22 --                  	
  	DATA >2020,>2020,>2080,>2020	;
  	DATA >2020,>2020,>2080,>8080	;
  	DATA >8020,>2080,>8020,>2020	;
  	DATA >2020,>8020,>2020,>2020	;
* -- Map Row 23 --                  	
  	DATA >2020,>2020,>2080,>8080	;
  	DATA >8080,>8080,>8080,>8080	;
  	DATA >8080,>8080,>8080,>8080	;
  	DATA >8080,>8020,>2020,>2020	;

 

 

 

My pattern definition I needed to do is simply >FFFF,>FFFF,>FFFF,>FFFF. Just a block--- solid and white. The color definitions I'm using look like this:

 

CLRSET DATA >1000,>1000,>1000,>1000 ;

DATA >1000,>1000,>1000,>1000 ;

DATA >1000,>1000,>1000,>1000 ;

DATA >1000,>1000,>1000,>1000 ;

DATA >F000,>1000,>1000,>1000 ;

DATA >1000,>1000,>1000,>1000 ;

DATA >1000,>1000,>1000,>1000 ;

DATA >1000,>1000,>1000,>1000 ;

 

As you can see, just one color redefine... White for the colorset corresponding with the defined character... I believe it's character set 14.

 

So what I need to do is redefine character 128, color it white, and then display the 768 bytes on the screen. The screen drawing is not hard, it's the rest that confuses me. I hope I'm not annoying you guys with this stuff... I know it's easy, but I'm just not getting it, and its more an indication of mental shortcomings than the complexity of the language.

Link to comment
Share on other sites

Well, they are probably using a set of default values in the book. Either the values set by XB, or by the console at power-on. Since you are trying to work in a mixed assembly / XB environment, you need to know where XB sets up the tables. Also, XB does not allow full use of the entire tile range, *and* it adds some offset to the tile values themselves. All-in-all a pain in the ass and nothing but added confusion.

 

I'll try to get an example for you.

 

Matthew

Link to comment
Share on other sites

So if I use an equate....

CHRPT EQU >0800

 

Then that places my PDT at that specific location... See, another example of this book confusing the hell out of me... All the tables and such are at hard locations in this book....

 

I think I see part of your problem here...

 

The EQU label is not saying "Put the character pattern table here" or "the character pattern table is here". It is literally just saying "this label points to this address".

 

It is used by the compiler and the programmer to replace something that would ordinarily be a number with a label so that, if you decide you want to move it to another location later, you can just change a single label and have it change everywhere.

 

So what does determine the character pattern table location? The settings in the VDP registers. And they have default settings coming from the E/A cartridge as follows:

 

R1=E0 Standard mode

R2=00 Screen image at >0000

R3=0E Color table at >0380

R4=01 Char pattern table at >0800

R5=06 Sprite attribute table at >0300

R6=00 Sprite pattern table at >0000 (not the same as char pats!)

R7=F5 White on blue

 

Does that help you grok this a bit better?

 

Adamantyr

Link to comment
Share on other sites

Thanks Matthew... But actually for this particular example, I'm just trying to get a straight assembly EA3 program to work... No XB involved. I wanted to get THAT working before I tried to do anything with BASIC hybridization. I can't even do THAT simple task without this much stress. All I wanted to do was draw the thing in assembly.... Then I was going to try to add some of the other colored tiles Keith had in his example.... Just do a piece by piece assembly version of his screen there.... If I could make all that work, I thought I might try to change it over for XB use. ;)

Link to comment
Share on other sites

Owen here is a small program to computer addresses

 

5 CALL CLEAR
10 INPUT "ENTER YOUR CHARACTER PATTERNTABLE STARTING ADDRESS >":B
20 PRINT "PRINT YOU ENTER >"&STR$(B)
25 PRINT
30 PRINT "PRESS Y IF THAT IS CORRECT"
40 PRINT "PRESS N IF THAT IS WRONG"
50 CALL KEY(0,K,S)
60 IF S=0 THEN 50
70 IF(K=89)+(K=121)THEN 100
80 IF(K=78)+(K=110)THEN 10
90 GOTO 50
100 INPUT "ENTER CHARACTER NUMBER TO   CONVERT TO ADDRESS:":A
110 PRINT "CHARACTER";A;"IS AT >"&STR$(B+(A*)
115 PRINT
120 GOTO 100

Edited by jchase1970
Link to comment
Share on other sites

New question,

 

DIV G,WR*

 

Divides the contents of the words in Workspace

Register 3 and Workspace Register 4 by the

value of ADR plus Workspace Register 2 and

stores the integer result in Workspace Register 3

with the remainder in Workspace Register 4.

 

Ok, I get it that this is a 32bit function and returns a 16bit balue

 

so DIV 2,R3

if R3=0 and R4=10 then the value for the dividend is 10

now 10/2 is 5

so R3=5 and R4=0?

 

if I'm right so far,

Div 4,R3 *same values

10/4=2.5

R3=2 and R4=5

 

One more step and my question if I'm right so far

New values R3=0, R4=17

DIV 8,R3

17/8=2.125

R3=2 and R4=?

is R4 1 or 125

If it stores the whole decimal remainder whats the cut off 1/1000?

 

John

Link to comment
Share on other sites

DIV can't use immediate values, the destination must be a workspace register and the source can use any of the addressing modes. DIV is "kind of" a 32-bit operation in that the dividend is a 32-bit value, but the divisor is a 16-bit value. The quotient goes into the dividend address, and the remainder goes into the dividend address + 1 (where 1 represents a 16-bit word, not a byte.)

 

       LI   R2,10    R2 will be the divisor
       CLR  R3       R3+R4 will be the 32-bit dividend
       LI   R4,123
       DIV  R2,R3    Divide 123 by 10

 

After the DIV instruction above, R3 will contain 12 and R4 will contain 3, and R2 is unchanged. You don't have to use R2, R3, and R4, but the dividend must be a register and will always be that register combined with the next register to make a 32-bit number.

 

Here is a bigger example with a source value that does not fit in a single 16-bit value.

 

DIVIDE DATA 1234       Divisor must be a 16-bit value
.
.
.
       LI   R8,>000F     Load 32-bit dividend with >000FFFFF
       LI   R9,>FFFF
       DIV  @DIVIDE,R8   Divide: 1,048,575 / 1,234 = 849 remainder 909

 

After the DIV, R8 would contain 849 and R9 would contain 909.

 

Matthew

Link to comment
Share on other sites

Here is a bigger example with a source value that does not fit in a single 16-bit value.

 

DIVIDE DATA 1234       Divisor must be a 16-bit value
.
.
.
       LI   R8,>000F     Load 32-bit dividend with >000FFFFF
       LI   R9,>FFFF
       DIV  @DIVIDE,R8   Divide: 1,048,575 / 1,234 = 849 remainder 909

 

After the DIV, R8 would contain 849 and R9 would contain 909.

 

One other point, DIV and MPY are both unsigned operations. Signed operations require a bit of extra work; you'll have to store the sign bits for divisor and dividend and restore the true value after completing operations.

 

Curiously, the only two new opcodes added in the TMS9995 processor were signed multiply and divide operators.

 

Adamantyr

Link to comment
Share on other sites

  • 4 weeks later...

Two questions on the fallowing code piece.

 

*VDP MEMORY MAP

VDPRD  EQU   >8800
VDPSTA EQU   >8802
VDPWD  EQU   >8C00
VDPWA  EQU   >8C02

*WORKSPACE

WRKSP  EQU   >8300
R0LB   EQU   WRKSP+1
R1LB   EQU   WRKSP+3
R2LB   EQU   WRKSP+5
R3LB   EQU   WRKSP+7
R4LB   EQU   WRKSP+9

MAIN
L10    BL    @CLS
      END   MAIN


*BASIC COMMANDS
CLS    LI    R0,0
      LI    R1,>2000
      LI    R2,768
      BL    @VMBW
      B     *R11

*ASSEMBLE COMMANDS

VMBW   MOVB @R0LB,@VDPWA
      ORI  R0,>4000
      MOVB R0,@VDPWA
VMBWLP MOVB *R1+,@VDPWD
      DEC  R2
      JNE  VMBWLP
      B    *R11

END

 

this line

L10    BL    @CLS

comes up with a undefined symbol error I don't know why.

 

 

And 2 I guess this code wont work anyway because I'm BLing in a BLing,

L10    BL    @CLS    <-----HERE
      END   MAIN


*BASIC COMMANDS
CLS    LI    R0,0
      LI    R1,>2000
      LI    R2,768
      BL    @VMBW    <----HERE
      B     *R11

*ASSEMBLE COMMANDS

VMBW   MOVB @R0LB,@VDPWA
      ORI  R0,>4000
      MOVB R0,@VDPWA
VMBWLP MOVB *R1+,@VDPWD
      DEC  R2
      JNE  VMBWLP
      B    *R11

So am I right now thinking you can't BL in a BL because it will store only 1 return address in R11?

Edited by jchase1970
Link to comment
Share on other sites

What assembler are you using? I'm not sure why it would be complaining about CLS.

 

Also, the assembler does not interpret your code, so the fact that you are executing a BL without saving R11 is inconsequential. As written, the code won't return though. The B *R11 from the VMBW routine will return to the instruction following the BL @VMBW line, which is B *R11, which is now pointing to itself, thus you have an infinite loop.

 

Before you call BL @VMBW from within your CLS function, you have to save R11, and restore it before B *R11 from the CLS function.

 

See my "Assembly My Way" thread, there is a long segment on a doing all of this, including managing a pseudo-stack for just such a thing.

 

Matthew

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