Asmusr Posted May 20, 2015 Share Posted May 20, 2015 Very nice. Sounds great. I noticed you have two memory word before you main program: VSTAT DATA >8000 * VDP vsync status NUM01 DATA 1 * 16-bit number 1 These will be executed as instructions because you program starts at SFIRST! If you want it to start at MAIN your last line should be: SLAST END MAIN Quote Link to comment https://forums.atariage.com/topic/237815-simon-game-in-assembly-language/page/2/#findComment-3241503 Share on other sites More sharing options...
Dexter Posted May 21, 2015 Author Share Posted May 21, 2015 Thanks Rasmus-M, nicely spotted. I also have to turn off all the sprites, some of them are causing garbage on the screen. Next I'm going to do the sounds and some text output routines... Quote Link to comment https://forums.atariage.com/topic/237815-simon-game-in-assembly-language/page/2/#findComment-3241754 Share on other sites More sharing options...
Gazoo Posted May 21, 2015 Share Posted May 21, 2015 I'm really looking forward to the final product. I've never been a game player, but have an interesting history with the game. I first encountered Simon at a dorm party at WCU in the late 70's. Someone else was playing it and I thought to myself "That looks cool!" After that person was done playing (unsuccessfully) they handed it to me. I started playing and soon had the attention of everyone in the room as I was doing well. (I was at college pursuing a BS in Music). I ended up finishing the game successfully, and was coaxed into doing it several more times. I thought nothing more of it other than it was fun. All you had to do was remember the pattern of the solfege notes so-do-mi-so. Simple! It's apparently not so simple for the musically uninclined, though. This is the one game I can actually play. Gazoo 3 Quote Link to comment https://forums.atariage.com/topic/237815-simon-game-in-assembly-language/page/2/#findComment-3242149 Share on other sites More sharing options...
+InsaneMultitasker Posted May 22, 2015 Share Posted May 22, 2015 Really nice progress!! I wrote an extended basic version a few years ago for one of the contests at the time, though I think we only had 30 lines of code to play with. Always enjoyed playing this game although the last time we had a group together, I vaguely remember consuming an alcohol-based penalty for missing the notes. That was a dangerous challenge I can't wait to see your final product! Quote Link to comment https://forums.atariage.com/topic/237815-simon-game-in-assembly-language/page/2/#findComment-3242205 Share on other sites More sharing options...
Dexter Posted May 22, 2015 Author Share Posted May 22, 2015 (I was at college pursuing a BS in Music). I ended up finishing the game successfully Indeed that’s extremely helpful! In my youth, I had music lessons in Electronic Organ, (not so popular anymore) and the game is like playing music on a “keyboard”. How helpful that is, I discovered recently. I made the SIMON game from this site: http://www.grandideastudio.com/portfolio/AVRSimon/ I created a PCB with the buttons arranged like on the schematic. Unfortunately, that wasn’t right, and the tones were scrambled, i.e. not from low to high like it should be. Playing the game like that was dreadful. That particular SIMON game also has a silent mode, that’s also rather difficult to play, although not as hard as hearing the sounds not in the right order. I wrote an extended basic version a few years ago for one of the contests at the time Yep, I found it (if you’re Tim) while researching the game on lots of different fronts. Your version is really quick for extended basic, a very fast response. I vaguely remember consuming an alcohol-based penalty for missing the notes. I could program something like this: “have a beer and try again...” There are quite some versions and deviations, like increasing speed while progressing in the game, silent mode, blind mode, reverse mode and so on. However I’ll first focus on one variant only. 1 Quote Link to comment https://forums.atariage.com/topic/237815-simon-game-in-assembly-language/page/2/#findComment-3242523 Share on other sites More sharing options...
Dexter Posted June 6, 2015 Author Share Posted June 6, 2015 Progress on SIMON is pretty slow, but that’s because I’m enjoying the view during the ride. Everything is new, so making graphics, music etc. costs a lot of investigation. I’ve also been working on a much shorter development workflow with ralphb’s cross-development tools. http://atariage.com/forums/topic/233677-xdt99-new-ti-99-cross-development-tools-available/ Basically it’s now as easy as the click on a button, to create EA5 files in V9T9 format, to try them out on the emulator(s) and the real thing. It’s not working 100% every time, but that’s another story. Here I have a little program that generates a list of 64 random numbers from 0-3, each stored in one word, starting at >a000. I know, wasteful, but it’s just for convenience. It uses some code of Matthew180's gameloop, like the random generator and the stack. I’m using a pointer to the “buffer” where the random numbers are located. For the pointer, I’m using R9, but I’d rather use a regular ram location, or even a scratch pad location as a pointer. Despite this is working, I’m not satisfied with the code. Is there a more convenient way to do this? Furthermore, am I using the def’s like sfirst etc. correctly? def sfirst,slast,sload,main sfirst equ $ sload equ $ b @main ** * workspace wrksp equ >8300 * workspace ** * random number memory map stack equ >8320 * subrouting stack, grows down (8 bytes) rand16 equ >83c0 * 16-bit random number aorg >a000 * absolute origin at >a000 rndpnt equ $ * pointer to the random number buffer rndbuf bss 128 * 64 words random number buffer, with values 0-3 *rndpnt data >a000 * pointer to the random number buffer main li r10,stack * set up the stack pointer li r9,rndpnt * set up random buffer pointer li r1,64 * initiate counter for 64 loops lp bl @grnd * get random number dec r1 * decrease value in r1 by one jne lp * if not zero, return to loop lp p jmp p * endless loop ** * general workspace use: * * r9 random number buffer pointer * r10 stack pointer * r11 return address ********************************************************************* * * get random number from 0-3 * grnd mov r11,*r10+ * push return address onto the stack bl @randno * get new random number, stored in rand16 srl r5,14 * divide 16-bit value through * * 16384 to get value from 0-3 mov r5,*r9+ * store the random number in * * buffer and increase the pointer dect r10 * pop return address off the stack mov *r10,r11 b *r11 ********************************************************************* * * generates a weak pseudo random number and places it in rand16 * * r4 - destroyed * r5 - 16-bit random number and stored in rand16 for next round * randno li r4,28643 * a prime number to multiply by mpy @rand16,r4 * multiply by last random number ai r5,31873 * add a prime number mov r0,r4 * save r0 * mov @tick,r0 * use the vsync tick to mix it up a little andi r0,>000f * check if shift count is 0 jeq rand01 * a 0 count means shift 16, which is a wash src r5,0 * mix up the number to break odd/even pattern rand01 mov r5,@rand16 * save this number for next time mov r4,r0 * restore r0 b *r11 slast end sfirst 1 Quote Link to comment https://forums.atariage.com/topic/237815-simon-game-in-assembly-language/page/2/#findComment-3251905 Share on other sites More sharing options...
Asmusr Posted June 6, 2015 Share Posted June 6, 2015 It looks OK to me, but as it stands you don't really need the rndpnt equate since it's the same as rndbuf. If you want it to be a pointer stored in a memory location it should be something like "rndpnt data rndbuf". Then you could get the value of the pointer using "mov @rndpnt,r9" and increment it using "inct @rndpnt". I also noticed that you have commented out the @tick part of the randno routine, but you're still shifting using whatever value r0 may contain, which is probably OK for making it a bit more random. Edit: Also note that you can get a random number seed from >83C0. 1 Quote Link to comment https://forums.atariage.com/topic/237815-simon-game-in-assembly-language/page/2/#findComment-3251932 Share on other sites More sharing options...
Dexter Posted June 6, 2015 Author Share Posted June 6, 2015 it should be something like "rndpnt data rndbuf". Then you could get the value of the pointer using "mov @rndpnt,r9" and increment it using "inct @rndpnt". That’s indeed like what I meant. I'll give it a try. I also noticed that you have commented out the @tick part of the randno routine, but you're still shifting using whatever value r0 may contain, which is probably OK for making it a bit more random. Edit: Also note that you can get a random number seed from >83C0. Oh yeah, I just commented it out, because I pulled the routines out of SIMON, to isolate this random number issue. It’s going to be in there. I think the initial seed will be from >83c0 1 Quote Link to comment https://forums.atariage.com/topic/237815-simon-game-in-assembly-language/page/2/#findComment-3252149 Share on other sites More sharing options...
Tursi Posted June 9, 2015 Share Posted June 9, 2015 I found in practice that the initial seed isn't always enough -- it's just a number that is steadily incremented on the master title page. Back in the day, I found that I hit a key so quickly and so predictably there that my number was frequently very close (if not the same - probably just close because back then I divided down). What helps with that, is I continue incrementing the seed on my own title page in any app I build, that helps improve the randomness. Quote Link to comment https://forums.atariage.com/topic/237815-simon-game-in-assembly-language/page/2/#findComment-3254000 Share on other sites More sharing options...
Dexter Posted June 9, 2015 Author Share Posted June 9, 2015 I found in practice that the initial seed isn't always enough -- it's just a number that is steadily incremented on the master title page. Back in the day, I found that I hit a key so quickly and so predictably there that my number was frequently very close (if not the same - probably just close because back then I divided down). What helps with that, is I continue incrementing the seed on my own title page in any app I build, that helps improve the randomness. Good Idea, in my game, the player has to press "s" to start the game. That's the point when the seed could be taken from "tick". It looks OK to me, but as it stands you don't really need the rndpnt equate since it's the same as rndbuf. If you want it to be a pointer stored in a memory location it should be something like "rndpnt data rndbuf". Then you could get the value of the pointer using "mov @rndpnt,r9" and increment it using "inct @rndpnt". I also noticed that you have commented out the @tick part of the randno routine, but you're still shifting using whatever value r0 may contain, which is probably OK for making it a bit more random. Edit: Also note that you can get a random number seed from >83C0. It completely works to my satisfaction now! However, by the time I read from >83c0, it always has the same value. >8379 on the other hand, is always different. In this version, I have taken the initial seed from >8378, which is >00xx. def sfirst,slast,sload,main sfirst equ $ sload equ $ b @main ** * workspace wrksp equ >8300 * workspace ** * random number memory map stack equ >8320 * subrouting stack, grows down (8 bytes) aorg >b000 * absolute origin at >a000 main limi 0 lwpi wrksp mov @>8378,@rand16 * initialize seed by user keypress li r10,stack * set up the stack pointer mov @rndpnt,r9 * set up random buffer pointer li r1,64 * initiate counter for 64 loops lp bl @grnd * get random number dec r1 * decrease value in r1 by one jne lp * if not zero, return to loop lp p1 jmp p1 * endless loop p jmp p * endless loop ** * general workspace use: * * r9 random number buffer pointer * r10 stack pointer * r11 return address ********************************************************************* * * get random number from 0-3 * grnd mov r11,*r10+ * push return address onto the stack bl @randno * get new random number, stored in rand16 srl r5,14 * divide 16-bit value through * * 16384 to get value from 0-3 mov @rndpnt,r9 mov r5,*r9 * store the random number in inct @rndpnt * * buffer and increase the pointer dect r10 * pop return address off the stack mov *r10,r11 b *r11 ********************************************************************* * * generates a weak pseudo random number and places it in rand16 * * r4 - destroyed * r5 - 16-bit random number and stored in rand16 for next round * randno li r4,28643 * a prime number to multiply by mpy @rand16,r4 * multiply by last random number ai r5,31873 * add a prime number mov r0,r4 * save r0 * mov @tick,r0 * use the vsync tick to mix it up a little andi r0,>000f * check if shift count is 0 jeq rand01 * a 0 count means shift 16, which is a wash src r5,0 * mix up the number to break odd/even pattern rand01 mov r5,@rand16 * save this number for next time mov r4,r0 * restore r0 b *r11 aorg >b0a0 * absolute origin at >a000 rndbuf bss 128 * 64 words random number buffer, with values 0-3 rndpnt data >b0a0 * pointer to the random number buffer rand16 data >ffff * 16-bit random number slast end sfirst Should I place those variables in line 81 and 82 in scratch pad memory, perhaps even those random numbers too (in a more compact format)? 1 Quote Link to comment https://forums.atariage.com/topic/237815-simon-game-in-assembly-language/page/2/#findComment-3254323 Share on other sites More sharing options...
Asmusr Posted June 9, 2015 Share Posted June 9, 2015 Should I place those variables in line 81 and 82 in scratch pad memory, perhaps even those random numbers too (in a more compact format)? Only if you want it to run from a cartridge without 32K. I don't think the access speed matters for a Simon game. I think you will get tired of the aorg in line 79 that you have to change every time your program grows. There is no real need for it, just use "rndpnt data rndbuf" to initialize the pointer to point to the buffer (whereever it is located). Quote Link to comment https://forums.atariage.com/topic/237815-simon-game-in-assembly-language/page/2/#findComment-3254341 Share on other sites More sharing options...
+Lee Stewart Posted June 9, 2015 Share Posted June 9, 2015 ... Edit: Also note that you can get a random number seed from >83C0. Only at power-up. After that it is used by the pseudo-random-number (PRN) generators (often the same code) in TI Basic, XB, TI Forth, the fbForths, ... to store the generated number for the next go-round. This is what guarantees the same sequence of PRNs from the same initial seed, which allows for checking programs using those PRNs. ====================== I see that you (@Dexter) are using what TI used with two differences: For some reason, TI’s formula was (seed * >6FE5 + >7AB9) SRC 5. Neither >65E5 nor >7AB9 is prime; but, they are both odd. The circular right shift is always a 5-bit shift. Here is the routine I use for fbForth: *** random number generator routine *** _RNDW LI R0,>6FE5 MPY @>83C0,R0 AI R1,>7AB9 SRC R1,5 MOV R1,@>83C0 B *LINK Also, here is the routine I use to randomize the seed when necessary: *** RANDOMIZE *** ( --- ) * increments a counter until VDP interrupt detected * DATA SEED_N * RNZ__N DATA 9+TERMBT*LSHFT8+'R','AN','DO','MI','ZE'+TERMBT RNDMZ DATA $+2 RNZ_P MOVB @>8802,R0 get VDP status byte CLR R0 discard it CLR R1 clear counter S1016A INC R1 increment counter MOVB @>8802,R0 get VDP status byte ANDI R0,>8000 VDP interrupt? JEQ S1016A no, increment counter MOV R1,@>83C0 yes, store new seed B *NEXT ...lee 2 Quote Link to comment https://forums.atariage.com/topic/237815-simon-game-in-assembly-language/page/2/#findComment-3254522 Share on other sites More sharing options...
Dexter Posted June 10, 2015 Author Share Posted June 10, 2015 @Lee Stewart I saw your reply in another thread, about random numbers: http://atariage.com/forums/topic/189117-restless-games/?p=3254385 That gave me some answers already. I see that you (@Dexter) are using what TI used with two differences: ... Thanks for the more in-depth information, so the second routine I just have to call if I want to ensure I get a new random seed, i.e. to get a new set of random numbers? And because I’m only checking the VDP’s status register, I can do that with the interrupts disabled? (limi 0) While debugging it’s often more desirable to get the same set of random numbers, just to see if the program behaves like I expect it to. Then I set the seed to a fixed number. I think you will get tired of the aorg in line 79 that you have to change every time your program grows. There is no real need for it, just use "rndpnt data rndbuf" to initialize the pointer to point to the buffer (whereever it is located). You’re right, but I used it only for debugging reasons, to see the data in the debugger at a fixed place. -------- Next I’m going to implement it in the game, to get a first working version, I hope... Quote Link to comment https://forums.atariage.com/topic/237815-simon-game-in-assembly-language/page/2/#findComment-3254787 Share on other sites More sharing options...
+Lee Stewart Posted June 10, 2015 Share Posted June 10, 2015 ... Thanks for the more in-depth information, so the second routine I just have to call if I want to ensure I get a new random seed, i.e. to get a new set of random numbers? Correct. And because I’m only checking the VDP’s status register, I can do that with the interrupts disabled? (limi 0) I believe so. While debugging it’s often more desirable to get the same set of random numbers, just to see if the program behaves like I expect it to. Then I set the seed to a fixed number. You will not get the same set if you use lines 71 – 74 of your post #35 because the shift is unpredictable. ...lee Quote Link to comment https://forums.atariage.com/topic/237815-simon-game-in-assembly-language/page/2/#findComment-3254852 Share on other sites More sharing options...
Dexter Posted June 10, 2015 Author Share Posted June 10, 2015 You will not get the same set if you use lines 71 – 74 of your post #35 because the shift is unpredictable. ...lee Yes indeed, I have to comment them out when I want that. Quote Link to comment https://forums.atariage.com/topic/237815-simon-game-in-assembly-language/page/2/#findComment-3254862 Share on other sites More sharing options...
Tursi Posted June 10, 2015 Share Posted June 10, 2015 You’re right, but I used it only for debugging reasons, to see the data in the debugger at a fixed place. Assemble with a listing file - you can use the listing file to see where everything got stored in memory for debugging purposes. Quote Link to comment https://forums.atariage.com/topic/237815-simon-game-in-assembly-language/page/2/#findComment-3254948 Share on other sites More sharing options...
matthew180 Posted June 10, 2015 Share Posted June 10, 2015 Thanks for the more in-depth information, so the second routine I just have to call if I want to ensure I get a new random seed, i.e. to get a new set of random numbers? And because I’m only checking the VDP’s status register, I can do that with the interrupts disabled? (limi 0) If you are reading the VDP status register directly then you really must use LIMI 0 to prevent the console ISR from running. Pulling the VDP status out from under the console ISR is a "bad thing". If you want to co-exist with the console ISR, then you have to follow the ISR's rules for using the scratchpad RAM. If you leave CPU interrupts enabled (LIMI 2) and use the console ISR, then I suggest you use the ISR's hook to update your game loop. Quote Link to comment https://forums.atariage.com/topic/237815-simon-game-in-assembly-language/page/2/#findComment-3254963 Share on other sites More sharing options...
Dexter Posted June 11, 2015 Author Share Posted June 11, 2015 (edited) Assemble with a listing file - you can use the listing file to see where everything got stored in memory for debugging purposes. Good point, that’s very often the case. However, I’m using ralphb’s xdt99: TI 99 Cross-Development Tools http://atariage.com/forums/topic/233677-xdt99-new-ti-99-cross-development-tools-available/, which does an incredibly good job I have to say. At the moment it doesn’t support outputting a listing file, but I could use WinAsm99 for that, of course. If you are reading the VDP status register directly then you really must use LIMI 0 to prevent the console ISR from running. Pulling the VDP status out from under the console ISR is a "bad thing". If you want to co-exist with the console ISR, then you have to follow the ISR's rules for using the scratchpad RAM. If you leave CPU interrupts enabled (LIMI 2) and use the console ISR, then I suggest you use the ISR's hook to update your game loop. Thanks, I intent to leave the interrupt off, and use your “gameloop” from the assembly thread. When reading the status register, it will be cleared, so an interrupt could be missed, right? -------- Here is the fruit of my work, just a little strawberry though. So far I have Graphics, Music, Keyboard (just the S-key) and the random generator. There's NO gameplay yet, only pressing "S" will give a set of 64 random numbers. System requirements: Extended BASIC Disk drive 32KiB memory expansion F18A (although it works without for now) The program will autostart from DSK1. The source file is attached, so feel free to give lots of suggestions etc. I’m sure things could be done more efficiently. Music and graphics are done by me, myself and I(rene) Except for the character set, which is from some game on the C64. myloop.a99 runme.dsk Edit: Correction, not the fruit of my work alone, but very much of your invaluable help! Edited June 11, 2015 by Dexter 3 Quote Link to comment https://forums.atariage.com/topic/237815-simon-game-in-assembly-language/page/2/#findComment-3255523 Share on other sites More sharing options...
+Lee Stewart Posted June 12, 2015 Share Posted June 12, 2015 If you are reading the VDP status register directly then you really must use LIMI 0 to prevent the console ISR from running. Pulling the VDP status out from under the console ISR is a "bad thing". If you want to co-exist with the console ISR, then you have to follow the ISR's rules for using the scratchpad RAM. If you leave CPU interrupts enabled (LIMI 2) and use the console ISR, then I suggest you use the ISR's hook to update your game loop. It was the TI developers of TI Forth who originally wrote the RANDOMIZE routine I use in fbForth. The point of the routine is to race the console ISR for the VDP interrupt, counting how many reads it takes to catch it before the console ISR does. Certainly, one VDP interrupt will be missed. One more could be missed with the initial VDP status read, if it is set. Though possible, that is unlikely. The swiped VDP interrupt will cause a hesitation in sprite automotion and ISR-processed sound lists; but, is it a “bad thing”, otherwise? ...lee Quote Link to comment https://forums.atariage.com/topic/237815-simon-game-in-assembly-language/page/2/#findComment-3256011 Share on other sites More sharing options...
Tursi Posted June 12, 2015 Share Posted June 12, 2015 In general, probably not. If you're relying on regular interrupts for anything important, you'd want to know about it, but it won't break anything otherwise. Quote Link to comment https://forums.atariage.com/topic/237815-simon-game-in-assembly-language/page/2/#findComment-3256177 Share on other sites More sharing options...
Asmusr Posted June 12, 2015 Share Posted June 12, 2015 Are you going to require an F18A just in order to change the palette or are you planning to use it for something else? If it's just for the palette you could easily obtain the same effect by changing a rectangle in color table (but I'm sure you know that already). Quote Link to comment https://forums.atariage.com/topic/237815-simon-game-in-assembly-language/page/2/#findComment-3256356 Share on other sites More sharing options...
Dexter Posted June 13, 2015 Author Share Posted June 13, 2015 Are you going to require an F18A just in order to change the palette or are you planning to use it for something else? If it's just for the palette you could easily obtain the same effect by changing a rectangle in color table (but I'm sure you know that already). It was sort of a mix actually, on one hand trying out some arbitrary functions of the F18A and unlocking them, and on the other hand changing the palette with a few values. But indeed, it’s a little bit silly to make the game dependent of the F18A, just for the altering of the palette. I’ll most likely scratch that from SIMON, so that it’s also playable on 4A’s without the F18A. Quote Link to comment https://forums.atariage.com/topic/237815-simon-game-in-assembly-language/page/2/#findComment-3256866 Share on other sites More sharing options...
Dexter Posted June 16, 2015 Author Share Posted June 16, 2015 Are you going to require an F18A just in order to change the palette or are you planning to use it for something else? If it's just for the palette you could easily obtain the same effect by changing a rectangle in color table (but I'm sure you know that already). Well, I’m using half bitmap mode, and the used bytes for the color table are not sequentially as in normal bitmap mode, but scattered over the place. So for the digit 1, there are a few specific characters used, which have do get another value in the color table. S123G MOV R11,*R10+ * Push return address onto the stack li r3,0 * r1 is index ld1 movb @dig1(r3),r4 * load value from dig1+index ci r4,0 * end of table? jeq nld1 * yes, exit loop li r0,>2000 * start of color table a r4,r0 * r0 holds now the actual color table location li r1,>e1 * grey pixels on black background bl @vsbw * store the byte in VRAM inc r3 * increase index b @ld1 * next character nld1 DECT R10 * Pop return address off the stack MOV *R10,R11 B *R11 dig1 byte 145,146,160,171,172,183,209,210,0 I’m using the Indexed Memory Addressing mode, to write >e1 (grey pixels on black background), to the specific color table bytes. The screen gets pretty messed up, so I’m obviously doing something wrong. Quote Link to comment https://forums.atariage.com/topic/237815-simon-game-in-assembly-language/page/2/#findComment-3258770 Share on other sites More sharing options...
+InsaneMultitasker Posted June 16, 2015 Share Posted June 16, 2015 If your BL @VSBW operates on the value of R1's MSByte, you are sending >00 every time. Setting R1 to 0xe100 may be what you need i.e., "LI R1,>E100" Also watch out for similar circumstances in byte-wise operations. For example, If R4 is not set to 0x0000 before your "movb @dig1(r3),r4 " the next test will always fail. Why? MOVB retains whatever is in the LSByte of the destination. Your routine may be executing many, many more times than anticipated. Quote Link to comment https://forums.atariage.com/topic/237815-simon-game-in-assembly-language/page/2/#findComment-3258780 Share on other sites More sharing options...
Asmusr Posted June 17, 2015 Share Posted June 17, 2015 You have to set 8 bytes of the color table for every character. If your @dig1 table is a list of character codes/numbers then you have to do something like this: clr r4 movb @dig1(r3),r4 jeq nld1 swpb r4 sla r4,3 li r0,>2000 a r4,r0 And then you need to use @VSMW to write 8 bytes. Quote Link to comment https://forums.atariage.com/topic/237815-simon-game-in-assembly-language/page/2/#findComment-3258967 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.