Jump to content
IGNORED

Baby Steps


Opry99er

Recommended Posts

Fixed the code, added an interrupt enable/disable at the beginning of my KSCAN loop to allow for exit to title screen.

 

LP
     	LIMI 2
     	LIMI 0

 

 

 

*
* Owen Brand, Nov 13, 2010
*
* Clear the screen.
* Assumes the default graphics mode I.
*
   	DEF  START
   	REF  VSBW,VWTR,VMBW,KSCAN
CTAB	EQU  >0380   		; equate location of colorset table in RAM

* The linker will branch to this location
* to start our program.
START

   	LI R0,CTAB  	; table location
   	LI R1,CSET  	; definitions
   	LI R2,32    	; number of bytes to write
   	BLWP @VMBW

*  	Interrupts need to be disabled any time the VDP
*  	is being accessed.
   	LIMI 0

*  	Always know where your workspace is!
   	LWPI >8300


*  	Set the background color to white >F
*  	VDP register 7 controls the text mode
*  	text color and the background color for
*  	the other modes.  All other VDP registers
*  	are assumed to have set graphics mode 1.

   	LI   R0,>071F      	; Register 7, black on white
   	BLWP @VWTR 			; Write the register


*  	Set up to clear the screen.  Assumes the
*  	Name Table is set to address >0000 in VRAM.
*  	All the names (tile / character values) in
*  	the Name Table will be set to the space character
*  	which is, well, a space, so it has no foreground
*  	bits, so the screen will show only the background
*  	color.
*
*  	Note, only the HIGH BYTE is transfered to the VDP
*  	hence using >2000 loads 32 (>20) into the MSB of R1.

   	CLR  R0            	; Start at >0000 in VRAM.
   	LI   R1,>2000      	; Write 32 (space char)
   	LI   R2,768        	; 32x24 tiles = 768 total to write

LOOP
   	BLWP @VSBW 			; Write the byte
   	INC  R0            	; Next VRAM screen location
   	DEC  R2            	; Count the byte just written
   	JNE  LOOP          	; If not done, write again

*  	The DEC instruction compares the result of the decrement to
*  	zero automatically (as do many instructions), so the JNE is
*  	really saying "jump if R2 is not zero".

*	This will place a "@" at screen location 110
   	LI R0,110 	; Screen location in VDP RAM
LI R1,>4000	; ASCII code for "@"
BLWP @VSBW 	; Write it


JOYCK   LI R1,>0100                 			*check for joystick 1 input
   	MOVB R1,@>8374                      	*check for Y return
LP  	LIMI 2
   	LIMI 0
   	BLWP @KSCAN                 			*check for input
   	CLR  R1                     			*clear register for Y return check
   	MOVB @>8376,R1                      	*move Y return value into MSB of R1
   	CI   R1,>0400               			*is the Y value "4"? (up)
   	JNE  T1                     			*if not, go to the next comparison
   	AI   R0,-32
   	JMP  PRINT
T1  	CI   R1,>FC00               			*compares MSB of R1 to >FC (down)
   	JNE  T2                     			*if not, go to the next comparison
   	AI  R0,32
   	JMP  PRINT
T2  	MOVB @>8377,R1                      	*move X-return byte into R1
   	CI   R1,>0400               			*is the X value "4"? (right)
   	JNE  T3                     			*if not, go to the next comparison
   	INC  R0
 JMP  PRINT
T3  	CI   R1,>FC00               			*final comparison... is the X value >FC? (left)
   	JNE  LP                     			*it was not, therefore no motion happened, jump to KSCAN
   	DEC  R0

PRINT LI  R4,3000   	*Start the delay loop
 DEC  R4 		*decrement register 4 (part of delay)
 JNE  $-2        *jump back one word in memory to DEC
 LI  R1,>4000            	*load the ASCII character to print
 BLWP @VSBW        *print it
 JMP  LP 		*back to KSCAN routine


CSET	BYTE >10,>10,>10,>10        	
   	BYTE >10,>10,>10,>10        	;set "@" to "red"
   	BYTE >C0,>10,>10,>10        	
   	BYTE >10,>10,>10,>10        	
   	BYTE >10,>10,>10,>10 
   	BYTE >10,>10,>10,>10
   	BYTE >10,>10,>10,>10
   	BYTE >10,>10,>10,>10


   	END  START
   

 

 

 

Thanks for all your help guys. =)

 

 

***edit***

Again, it messed up my indentation. =) But whatever. I could attach the actual object code, but it's nothing all that great yet. I'll be adding borders and whatnot tomorrow. I don't know what to do with this next, but probably change it to where it won't create a trail, but re-draw it each time. Then draw some "treasure chests" on the screen (probably just an "X") and allow the user to "pick them up"... Maybe have a status on screen somewhere showing how many the user has collected. Just to get the hang of it. This could end up being the starting skeleton for Calimari Carl in assembly. =)

Edited by Opry99er
Link to comment
Share on other sites

 

3. Personally I'm opposed to the VSBW and company routines, but using them now can help make your code *look* smaller. Just keep in mind that at some point you will need to learn what they do and replace them. Also, remember they *drastically* slow down your program.

 

4. Comment you code. Typically most people comment every line in assembly. I find this a *little* helpful sometimes, but what is more useful is a block comment that describes what the following code does. Use comments of individual instructions to explain why you are using a certain value or memory address.

 

 

I keep hearing about how slow the internal VDP routines are, but quite honestly they fit the bill for the vast majority of the time for most projects. I suggest you stick with them until you hit an unacceptable performance point. Test your program with them, and if you are happy then everything is cool. Otherwise, replace them (not too hard to do). I know the purists here are probably pulling their hair out by now and clamoring for my lynching, but I am a simple guy that does not need to complicate his life unnecessarily :)

As far as commenting, trust me when I say that you cannot comment enough! Since comments do not take any memory space after compilation, go wild! I tend to comment almost every line because I can't understand my own code a couple of days later :D

 

Interesting trivia: In the late 1950's, the legendary MIT hacker Peter Samson was notorious for not commenting his code with ONE exception: In one well distributed program running for hundreds of lines, there was only one comment next to an instruction containing the number 1750. The comment was RIPJSB. Can you figure it out? :? (source: Hackers by Steven Levy. Amazing book if you have never read it).

Link to comment
Share on other sites

Pretty cool how small the object code is. =) I wonder if there's anyone who can read this and tell what it does... without seeing source. =)

 

 

 

000BA    	A0000B0200B0380B0201C009AB0202B0020B0420B0000B03007F369F   	0001
A0012B0000B02E0B8300B0200B071FB0420B0000B04C0B0201B2000B02027F347F      	0002
A0028B0300B0420B0000B0580B0602B16FBB0200B006EB0201B4000B04207F331F      	0003
A003EC002CB0201B0100BD801B8374B0300B0002B0300B0000B0420B00007F33FF      	0004
A0054B04C1BD060B8376B0281B0400B1603B0220BFFE0B1011B0281BFC007F2CAF      	0005
A006AB1603B0220B0020B100BBD060B8377B0281B0400B1602B0580B10047F31BF      	0006
A0080B0281BFC00B16E1B0600B0204B0BB8B0604B16FEB0201B4000B04207F2D8F      	0007
A0096C003EB10D7B1010B1010B1010B1010BC010B1010B1010B1010B10107F34AF      	0008
A00ACB1010B1010B1010B1010B1010B1010B10107F788F                          	0009
200007FED7F                                                             	0010
50000START 30096VSBW  3001EVWTR  3000EVMBW  30052KSCAN 7F2F8F           	0011
:   	99/4 AS                                                         	0012

 

 

Link to comment
Share on other sites

I keep hearing about how slow the internal VDP routines are, but quite honestly they fit the bill for the vast majority of the time for most projects. I suggest you stick with them until you hit an unacceptable performance point. Test your program with them, and if you are happy then everything is cool. Otherwise, replace them (not too hard to do). I know the purists here are probably pulling their hair out by now and clamoring for my lynching, but I am a simple guy that does not need to complicate his life unnecessarily :)

As far as commenting, trust me when I say that you cannot comment enough! Since comments do not take any memory space after compilation, go wild! I tend to comment almost every line because I can't understand my own code a couple of days later :D

You're right. :)

 

PS. I don't use them, so ... ;)

 

Interesting trivia: In the late 1950's, the legendary MIT hacker Peter Samson was notorious for not commenting his code with ONE exception: In one well distributed program running for hundreds of lines, there was only one comment next to an instruction containing the number 1750. The comment was RIPJSB. Can you figure it out? :? (source: Hackers by Steven Levy. Amazing book if you have never read it).

"Rest In Peace Johann Sebastian Bach" (year of death). :cool:

Edited by sometimes99er
Link to comment
Share on other sites

 

Interesting trivia: In the late 1950's, the legendary MIT hacker Peter Samson was notorious for not commenting his code with ONE exception: In one well distributed program running for hundreds of lines, there was only one comment next to an instruction containing the number 1750. The comment was RIPJSB. Can you figure it out? :? (source: Hackers by Steven Levy. Amazing book if you have never read it).

"Rest In Peace Johann Sebastian Bach" (year of death). :cool:

 

Ahhh! You read the book! if not, well chapeau bas!

Link to comment
Share on other sites

Interesting trivia: In the late 1950's, the legendary MIT hacker Peter Samson was notorious for not commenting his code with ONE exception: In one well distributed program running for hundreds of lines, there was only one comment next to an instruction containing the number 1750. The comment was RIPJSB. Can you figure it out? :? (source: Hackers by Steven Levy. Amazing book if you have never read it).

 

An excellent book. Fantastic and full of our history. Not many people know that "hacking" started with model railroad Signals and Lights. Read up on "Blatties" and "yellow gunkies." Now I have a hankering to dig it out and read it again.

 

Another good book to read is "Soul of a New Machine."

 

Yeah, the kernal code (SEMP: System Event Monitoring Procedure) for my Commodore 64 BBS program had a comment on just about every line. In a lot of cases it was something like "WTF was I thinking here?" or "I'm not sure why this works."

 

Thinking about Head-Slapping Moments in Assembly Language Programming , I was writing a simple screen blanker module for the BBS, a clone of the blanker in the TI. Of course it did not work properly and I had the damnedest time figuring it out. I even rewrote the code. I left it in frustration and came back to it later, and there it was starting me right in the face. If you are familiar with 6502 assembly then you know how CMP works with BNE and BEQ. Right there... there it was, a BEQ instead of a BNE (or opposite, I cannot quite recall and I think this part changes every time I tell the story.)

Link to comment
Share on other sites

 

Thinking about Head-Slapping Moments in Assembly Language Programming , I was writing a simple screen blanker module for the BBS, a clone of the blanker in the TI. Of course it did not work properly and I had the damnedest time figuring it out. I even rewrote the code. I left it in frustration and came back to it later, and there it was starting me right in the face. If you are familiar with 6502 assembly then you know how CMP works with BNE and BEQ. Right there... there it was, a BEQ instead of a BNE (or opposite, I cannot quite recall and I think this part changes every time I tell the story.)

 

Damn that sounds familiar :) For me, the most common error is forgetting that byte operations are done on the most significant byte of a word. My palm is still imprinted on my forehead. Have to go: I'm playing Orbiter on my Pcjr and I have to begin the deorbit procedure!

Link to comment
Share on other sites

Looking good, Owen! Just set yourself small goals and achieve them one by one. Doing borders and being able to detect and pick up objects on the screen is a good set of goals.

 

I agree with Vorticon about the VDP utilities... I've butted heads with Matthew on this subject before. :) I'd call writing your own VDP utilities and VDP read/write techniques an optimization step, and probably best for the intermediate programmer who has mastered the basics (replicated everything he could do in BASIC and Extended BASIC) and is ready to move on into what assembly can do for you that can't be done elsewhere.

 

One area that is a must for assembly programming is understanding boolean logic. (AND, OR, NOT, bit masks, etc.) TI BASIC and Extended BASIC use these, but you can use IF/THEN without ever really understanding what's going on under the hood. I had a college course on the subject in my CS path, can anyone recommend a decent book that's good for a beginner here?

 

Adamantyr

Link to comment
Share on other sites

First, thank you guys for being so supportive. I was doing pretty well back in May--- I was able to accomplish some cool things, but I guess I really didn't quite know what the hell I was doing. Got lucky I guess. :)

 

Anyway--- I have some cool ideas for what I want to achieve this time around... Doable goals that won't get lost in a fog of uncertainty. My Beryl Reichardt scroller was a nice step, but I had nowhere to go with it. This time around, I plan to start with accomplishable goals--- like make a roguelike. :) I actually like Nethack quite a bit. I know some folks don't care for that game too much, but it's achievable, I think.... First things first... Let's do screen boundaries and keep one "@" on the screen at a time. :) code forthcoming.

Link to comment
Share on other sites

I added this to my code... I won't post the whole thing here, but I want to get some opinions. My program works just fine, it does ALMOST what I expect it to... but the "@" doesn't hit every screen position as I move it up down left and right. It looks like it skips screen positions... As you hold down the key, it disappears from sight. I'm not 100% sure why yet, but I'll know momentarily. The important additions to my code are the re-load of R1 with ASCII >20 and BLWP @VSBW that I do in all my joystick checks now, BEFORE the modification on location and jump to print routine. Here's program flow for the most part on the check for a "down" diretion... Code checks for "down", if not, it jumps... if it IS down, it writes a space character to the current location of the "@", then changes the screen location to print the next "@", giving the appearance that it is moving around the screen. This little chunk of code will show what I mean. If you want to see the whole joystick routine as it currently sits, check the collapsed code box. =) Thanks... I hope to hear some suggestions on how to smooth out this routine here. =)

 

   	JNE  T2     		;if not, jump to next comparison
   	LI  R1,>2000	;load ASCII with space character to write over the current "@"
       BLWP @VSBW  ; write it
   	AI   R0,32

 

 

 

JOYCK   LI R1,>0100                     		*check for joystick 1 input
   	MOVB R1,@>8374                      	*check for Y return
LP  	LIMI 2
 LIMI 0
 BLWP @KSCAN                     		*check for input
   	CLR  R1                         		*clear register for Y return check
   	MOVB @>8376,R1                      	*move Y return value into MSB of R1
   	CI   R1,>0400                   		*is the Y value "4"? (up)
   	JNE  T1                         		*if not, go to the next comparison
 LI  R1,>2000
 BLWP @VSBW
   	AI   R0,-32
   	JMP  PRINT
T1  	CI   R1,>FC00                   		*compares MSB of R1 to >FC (down)
   	JNE  T2                         		*if not, go to the next comparison
 LI  R1,>2000
 BLWP @VSBW
   	AI  R0,32
   	JMP  PRINT
T2  	MOVB @>8377,R1                      	*move X-return byte into R1
   	CI   R1,>0400                   		*is the X value "4"? (right)
   	JNE  T3                         		*if not, go to the next comparison
 LI  R1,>2000
 BLWP @VSBW
   	INC  R0
 JMP  PRINT
T3  	CI   R1,>FC00                   		*final comparison... is the X value >FC? (left)
   	JNE  LP                         		*it was not, therefore no motion happened, jump to KSCAN
 LI  R1,>2000
 BLWP @VSBW
   	DEC  R0

PRINT LI  R4,3000   	*Start the delay loop
 DEC  R4     	*decrement register 4 (part of delay)
 JNE  $-2        *jump back one word in memory to DEC
 LI  R1,>4000            	*load the ASCII character to print
 BLWP @VSBW        *print it
 JMP  LP     	*back to KSCAN routine

 

 

 

***edit***

 

It seems like the problem is ONLY when the key is held down... It clears immediately, but it won't redraw until I let off the key... hmmmmmm...................

Edited by Opry99er
Link to comment
Share on other sites

Would a better way be to copy the MSB of R1 to another register (MOVB R1,R5) and then use THAT register to keep current screen position? It seems redundant and unnecessary which is why I didn't do it initially, but having a copy of screen location somewhere (preferably a register) would most likely come in handy at some point... assuming this becomes something other than a tester program.

 

This still doesn't solve the problem of the key-press... Where it won't draw the next "@" until I let off the key. I need it to print every screen position as the location is changed... a "smooth" type of motion. Obviously it's not a SPRITE, but I'm thinking I can get it to do every position..... Need to research more.

Edited by Opry99er
Link to comment
Share on other sites

Here's the list output after doing an AORG >A000.

 

 

 

Asm994a TMS99000 Assembler - v3.008

               * Asm994a Generated Register Equates
               *
     0000 0000 R0      EQU     0 
     0000 0001 R1      EQU     1 
     0000 0002 R2      EQU     2 
     0000 0003 R3      EQU     3 
     0000 0004 R4      EQU     4 
     0000 0005 R5      EQU     5 
     0000 0006 R6      EQU     6 
     0000 0007 R7      EQU     7 
     0000 0008 R8      EQU     8 
     0000 0009 R9      EQU     9 
     0000 000A R10     EQU     10
     0000 000B R11     EQU     11
     0000 000C R12     EQU     12
     0000 000D R13     EQU     13
     0000 000E R14     EQU     14
     0000 000F R15     EQU     15
               *
  1            *
  2            * Owen Brand, Nov 13, 2010
  3            *
  4            * Clear the screen.
  5            * Assumes the default graphics mode I.
  6            *
  7  0000 A000         DEF  START
  8  0000 0000         REF  VSBW,VWTR,VMBW,KSCAN
  8  0000 0000  
  8  0000 0000  
  8  0000 0000  
  9                    AORG >A000
 10  0000 0380 CTAB    EQU  >0380           ; equate location of colorset table in RAM
 11            
 12            * The linker will branch to this location
 13            * to start our program.
 14            START
 15            
 16  A000 0200         LI R0,CTAB      ; table location
 16  A002 0380  
 17  A004 0201         LI R1,CSET      ; definitions
 17  A006 A0BA  
 18  A008 0202         LI R2,32        ; number of bytes to write
 18  A00A 0020  
 19  A00C 0420         BLWP @VMBW
 19  A00E 0000  
 20            
 21            *      Interrupts need to be disabled any time the VDP
 22            *      is being accessed.
 23  A010 0300         LIMI 0
 23  A012 0000  
 24            
 25            *      Always know where your workspace is!
 26  A014 02E0         LWPI >8300
 26  A016 8300  
 27            
 28            
 29            *      Set the background color to white >F
 30            *      VDP register 7 controls the text mode
 31            *      text color and the background color for
 32            *      the other modes.  All other VDP registers
 33            *      are assumed to have set graphics mode 1.
 34            
 35  A018 0200         LI   R0,>071F          ; Register 7, black on white
 35  A01A 071F  
 36  A01C 0420         BLWP @VWTR             ; Write the register
 36  A01E 0000  
 37            
 38            
 39            *      Set up to clear the screen.  Assumes the
 40            *      Name Table is set to address >0000 in VRAM.
 41            *      All the names (tile / character values) in
 42            *      the Name Table will be set to the space character
 43            *      which is, well, a space, so it has no foreground
 44            *      bits, so the screen will show only the background
 45            *      color.
 46            *
 47            *      Note, only the HIGH BYTE is transfered to the VDP
 48            *      hence using >2000 loads 32 (>20) into the MSB of R1.
 49            
 50  A020 04C0         CLR  R0                ; Start at >0000 in VRAM.
 51  A022 0201         LI   R1,>2000          ; Write 32 (space char)
 51  A024 2000  
 52  A026 0202         LI   R2,768            ; 32x24 tiles = 768 total to write
 52  A028 0300  
 53            
 54            LOOP
 55  A02A 0420         BLWP @VSBW             ; Write the byte
 55  A02C 0000  
 56  A02E 0580         INC  R0                ; Next VRAM screen location
 57  A030 0602         DEC  R2                ; Count the byte just written
 58  A032 16FB         JNE  LOOP              ; If not done, write again
 59            
 60            *      The DEC instruction compares the result of the decrement to
 61            *      zero automatically (as do many instructions), so the JNE is
 62            *      really saying "jump if R2 is not zero".
 63            
 64            *          This will place a "@" at screen location 110
 65  A034 0200         LI      R0,110                    ; Screen location in VDP RAM
 65  A036 006E  
 66  A038 0201             LI  R1,>4000                  ; ASCII code for "@"
 66  A03A 4000  
 67  A03C 0420             BLWP        @VSBW                     ; Write it
 67  A03E A02C  
 68            
 69            
 70  A040 0201 JOYCK   LI R1,>0100                             *check for joystick 1 input
 70  A042 0100  
 71  A044 D801         MOVB R1,@>8374                          *check for Y return
 71  A046 8374  
 72  A048 0300 LP      LIMI 2
 72  A04A 0002  
 73  A04C 0300                 LIMI 0
 73  A04E 0000  
 74  A050 0420                 BLWP @KSCAN                             *check for input
 74  A052 0000  
 75  A054 04C1         CLR  R1                                 *clear register for Y return check
 76  A056 D060         MOVB @>8376,R1                          *move Y return value into MSB of R1
 76  A058 8376  
 77  A05A 0281         CI   R1,>0400                           *is the Y value "4"? (up)
 77  A05C 0400  
 78  A05E 1607         JNE  T1                                 *if not, go to the next comparison
 79  A060 0201                 LI       R1,>2000
 79  A062 2000  
 80  A064 0420                 BLWP @VSBW
 80  A066 A03E  
 81  A068 0220         AI   R0,-32
 81  A06A FFE0  
 82  A06C 101D         JMP      PRINT
 83  A06E 0281 T1      CI   R1,>FC00                           *compares MSB of R1 to >FC (down)
 83  A070 FC00  
 84  A072 1607         JNE  T2                                 *if not, go to the next comparison
 85  A074 0201                 LI       R1,>2000
 85  A076 2000  
 86  A078 0420                 BLWP @VSBW
 86  A07A A066  
 87  A07C 0220         AI       R0,32
 87  A07E 0020  
 88  A080 1013         JMP      PRINT
 89  A082 D060 T2      MOVB @>8377,R1                          *move X-return byte into R1
 89  A084 8377  
 90  A086 0281         CI   R1,>0400                           *is the X value "4"? (right)
 90  A088 0400  
 91  A08A 1606         JNE  T3                                 *if not, go to the next comparison
 92  A08C 0201                 LI       R1,>2000
 92  A08E 2000  
 93  A090 0420                 BLWP @VSBW
 93  A092 A07A  
 94  A094 0580         INC      R0
 95  A096 1008                 JMP      PRINT
 96  A098 0281 T3      CI   R1,>FC00                           *final comparison... is the X value >FC? (left)
 96  A09A FC00  
 97  A09C 16D5         JNE  LP                                 *it was not, therefore no motion happened, jump to KSCAN
 98  A09E 0201                 LI       R1,>2000
 98  A0A0 2000  
 99  A0A2 0420                 BLWP @VSBW
 99  A0A4 A092  
100  A0A6 0600         DEC      R0
101            
102  A0A8 0204 PRINT   LI       R4,3000                                                        *Start the delay loop
102  A0AA 0BB8  
103  A0AC 0604                 DEC      R4                                                                     *decrement register 4 (part of delay)
104  A0AE 16FE                 JNE      $-2                                                            *jump back one word in memory to DEC
105  A0B0 0201                 LI       R1,>4000                                           *load the ASCII character to print
105  A0B2 4000  
106  A0B4 0420                 BLWP @VSBW                                                              *print it
106  A0B6 A0A4  
107  A0B8 10C7                 JMP      LP                                                                     *back to KSCAN routine
108                       
109                       
110  A0BA 1010 CSET    BYTE >10,>10,>10,>10            
110  A0BC 1010  
111  A0BE 1010         BYTE >10,>10,>10,>10            ;set "@" to "red"
111  A0C0 1010  
112  A0C2 C010         BYTE >C0,>10,>10,>10            
112  A0C4 1010  
113  A0C6 1010         BYTE >10,>10,>10,>10            
113  A0C8 1010  
114  A0CA 1010         BYTE >10,>10,>10,>10 
114  A0CC 1010  
115  A0CE 1010         BYTE >10,>10,>10,>10
115  A0D0 1010  
116  A0D2 1010         BYTE >10,>10,>10,>10
116  A0D4 1010  
117  A0D6 1010         BYTE >10,>10,>10,>10
117  A0D8 1010  
118            
119            
120  A0DA 0000         END  START
120            


Assembly Complete - Errors: 0,  Warnings: 0


------ Symbol Listing ------

CSET   ABS:A0BA CSET
CTAB   ABS:0380 CTAB
JOYCK  ABS:A040 JOYCK
KSCAN  REF:A052 KSCAN
LOOP   ABS:A02A LOOP
LP     ABS:A048 LP
PRINT  ABS:A0A8 PRINT
R0     ABS:0000 R0
R1     ABS:0001 R1
R10    ABS:000A R10
R11    ABS:000B R11
R12    ABS:000C R12
R13    ABS:000D R13
R14    ABS:000E R14
R15    ABS:000F R15
R2     ABS:0002 R2
R3     ABS:0003 R3
R4     ABS:0004 R4
R5     ABS:0005 R5
R6     ABS:0006 R6
R7     ABS:0007 R7
R8     ABS:0008 R8
R9     ABS:0009 R9
START  ABS:A000 START
T1     ABS:A06E T1
T2     ABS:A082 T2
T3     ABS:A098 T3
VMBW   REF:A00E VMBW
VSBW   REF:A0B6 VSBW
VWTR   REF:A01E VWTR

 

 

Link to comment
Share on other sites

I see a few things... your delay was in the wrong place, it should be AFTER you have written the character, not before.

 

I also made some changes to how the joystick is scanned. Since the X and Y values are in a single word, you can easily check for no activity and just loop back.

 

Code below

 

 

 

*
* Owen Brand, Nov 13, 2010
*
* Clear the screen.
* Assumes the default graphics mode I.
*
      DEF  START
      REF  VSBW,VWTR,VMBW,KSCAN
      AORG >A000                      * Start program at bottom of high memory
CTAB   EQU  >0380                      * equate location of colorset table in RAM

* Data constants
B4     BYTE 4
BN4    BYTE >FC

* The linker will branch to this location
* to start our program.
START  
      LI   R0,CTAB                    * table location
      LI   R1,CSET                    * definitions
      LI   R2,32                      * number of bytes to write
      BLWP @VMBW

*      Interrupts need to be disabled any time the VDP
*      is being accessed.
      LIMI 0

*      Always know where your workspace is!
      LWPI >8300


*      Set the background color to white >F
*      VDP register 7 controls the text mode
*      text color and the background color for
*      the other modes.  All other VDP registers
*      are assumed to have set graphics mode 1.

      LI   R0,>071F                   * Register 7, black on white
      BLWP @VWTR                      * Write the register


*      Set up to clear the screen.  Assumes the
*      Name Table is set to address >0000 in VRAM.
*      All the names (tile / character values) in
*      the Name Table will be set to the space character
*      which is, well, a space, so it has no foreground
*      bits, so the screen will show only the background
*      color.
*
*      Note, only the HIGH BYTE is transfered to the VDP
*      hence using >2000 loads 32 (>20) into the MSB of R1.

      CLR  R0                         * Start at >0000 in VRAM.
      LI   R1,>2000                   * Write 32 (space char)
      LI   R2,768                     * 32x24 tiles = 768 total to write

LOOP   BLWP @VSBW                      * Write the byte
      INC  R0                         * Next VRAM screen location
      DEC  R2                         * Count the byte just written
      JNE  LOOP                       * If not done, write again

*      The DEC instruction compares the result of the decrement to
*      zero automatically (as do many instructions), so the JNE is
*      really saying "jump if R2 is not zero".
*      This will place a "@" at screen location 110

      LI   R0,110                     *Screen location in VDP RAM
      LI   R1,>4000                   * ASCII code for "@"
      BLWP @VSBW                      * Write it

JOYCK  LI   R1,>0100                   *check for joystick 1 input
      MOVB R1,@>8374                  *check for Y return
LP     LIMI 2
      LIMI 0
      BLWP @KSCAN                     *check for input
      MOV  @>8376,R1                  * Move joystick XY values into R1
      JEQ  LP                         * If 0 (no movement, jump back to KSCAN
      CB   R1,@B4                     *is the Y value "4"? (up)
      JNE  T1                         *if not, go to the next comparison
      LI   R1,>2000
      BLWP @VSBW
      AI   R0,-32
      JMP  PRINT
T1     CB   R1,@BN4                    *compares MSB of R1 to >FC (down)
      JNE  T2                         *if not, go to the next comparison
      LI   R1,>2000
      BLWP @VSBW
      AI   R0,32
      JMP  PRINT
T2     SWPB R1                         * Swap bytes in R1 for Y comparisons
      CB   R1,@B4                     *is the X value "4"? (right)
      JNE  T3                         *if not, go to the next comparison
      LI   R1,>2000
      BLWP @VSBW
      INC  R0
      JMP  PRINT
T3     LI   R1,>2000
      BLWP @VSBW
      DEC  R0
PRINT  LI   R1,>4000                   *load the ASCII character to print
      BLWP @VSBW                      *print it
      LI   R4,3000                    *Start the delay loop
      DEC  R4                         *decrement register 4 (part of delay)
      JNE  $-2                        *jump back one word in memory to DEC
      JMP  LP                         *back to KSCAN routine
         
CSET   BYTE >10,>10,>10,>10            
      BYTE >10,>10,>10,>10            *set "@" to "red"
      BYTE >C0,>10,>10,>10            
      BYTE >10,>10,>10,>10            
      BYTE >10,>10,>10,>10 
      BYTE >10,>10,>10,>10
      BYTE >10,>10,>10,>10
      BYTE >10,>10,>10,>10
      END  START

 

 

 

Adamantyr

Link to comment
Share on other sites

Sometimes I start out writing (comments) in pseudo code. This step can involve many changes, renaming and rearrangements.

 

  1. Set default screen location
  2. Put "@" character code at screen location
  3. Delay loop
  4. Put "space" character code at screen location
  5. Read joystick
  6. Change screen location accordingly
  7. Go to 2.

Writing assembler code to perform just one of the steps above are often quite easy. I can concentrate on the simple task at hand one at a time, knowing that the overall flow has been taken care of (at least I assume so - debugging later).

 

If I have pseudo code on higher levels like

 

  1. Intro screen
  2. Main game
  3. Game over

I'll break down one element into many smaller elements (often into 5 to 10 elements). This process continues in an uneven/not balanced tree structure, until one element is like a comment for a section of assembler instructions (often 3 to 20 instructions).

 

Designing a complete game this way is possible, but can you go all the way without wanting to code (prove certain aspects etc.) ? With Basic we probably design as we code - besides an initial overall design phase/idea. You might have some of the graphics and a screen design, but things change a lot and you add things. This is not necessarily bad, but you might loose the drive at some point. Funny thing is, if you're two (enthusiastic) programmers sitting at one computer, it's much more fun, and the drive isn't lost so easily.

 

:)

Link to comment
Share on other sites

Thanks sometimes!! Question...

 

Screen boundaries... Should I place a different character value around the edge and check for that particular ASCII value? Kind of a GCHAR sort of thing... Its all I can think to do for the right and left sides of the screen--- top and bottom wouldn't be so difficult... But I think this method might be the most efficient (the method of putting a different ASCII on the edges)

Link to comment
Share on other sites

Separate your graphics rendering from your game logic. You are thinking in terms of the raw information needed to draw on the screen, and that will make your life a lot harder. In games there is a lot of translation that goes on, and the game map is not the same thing you see on the screen.

 

First, don't try to use the registers for specific values (current screen location, player information, etc.) Use variables. Second, the screen should be an output only device.

 

Keep your player's X,Y values in variables, as well as the prospective *new* location.

 

P1X    BYTE 16
P1Y    BYTE 12
P1XNEW BYTE >00
P1YNEW BYTE >00

 

Then when you read the keyboard / joystick, do the same thing you do in BASIC, add / subtract 1 from the respective variable. When you want to draw, make a subroutine that puts your players on the screen given an X,Y location. You do bounds checking based on the variable values or the X,Y locations compared to map data, etc. Something like this (mix of pseudo code and real code):

 

P1X    BYTE 16
P1Y    BYTE 12
P1XNEW BYTE >00
P1YNEW BYTE >00
P1TILE BYTE 64


* K_UPDN and K_LTRT will be -1, 0, or 1
      EVEN
K_UPDN BYTE >00
K_LTRT BYTE >00

* General use numbers
NEG1   BYTE -1
NUM0   BYTE 0
NUM1   BYTE 1
NUM2   BYTE 2

* Boundaries
XMIN   BYTE 2
XMAX   BYTE 29
YMIN   BYTE 2
YMAX   BYTE 21


GAMELOOP

*      Save the current X,Y location.
*      The new location is the current location until there is movement.
      MOVB @P1X,@P1XNEW
      MOVB @P1Y,@P1YNEW

*      Clears both movement indicator bytes.  K_UPDN was preceded by EVEN
      to make sure it is on a 16-bit WORD boundary.
      CLR  @K_UPDN

*      Start by reading the keyboard.
      BLWP @KSCAN
      IF NO KEYPRESS, READ JOYSTICK

      compare if UP
      JNE  KB01
      MOVB @NEG1,@K_UPDN
      JMP  KEYBOARD_DONE

KB01
      compare if DOWN
      JNE  KB02
      MOVB @NUM1,@K_UPDN
      JMP  KEYBOARD_DONE

KB02
      compare if LEFT
      JNE  KB03
      MOVB @NEG1,@K_LTRT
      JMP  KEYBOARD_DONE

KB03
      compare if RIGHT
      JNE  KEYBOARD_DONE
      MOVB @NUM1,@K_LTRT

KEYBOARD_DONE
      JMP  BOUND_CHECK

*      Code falls here if no keyboard movement was found.
READ_JOYSTICK

      BLWP @JOYSTICK
      IF NO JOYSTICK, JUMP TO BOUND CHECK.

      compare if UP
      JNE  JS01
      MOVB @NEG1,@K_UPDN
      JMP  JOYSTICK_DONE

JS01
      compare if DOWN
      JNE  JS02
      MOVB @NUM1,@K_UPDN
      JMP  JOYSTICK_DONE

JS02
      compare if LEFT
      JNE  JS03
      MOVB @NEG1,@K_LTRT
      JMP  JOYSTICK_DONE

JS03
      compare if RIGHT
      JNE  JOYSTICK_DONE
      MOVB @NUM1,@K_LTRT


BOUND_CHECK

*      At this point there should be a movement indicator for any direction
*      of concern, i.e. up, down, left, or right.  Reading the keyboard OR
*      joystick for movement should set the same indicators.

*      Adjust the new position based on the direction request.
      AB   @K_UPDN,@P1YNEW
      AB   @K_LTRT,@P1XNEW

*      Check if the new location is legal.
      CB   @P1XNEW,@XMIN
      JL   RENDER

      CB   @P1XNEW,@XMAX
      JH   RENDER

      CB   @P1YNEW,@YMIN
      JL   RENDER

      CB   @P1YNEW,@YMAX
      JH   RENDER

*      Player updating begins here.
*      The new move is legal, so erase the player at the current location.
      MOVB @P1Y,R0
      SWPB R0
      MOVB @P1X,R0
      MOVB @P1TILE,R1
      BL   @RENDER_PLAYER

*      Screen rendering starts here.  This is done even if the player did not
*      move or make a legal move.  This allows *other* objects to still move
*      or animate themselves.  Even the player make animate (change character
*      pattern, color, sound, etc) even if the move was not legal.

RENDER
      MOVB @P1YNEW,R0
      SWPB R0
      MOVB @P1XNEW,R0
      MOVB @P1TILE,R1
      BL   @RENDER_PLAYER


*      Update the player coordinates.
      MOVB @P1XNEW,@P1X
      MOVB @P1YNEW,@P1Y

      B    @GAME_LOOP


*******
*      Render the player on the screen
*      R0 contains the X location in the MSB, the Y location in the LSB
*      R1 contains the player tile to use
RENDER_PLAYER

*      Convert the X,Y into a linear offset value of the screen location.
*      The formula is: OFFSET = Y*32+X

      CLR   R2           ; Prepare R2 for the X value
      MOVB  R0,R2        ; Save the X coordinate in the MSB of R2
      ANDI  R0,>00FF     ; Isolate the Y coordinate
      SLA   R0,5         ; Multiply Y by 32
      SWPB  R2           ; Move the X coordinate to the LSB for the addition
      A     R2,R0        ; Add the X coordinate
      BLWP  @VSBW
      RT

 

That's the basic idea anyway. Use variables to track your player's location, state, tile, color, direction, etc. Same with all the other objects in the game. Since you know where the player is, you can do a bounds check and see if the move is legal before you update the player's location. Also remember that just because the player may not move, the rest of the game does not come to a halt, so you still perform the rendering every frame, which lets you do things like animate other objects, play sounds, update timers, etc.

 

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