Opry99er Posted November 18, 2009 Share Posted November 18, 2009 In my current game development, I have discovered yet again that my XB is not quite fast or versatile enough to accomplish all of what I want to accomplish. As I have only just begun learning assembly, I will not be able to write this game in assembly, but I do feel confident that I can use it to diversify my program parameters. Whether to CALL LOAD, or take the advice if some others and embed with STSTEX... That is the question. On the list server discussion, I have learned many things and heard many more I do not understand 100%. My question here is, what precisely is the difference between the two options, and is one more effective than the other for certain tasks? Quote Link to comment Share on other sites More sharing options...
matthew180 Posted November 19, 2009 Share Posted November 19, 2009 I'm not sure what STSTEX is, do you have a link to more info? As for not doing your game in Assembly, I think you should try. Maybe go for something a little more simple so you can finish. Personally I believe the best way to learn is the have a something you are working on while trying to learn a new language or whatever. Make a list of things you need to do like: 1. initialize 2. clear the screen 3. draw the player 4. get user input (keyboard / joystick) 5. update the player 6. check for bounds / collisions 7. check for quit / end game 8. go back to 3. I saw a post you made on the TI list that you are trying to go through the Molesworth book... IMHO that is not such a great book for a beginner. The book that really helped me when I was learning assembly (back in 1984 that is) was Lottrup's book, but that is hard to find. I'm actually considering writing some assembly language tutorials, so if you have specific questions I'd be glad to try and help. Matthew 1 Quote Link to comment Share on other sites More sharing options...
Opry99er Posted November 19, 2009 Author Share Posted November 19, 2009 Thank you Matthew ... I am very interested in learning to (first) write some assembly subroutines to make my XB games function better. I know that might not be the best way to learn assembly, but it is something I want to do. Tursi is helping me out and so is Marc Hull. Systex.... Not Ststex... My bad. It is apparently a way to embed assembly directly into XB code... I'll get some more info and post it when I have it. Thanks man Quote Link to comment Share on other sites More sharing options...
matthew180 Posted November 19, 2009 Share Posted November 19, 2009 You must like pain! The day I got my PEB with the E/A cart is the day I stopped writing anything in XB. It is just too painful due to the double interpretation. XB (and BASIC) hog the whole system too, so you really have to know a *lot* about the memory use and the hardware to use assembly with XB. IHMO it is harder to interface XB with assembly than to just write the whole thing straight up in assembly. Either way though, I have a lot of subroutines you could probably use. I posted a link to an integer to ASCII conversion routine on the TI list, which also has video routines to replace the stock TI ones in ROM. What ever you want to do, if you need some help let me know. If you give me some idea about what you are trying to learn first, I might be able to come up with something useful to you. Matthew Quote Link to comment Share on other sites More sharing options...
Opry99er Posted November 19, 2009 Author Share Posted November 19, 2009 Well, I tell ya... XB is the only language I know... Assembly is my nemesis... . I bought an EA package a year ago and, to my dismay, the first line of the manual said "This is not a tutorial... You must know some assembly before this manual will help you" or some crap like that... Sad... Anyway, I bought this Molesworth book, but it is not very "beginner-friendly". I wrote my first game in XB with minor A/L support... You can DL it from my website free... Opry99er.com. You can play it and see how you like it. . Wish that game qualified for this contest... But alas, it was finished before the contest started... I am hoping to finish a concept game I started a month or so ago... Right now I just have basic graphics done and the motion and pattern routines encoded. On the "New Game Development" page, it is listed along with other great game ideas by Keith, Filip, and Mark Wills. As for assembly, man.... It just scares the crap out of me. . I am hoping to develop some way to create impassible borders for my main game character... For instance, I do not want the character to be able to "wrap" around the left side of the screen to get to the right, or the bottom to get to the top... Simple, right? But in XB, it is hard to do that with any precision. Quote Link to comment Share on other sites More sharing options...
Tursi Posted November 19, 2009 Share Posted November 19, 2009 Systex is a distribution mechanism, you can't use it until the XB side of the program is completely finished. So during development, just stick to CALL LOAD(). What Systex does, and why it's handy, is it changes the pointers that tell the system where your XB program ends, so that they include the assembly program. This way, when you load your XB program, the assembly comes at the same time. This is useful, because CALL LOAD() is relatively slow compared to the program loader. However, once you go there, it's not safe to make a lot of changes to the XB side of the program, so you do this at the end, when you're finished development. At least, if I remember correctly. I never had an official copy of it, I played with other people's loaders. Quote Link to comment Share on other sites More sharing options...
Opry99er Posted November 19, 2009 Author Share Posted November 19, 2009 Thanks Tursi... I am quite enamored with the AL programming guys like Marc Hull and Walid Maalouli have been doing... TI Clickety and Never-Lander are two excellent programs written by Marc Hull-- both in Assembly. I find that these games are faster and more intuitive than many games that TI programmers came out with in the 80s. I suppose it just comes with time, patience, and being able to learn from those who came before. I am going to learn Assembly. I am learning more and more every day. But I don't think I'll be able to learn it, become proficient with it, and complete a game by the deadline for this particular contest. I doubt I'll win, with an XB clunker, but I'll do my best. "Lemonade Stand" was a labor of love, and it taught me so much about XB programming that it's almost hard to let go of the format. If I had written it in TMS9900, it would most decidedly be cleaner, faster, and it would be on a cartridge right now. That's my ultimate reasoning for learning AL... I want to distribute a game on cartridge. =) Quote Link to comment Share on other sites More sharing options...
Willsy Posted November 19, 2009 Share Posted November 19, 2009 For instance, I do not want the character to be able to "wrap" around the left side of the screen to get to the right, or the bottom to get to the top... Simple, right? But in XB, it is hard to do that with any precision. Easy - don't use the auto motion - move your sprites yourself by steps, say 4 pixels at a time. When you scan the keys, you only scan for a particular direction key IF the sprite is STILL in allowable bounds. 10 X=50 :: Y=50 20 CALL MAGNIFY(3) 30 CALL SPRITE(#1,42,5,Y,X) 40 CALL KEY(0,K,S) 50 IF X>50 THEN IF K=ASC("S") THEN X=X-4 60 IF X<100 THEN IF K=ASC("D") THEN X=X+4 70 IF Y>50 THEN IF K=ASC("E") THEN Y=Y-4 80 IF Y<100 THEN IF K=ASC("X") THEN Y=Y+4 90 GOTO 30 That should do it. Check I got the CALL SPRITE correct. Is it sprite number, ascii code, colour, y then x? I can't remember - been a while! Also, lines 50 to 80 can be sped up by using the true ascii codes, not the ASC function - for example: 50 IF X>50 THEN IF K=83 THEN X=X-4 However, I just wrote the code so it's easy to understand for now. But that is how I would do it. BTW: I couldn't check this code, but I think it should work Mark Quote Link to comment Share on other sites More sharing options...
Opry99er Posted November 19, 2009 Author Share Posted November 19, 2009 (edited) I have just implemented my JOYST function today. Took some bending and twisting of arms, and gnashing of teeth, but I got it done, thanks to Marc and Tursi. Sent you the code in eMail. Anyway, with a JOYST function, wouldn't it simplify the matter even more? There will have to be several things tied into the loop... a few CALL COINCs for SPRITE collision and such... couldn't your routine be rewritten to fit inside a JOYST loop along with the other subprograms? Or would this slow down reaction times... I know XB is slow as molasses. I just need to get this darned thing into Assembly and call it a night. In any case, I have two great books, the reading of which will put me right where I need to be in my road to "Assemblyland." Plus I have been getting excellent advice from a few folks here. Matthew has me almost convinced to stop writing in XB, throw my cart away, burn the XB manual, and get down to EA bidness. Edited November 19, 2009 by Opry99er Quote Link to comment Share on other sites More sharing options...
matthew180 Posted November 19, 2009 Share Posted November 19, 2009 Don't be scared of assembly. It is not hard. Actually, the commands are very primitive: move data here, add two values, send a byte to the VDP, etc.. But, because of this simplicity you have a lot more commands to do something that a single statement in a high level language would do. The trade off is speed and control, and on the older computers speed is generally critical especially for games. Also, things you learn about computers when working in assembly will make you a better programmer in any other language you use. I learned 9900 assembly in 1984 and the principles are still applicable today. For example when learning C, pointers are really hard for people to understand and they usually struggle with that aspect of the language. For me they were natural and easy because I understood indirect memory addressing thanks to my assembly experience. Unlike what most people think, computers have not changed in the last 40 years, they are only faster and more dense, and the OSes are more complex, but that's about it. The real key to learning assembly on any computer is to understand how memory really works and how the CPU treats the bytes of data it is dealing with. That's really the secret. Matthew Quote Link to comment Share on other sites More sharing options...
Opry99er Posted November 20, 2009 Author Share Posted November 20, 2009 Well, I am game... I have convinced myself to push on... Your tutorials would be a great help in this process! Quote Link to comment Share on other sites More sharing options...
matthew180 Posted November 20, 2009 Share Posted November 20, 2009 Cool. Well, tell me what you want to learn how to do first and I'll try to write something up. For the last three hours I've been working on a "accessing memory" chapter (thinking of a book now... ) When I'm done it would be great to get your feedback on it. Matthew Quote Link to comment Share on other sites More sharing options...
Opry99er Posted November 20, 2009 Author Share Posted November 20, 2009 I would like to learn to clear screen, call screen(.... Oh hell, why don't I email you the code I am messing with right now... It's about 15 lines of code.. If you could show me the assembly equivalent of a short section if my XB program, that would help immensely!! Quote Link to comment Share on other sites More sharing options...
matthew180 Posted November 20, 2009 Share Posted November 20, 2009 Haha, that's funny, I started writing a "call clear" equivalent tutorial. There was way too much background though, and my thoughts were running all over the place. I'll try to refocus on that topic though. Ironically, clearing the screen is also one of the first examples given in the Lottrup book too. Matthew Quote Link to comment Share on other sites More sharing options...
Opry99er Posted November 20, 2009 Author Share Posted November 20, 2009 You know what, my friend Marc Hull just sent me his prized hardback copy of Lottrups book to borrow until I'm on my feet. How cool is that? Quote Link to comment Share on other sites More sharing options...
Willsy Posted November 20, 2009 Share Posted November 20, 2009 You know what, my friend Marc Hull just sent me his prized hardback copy of Lottrups book to borrow until I'm on my feet. How cool is that? That's the one that deals with MiniMem, right? You're on your way now... It's a great book... Quote Link to comment Share on other sites More sharing options...
sometimes99er Posted November 20, 2009 Share Posted November 20, 2009 (edited) This does not go into details for absolute beginners, but shows how I extended one of the Mini Memory system utility routines. The routine can clear the screen. The Mini Memory manual has this documentation on VDP Multiple Byte Write – VMBW Format: BLWP @VMBW This routine writes multiple bytes from CPU RAM to VDP RAM. R0 – VDP RAM address R1 – Starting address of CPU RAM buffer R2 – Number of bytes to write Example: LI R0,>018E ; VDP RAM address >01BE LI R1,HI ; Address of text LI R2,5 ; Number of bytes to write BLWP @WMBW ; Display the characters ... ... HI TEXT "HELLO" ; Text to be displayed Now we could construct a new similar routine and document it like this ... VDP Single Byte Multiple Write – VSBMW Format: BL @VSBMW This routine writes one byte multiple times to VDP RAM. R0 – VDP RAM address R1 – Byte to write (in even/high byte of word) R2 – Number of times to writes Example: CLR R0 ; VDP RAM address >0000 LI R1,>2000 ; Byte to write (equals the space character) LI R2,>300 ; Number of bytes to write (equals the no. of characters on screen) BL @VSBMW ; Write byte multiple times to VDP (Clear the screen) The actual code for VSBMW could be like this VSBMW ORI R0,>4000 ; adjust for writing SWPB R0 ; swap MOVB R0,@VDPWA ; put low byte to vdp SWPB R0 ; swap back MOVB R0,@VDPWA ; put high byte to vdp NOP ; delay VSBMWL MOVB R1,@VDPWD ; put byte to vdp DEC R2 ; countdown JNE VSBMWL ; more bytes ? RT ; return from subroutine Edited November 20, 2009 by sometimes99er Quote Link to comment Share on other sites More sharing options...
+retroclouds Posted November 20, 2009 Share Posted November 20, 2009 The actual code for VSBMW could be like this VSBMW ORI R0,>4000 ; adjust for writing SWPB R0 ; swap MOVB R0,@VDPWA ; put low byte to vdp SWPB R0 ; swap back MOVB R0,@VDPWA ; put high byte to vdp NOP ; delay VSBMWL MOVB R1,@VDPWD ; put byte to vdp DEC R2 ; countdown JNE VSBMWL ; more bytes ? RT ; return from subroutine I know just recently we got the discussion on the TI yahoo group if the NOP (pseudo-)instructions are still required. Somehow I lost track of the outcome. Is it safe to assume we can just remove the NOP after setting the VDP write address ? Quote Link to comment Share on other sites More sharing options...
sometimes99er Posted November 20, 2009 Share Posted November 20, 2009 I know just recently we got the discussion on the TI yahoo group if the NOP (pseudo-)instructions are still required. Somehow I lost track of the outcome. Is it safe to assume we can just remove the NOP after setting the VDP write address ? I lost track also. The single NOP in the above is outside the loop, so not much time to gain there if possible. The loop itself takes time with the DEC and JNE. Rolling out, moving to ScratchPad and using indirect (sort of) register access to the VDPWD should make things faster. Rolling out might then need those NOPs. Quote Link to comment Share on other sites More sharing options...
Tursi Posted November 20, 2009 Share Posted November 20, 2009 (edited) According to the datasheets and tracing the hardware timing: After setting the address, always safe to drop the NOP. After writing data to the VDP data port, always safe to drop the NOP. After reading data from the VDP data port, if in scratchpad RAM and using indirect register access to the VDP (ie: MOV *Rxx,Rxx), and in bitmap mode, then a delay (NOP or otherwise) is needed. If you use any other addressing mode, are not in bitmap mode, or not in 16-bit fast RAM, then it's safe. (Note that assuming memory expansion is 8 bit RAM may cause your code not to run on modified consoles). Note that not all of these assertions have been proven yet - it's based on comparing the datasheet to observed timing on the hardware Edited November 20, 2009 by Tursi Quote Link to comment Share on other sites More sharing options...
matthew180 Posted November 20, 2009 Share Posted November 20, 2009 (edited) Unless the routines are running from the 16-bit scratchpad and you are using an unrolled loop, you pretty much cannot over run the VDP in the 99/4A. Making a modified VSBW as sometimes99er did seems to be a common conclusion for those who look into making faster versions of the routines provided by TI in the ROM. This is my version of VSBW which includes a VSMW modification to write the same byte multiple times (for doing things like initializing VDP RAM, clearing the screen, etc.) To save two SWPB instructions, my routines require an equate to the address of the low byte of register 0. I also don't use BLWP because it is slower than just BL and I don't mind keeping R0, R1, R2, and R3 available for function use. Matthew DEF START * VDP Memory Map * VDPRD EQU >8800 VDP read data VDPSTA EQU >8802 VDP status VDPWD EQU >8C00 VDP write data VDPWA EQU >8C02 VDP set read/write address VR1CPY EQU >83D4 Copy of VDP register 1 - see E/A manual pg. 248 VSYNC EQU >83D7 Vertical Sync * Workspaces * WRKSP0 EQU >8300 Workspace 0 WRKSP1 EQU >8320 Workspace 1 R0LB EQU WRKSP0+1 R0 low byte for VDP routines * Set up workspace. * START LIMI 0 Disable interrupts LWPI WRKSP0 Set workspace pointer * Clear the screen. * LI R0,0 Upper left corner of screen LI R1,>2000 Character >20 (32) = space LI R2,>300 Number to write (768) BL @VSMW Write to VDP LIMI 2 LOOP1 JMP LOOP1 ** * VDP Routines ** * General register use is: * R0 VDP RAM starting address. * R1 MSB contains the value to write or to receive a value * when reading. For multiple byte reads/writes, contains * the CPU buffer address. * R2 Counter (counts down) for multiple reads/writes. ** * VDP Single Byte Write and Single Byte Multiple Write * * Writes the value in the most-significant byte of R1 to the * VDP RAM address indicated in R0. For VSMW, the value in R2 * determines how many times to write the byte. This is very * useful when initializing large amounts of VDP RAM for things * such as clearing the screen or setting up bitmap mode. * VSBW LI R2,1 Force the byte count to 1 for single byte write VSMW MOVB @R0LB,@VDPWA Send low byte of VDP RAM write address ORI R0,>4000 Set read/write bits 14 and 15 to write (01) MOVB R0,@VDPWA Send high byte of VDP RAM write address ANDI R0,>3FFF Restore R0 to be as nondestructive as possible VSMWLP MOVB R1,@VDPWD Write byte to VDP RAM DEC R2 Byte counter JNE VSMWLP Check if done RT ** * VDP Multiple Byte Write * * Writes the number of bytes indicated in R2 from the CPU RAM * starting at the address indicated by R1 and places them in * the VDP RAM starting at the address indicated by R0. * VMBW MOVB @R0LB,@VDPWA Send low byte of VDP RAM write address ORI R0,>4000 Set read/write bits 14 and 15 to write (01) MOVB R0,@VDPWA Send high byte of VDP RAM write address ANDI R0,>3FFF Restore R0 to be as nondestructive as possible VMBWLP MOVB *R1+,@VDPWD Write byte to VDP RAM DEC R2 Byte counter JNE VMBWLP Check if done RT ** * VDP Single Byte Read * * Reads a byte from VDP RAM address indicated in R0 and places * it in the most-significant byte of R1. * VSBR MOVB @R0LB,@VDPWA Send low byte of VDP RAM write address ANDI R0,>3FFF Set read/write bits 14 and 15 to read (00) MOVB R0,@VDPWA Send high byte of VDP RAM write address MOVB @VDPRD,R1 Read byte from VDP RAM RT ** * VDP Multiple Byte Read * * Reads the number of bytes indicated in R2 from the VDP RAM * starting at the address indicated by R0 and places them in * the CPU RAM starting at the address indicated by R1. * VMBR MOVB @R0LB,@VDPWA Send low byte of VDP RAM write address ANDI R0,>3FFF Set read/write bits 14 and 15 to read (00) MOVB R0,@VDPWA Send high byte of VDP RAM write address VMBRLP MOVB @VDPRD,*R1+ Read byte from VDP RAM DEC R2 Byte counter JNE VMBRLP Check if finished RT ** * VDP Write To Register * * Writes the value in the least-significant byte of R0 to the * VDP register indicated in the most-significant byte of R0. * VWTR MOVB @R0LB,@VDPWA Send low byte (value) to write to VDP register ORI R0,>8000 Set up a VDP register write operation MOVB R0,@VDPWA Send high byte (address) of VDP register RT END Edited November 20, 2009 by matthew180 Quote Link to comment Share on other sites More sharing options...
Opry99er Posted November 21, 2009 Author Share Posted November 21, 2009 This Lottrup book is very handy... I am beginning to understand a bit of what this stuff means..... Quote Link to comment Share on other sites More sharing options...
matthew180 Posted November 21, 2009 Share Posted November 21, 2009 Yup, Lottrup's book will defiantly get you going. You still have to take a lot of things on faith though. I'm working on two "chapters" right now, one on understanding memory and another is an in depth explanation of a clear screen function. Both are about 5 pages long so far and about half done based on what I still have in my head to write down. Matthew Quote Link to comment Share on other sites More sharing options...
Opry99er Posted November 21, 2009 Author Share Posted November 21, 2009 This is great stuff, Matthew. Thanks for the routines..... That's critical stuff up there Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.