RXB Posted January 28, 2015 Share Posted January 28, 2015 (edited) Well, whaddaya know... Learned something today... An un-documented feature: * * FOLLOWING DISPLAYS A NUMBER USING AN * UNDOCUMENTED FEATURE WITH GPLLNK * BY CONVERTING THE INTEGER PLACED AT * >835E INTO A STRING, WHICH IS THEN * DISPLAYED AT ROW 12, COLUMN 7 * THE NUMBER IS DISPLAYED AS AN UNSIGNED * INTEGER FROM 0 THROUGH 65535 * THANKS TO MERLE VOGT FOR THIS ONE! * * LI R0,11*32+6 SET R0, ROW 12, COL 7 MOV @NUMBER,@>835E PLACE NUMBER AT >835E CLR @>837C CLEAR GPL STATUS BYTE BLWP @GPLLNK USE GPLLNK DATA >2F7C TO CONVERT INTEGER TO STRING (UNDOCUMENTED) MOVB @>8361,R2 GET STRING LENGTH SRL R2,8 RIGHT-JUSTIFY MOVB @>8367,R1 GET LOW BYTE OF ADDRESS SRL R1,8 RIGHT-JUSTIFY AI R1,>8300 ADD >8300 HIGH BYTE BLWP @VMBW WRITE STRING TO SCREEN * * (the above taken from Bruce Harrisons articles on FP) Hmm this is just using a TI Basic routine from here in TI Intern: 2F9A : CALL GROM@>2F7C Convert integer into ASCII 2F9D : ST @>8342,*>8367 1st character 2FA1 : CALL GROM@>2FE3 Print 2FA4 : INC @>8367 2FA6 : DEC @>8361 Till all characters 2FA8 : BR I even talked to Bruce Harrison on the phone about a couple of these things when he called me about GPL. Do not remember if this one came up but we were discussing TI Intern and GPL at the time, also about GPL in XB. But it is a cool idea! Edited January 28, 2015 by RXB 1 Quote Link to comment Share on other sites More sharing options...
Willsy Posted January 28, 2015 Share Posted January 28, 2015 Can anyone actually try it and see if it works? Would be cool. I don't have the facilities at the moment. Quote Link to comment Share on other sites More sharing options...
lucien2 Posted January 28, 2015 Share Posted January 28, 2015 It works. I used it in my first GPL program: http://atariage.com/forums/topic/180471-gplhow2/?do=findComment&comment=2260382 Quote Link to comment Share on other sites More sharing options...
Omega-TI Posted January 28, 2015 Author Share Posted January 28, 2015 I was playing around with the editor assembler (in Classic 99) to get familiar with things. Anyway I had ripped off a "Hello World" source code listing from another site to play with, and I ran it through the assembler and ended up with a object file that completed successfully... the problem is, there appears to be no way to START the program. Am I overlooking something painfully obvious here? Hello World.zip Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted January 28, 2015 Share Posted January 28, 2015 I was playing around with the editor assembler (in Classic 99) to get familiar with things. Anyway I had ripped off a "Hello World" source code listing from another site to play with, and I ran it through the assembler and ended up with a object file that completed successfully... the problem is, there appears to be no way to START the program. Am I overlooking something painfully obvious here? Wow! —You picked up a program for the TI-990 minicomputer. @Stuart will likely jump in here shortly. The statement DXOP SVC,15 Define SVC defines an extended operation (SVC) as XOP 15. You can certainly use XOPs on the TI-99/4A, but only XOP 1 and XOP 2—and sometimes only XOP 2—it depends on the console. Learning about XOPs is definitely not where you want to start learning TMS9900 Assembler. I will work on a “Hello, World!” program for the 4A for you. Someone else will probably beat me to it; but, you’ll get one soon. ...lee Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted January 29, 2015 Share Posted January 29, 2015 Here ya go: * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * To keep this "Hello World!" program simple, we make use of the * * GRAPHICS mode text display of the Editor/Assembler. Doing this * * allows us to avoid setting up VDP registers and only requires us * * to clear the screen buffer in VRAM by writing blanks to the buffer. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * MAINWS EQU >8300 Our workspace CPU RAM scratchpad SCSTRT EQU 0 Graphics mode screen start SC_END EQU >0300 " " " end LINE12 EQU 12*32 Line 12 screen location DEF START Needed for auto-start REF VSBW,VMBW VDP single-byte and multi-byte writes START LWPI MAINWS Load our workspace LI R0,SCSTRT Load screen start VRAM address in R0 LI R1,>2000 Load space character in high byte of R1 LI R2,SC_END Load number of bytes to copy * Clear screen (24 lines by 32 characters/line) * SCCLR BLWP @VSBW Copy 1 blank DEC R2 decrement count JEQ NEXT Jump to NEXT if count = 0 INC R0 Increment VRAM address by 1 byte JMP SCCLR Copy next blank to next screen location NEXT LI R0,LINE12 line 12 VRAM address to R0 LI R1,HELLO Load string starting address in R1 LI R2,LEN Load string length in R2 BLWP @VMBW Write string to screen NOEND JMP NOEND Endless loop HELLO TEXT 'Hello, World!' String LEN EQU $-HELLO String length END START This program runs with the same screen mode as the Editor/Assembler, clears the screen with blanks, writes “Hello, World!” and sits and spins in and endless loop. ...lee 1 Quote Link to comment Share on other sites More sharing options...
Asmusr Posted January 29, 2015 Share Posted January 29, 2015 I was playing around with the editor assembler (in Classic 99) to get familiar with things. Anyway I had ripped off a "Hello World" source code listing from another site to play with, and I ran it through the assembler and ended up with a object file that completed successfully... the problem is, there appears to be no way to START the program. Am I overlooking something painfully obvious here? Well, I already made you a hello world program in post #32. Quote Link to comment Share on other sites More sharing options...
Omega-TI Posted January 29, 2015 Author Share Posted January 29, 2015 Well, I already made you a hello world program in post #32. Yes, thank you for that. Actually my plan was to run both programs, view the differences (if any) and try to discern what commands did what and where for the results. Quote Link to comment Share on other sites More sharing options...
Omega-TI Posted January 29, 2015 Author Share Posted January 29, 2015 Here ya go: This program runs with the same screen mode as the Editor/Assembler, clears the screen with blanks, writes “Hello, World!” and sits and spins in and endless loop. ...lee Thanks Lee, I'll run this program and the other one too and see exactly what is happening. I have the next two days off, but I have so many things I have to take care of in those two days, I might not get to it right away... sorry. In fact it's way past this old mans bed time and I have to get up early to feed the cows before I tackle the rest of the day tomorrow... so it's off to bed! Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted January 29, 2015 Share Posted January 29, 2015 Well, I already made you a hello world program in post #32. So much for my short-term memory! Well, I am old. ...lee Quote Link to comment Share on other sites More sharing options...
palmheads Posted February 3, 2015 Share Posted February 3, 2015 (edited) So been playing with xdt99, js99er web emulator with mini-memory module loaded and the Lottrup book. Made my own sprite & got it scrolling across the page by using an example in the book The sprite is the ship off the game "Thrust", magnification 2 See attached motion.asm Feel like with this I have the start of the building blocks of porting "Thrust" to the TI. Next step am gonna try being able to move the sprite around the screen. There is an example of something similar in the Lottrup book with a hires sketch app using the arrow keys. if using xdt99 tools, make object file thus: ./xas99.py -OR motion.asm Then load object file to a disk image, load & run thru mini-memory. I normally run it thru EasyBug using 'E7D00' To see "Thrust" the game in action, here is the BBC Micro version cheers Daryn motion.asm Edited February 3, 2015 by palmheads 4 Quote Link to comment Share on other sites More sharing options...
+InsaneMultitasker Posted February 3, 2015 Share Posted February 3, 2015 That "Thrust" looks like a fun game! Quote Link to comment Share on other sites More sharing options...
palmheads Posted February 3, 2015 Share Posted February 3, 2015 That "Thrust" looks like a fun game! Yeah its a fantastic game. Its been ported to almost every 8 bit machine known to man. Graphics are simple, but the gameplay amazing. The physics of the game are great, collecting the orb, it being heavy causing all sorts of momentum mayhem. Feels like a good fit for the TI, not a huge amount of sprites, all one colour. Am sure with assembly the gameplay would be fast enough. In my example above moving the sprite across the page looked plenty quick to me. cheers Daryn Quote Link to comment Share on other sites More sharing options...
palmheads Posted February 6, 2015 Share Posted February 6, 2015 (edited) Hi all Got a question. Been trying to get my sprite moving around the screen using the arrow keys (E-S-D-X). Have more or less got it working, but for some reason my sprite mostly disappears. Its looks like of the 4 data statements to make the sprite, only the top left quadrant actually moves! So the whole sprite appears initially, but then only part of it thereafter. I can't see what I am doing wrong. Here is my source... aorg >7d00 lwpi >70b8 ;load registers li r14,>0016 ;pixel movement li r0,>0420 li r1,df ;sprite 0 def li r2,32 blwp @>6028 li r0,>0300 li r1,dt ;sprite 0 attr li r2,5 blwp @>6028 li r0,>01e2 ;sprite magnify 2 blwp @>6034 clr @>8374 ;clearing for keyscan rs clr r1 lp limi 2 limi 0 li r0,>0301 ;row blwp @>6020 ;keyscan clr r3 mov @>8374,r3 ;ascii key ci r3,83 ;s key jne $+10 ai r1,-r14 ;move left blwp @>6024 ci r3,68 ;d key jne $+10 ai r1,r14 ;move right blwp @>6024 li r0,>0300 ;col ci r3,69 ;e key jne $+10 ai r1,-r14 ;move up blwp @>6024 ci r3,88 ;x key jne $+10 ai r1,r14 ;move down blwp @>6024 ci r3,90 ;z key jne $+10 ai r1,r14 ;move down blwp @>6024 jmp lp df data >0102,>0204,>0408,>0810 ; sprite 0 - 4 cnrs data >1060,>8040,>2023,>1408 data >0080,>8040,>4020,>2010 data >100c,>0204,>0888,>5020 dt data >0000,>8401,>d000 aorg >701c data >7d1e data >7fe0 aorg >7fe0 text 'SPRITE' data >7d00 end Am running it through mini memory (hence the AORG 7D00 etc). Any ideas what I have missed? cheers Daryn Edited February 6, 2015 by palmheads Quote Link to comment Share on other sites More sharing options...
+mizapf Posted February 6, 2015 Share Posted February 6, 2015 If you set video register 1 and you allow interrupts, you must copy its value to 83D4 before because the interrupt handler will copy that value to register 1 when you press a key. Quote Link to comment Share on other sites More sharing options...
Asmusr Posted February 6, 2015 Share Posted February 6, 2015 I'm not sure I'm able to follow your code, but these lines "ai r1,r14" and "ai r1,-r14" look a bit strange. Should you be using "a r14,r1" and "s r14,r1" instead? Quote Link to comment Share on other sites More sharing options...
palmheads Posted February 6, 2015 Share Posted February 6, 2015 I'm not sure I'm able to follow your code, but these lines "ai r1,r14" and "ai r1,-r14" look a bit strange. Should you be using "a r14,r1" and "s r14,r1" instead? Hi Rasmus For that was using an example from the Lottrup assembly language book, with my own mod From the book, the first "Add Immediate" line moves my sprite 16 pixels to the right. From the book, you can add a minus to effectively have a "Subtract Immediate", so the second with the '-' moves it 16 pixels to the left ai r1,>0016 ai r1,->0016 I made a small mod, instead of having to type '>0016' 4 times, I assigned it to register 14 li r14,>0016 ai r1,r14 ;move right ai r1,-r14 ;move left I dunno if thats the right thing todo, but it does seem to allow me to move my (partial) sprite up/down/left/right. Was basing all of this from an example in the book where a sprite was scrolled right across the screen, which works perfectly. aorg >7d00 lwpi >70b8 li r0,>0420 li r1,df li r2,32 blwp @>6028 li r0,>01e2 ;magnify 2 blwp @>6034 li r0,>0300 ;sprite 0 li r1,dt li r2,5 blwp @>6028 li r0,>0301 rs clr r1 lp ai r1,>0100 blwp @>6024 ci r1,>ff00 jeq rs li r15,1000 dec r15 jne $-2 jmp lp df data >0102,>0204,>0408,>0810 data >1060,>8040,>2023,>1408 data >0080,>8040,>4020,>2010 data >100c,>0204,>0888,>5020 dt data >6080,>8401,>d000 end I don't really know what I'm doing yet, hence my confusion that only part of my sprite is actually getting moved around! cheers Daryn Quote Link to comment Share on other sites More sharing options...
palmheads Posted February 6, 2015 Share Posted February 6, 2015 (edited) If you set video register 1 and you allow interrupts, you must copy its value to 83D4 before because the interrupt handler will copy that value to register 1 when you press a key. Hi mizapf So would doing a MOV/MOVB do that? Something like this? movb r1,@>83D4 Will have a play! cheers Daryn Edited February 6, 2015 by palmheads Quote Link to comment Share on other sites More sharing options...
+mizapf Posted February 6, 2015 Share Posted February 6, 2015 Have a look at the Editor/Assembler manual on page 326 and pages 404-406. Long ago, when I did my first steps in assembly language, these pages really confused me, and they are a quite good example for bad documentation. What TI writes here is not really wrong, but they do not reveal the context where this information is meaningful. In particular, when you keep full control over your program, you certainly do not have to copy the value to 83D4. However, as soon as you allow interrupts with LIMI 2, the interrupt handler gets into action. Patching your code: li r0,>01e2 ; sprite magnify 2 swpb r0 movb r0,@>83d4 swpb r0 blwp @>6034 Quote Link to comment Share on other sites More sharing options...
Willsy Posted February 6, 2015 Share Posted February 6, 2015 (edited) The AI instruction can only take a VALUE as the second parameter, not a register. If you want to add the value *in* a register to another register then you need the A instruction. AI R1, 10 - correct AI R1, R10 - incorrect. Must be a value not a register. A R1, R10 adds the value in R1 to R10, leaving the result in R10 HTH Edited February 6, 2015 by Willsy Quote Link to comment Share on other sites More sharing options...
palmheads Posted February 6, 2015 Share Posted February 6, 2015 Have a look at the Editor/Assembler manual on page 326 and pages 404-406. Long ago, when I did my first steps in assembly language, these pages really confused me, and they are a quite good example for bad documentation. What TI writes here is not really wrong, but they do not reveal the context where this information is meaningful. In particular, when you keep full control over your program, you certainly do not have to copy the value to 83D4. However, as soon as you allow interrupts with LIMI 2, the interrupt handler gets into action. Patching your code: li r0,>01e2 ; sprite magnify 2 swpb r0 movb r0,@>83d4 swpb r0 blwp @>6034 WOOO! That is fantastic! So I guess once you enable interupts for things like keypress recognition, this needs to happen everytime? Thanks so much mizapf - works great! Now have to figure out why it jumps ahead a few pixels as I'm moving the sprite around. Thank you so much! cheers Daryn Quote Link to comment Share on other sites More sharing options...
palmheads Posted February 6, 2015 Share Posted February 6, 2015 (edited) The AI instruction can only take a VALUE as the second parameter, not a register. If you want to add the value *in* a register to another register then you need the A instruction. AI R1, 10 - correct AI R1, R10 - incorrect. Must be a value not a register. A R1, R10 adds the value in R1 to R10, leaving the result in R10 HTH Ah cool, that makes sense. My intent for my AI example was to define a constant in a register (in my case a 16 pixel movement), and then add/sub So this is good ai r1,>0016 ai r1,->0016 What I was doing here is bad li r14,>0016 ai r1,r14 ;move right ai r1,-r14 ;move left thanks Willsy & Rasmus, that makes sense! cheers Daryn Edited February 6, 2015 by palmheads Quote Link to comment Share on other sites More sharing options...
+mizapf Posted February 6, 2015 Share Posted February 6, 2015 The AI instruction can only take a VALUE as the second parameter, not a register. If you want to add the value *in* a register to another register then you need the A instruction. AI R1, 10 - correct AI R1, R10 - incorrect. Must be a value not a register. The funny thing is that this assembles perfectly. Why? - The "R" option of the Assembler adds EQU like R0 EQU 0 R1 EQU 1 ... R15 EQU 15 so the line AI R10,R5 actually assembles as AI 10,5 Quote Link to comment Share on other sites More sharing options...
+mizapf Posted February 6, 2015 Share Posted February 6, 2015 That is fantastic! So I guess once you enable interupts for things like keypress recognition, this needs to happen everytime? Only if you change the value of video register 1. In the above code it suffices to load 83D4 only once. The reason is that the interrupt handler copies the value of 83D4 into video register 1. So if you want it to remain constant, just ensure that 83D4 always contains that value. If you'd like to see the details, have a look at TI Intern, page 34. This is the last part of the handler, shortly before returning. 0A92 D30A MOVB 10,12 VDP register 1 0A94 098C SRL 12,8 0A96 026C ORI 12,>8160 Basis value 0A98 8160 0A9A 024C ANDI 12,>FFBF Turn off screen 0A9C FFBF 0A9E D820 MOVB @>83D9,@>8C02 Load VDP register 0AA0 83D9 0AA2 8C02 0AA4 D80C MOVB 12,@>8C02 0AA6 8C02 0AA8 02E0 LWPI >83E0 GPLWS 0AAA 83E0 0AAC B80E AB 14,@>8379 VDP interrupt timer (system flags!) 0AAE 8379 0AB0 C320 MOV @>83C4,12 User defined interrupt 0AB2 83C4 0AB4 1301 JEQ >0AB8 None, then jump 0AB6 069C BL *12 Otherwise execute 0AB8 04C8 CLR 8 Clear GROM search pointer 0ABA 02E0 LWPI >83C0 INTWS 0ABC 83C0 0ABE 0380 RTWP And end interrupt The workspace is 83C0 (INTWS); accordingly, 83D4 is register 10. So if you store that value in 83D4, you effectively load R10 of INTWS. Quote Link to comment Share on other sites More sharing options...
Gazoo Posted February 7, 2015 Share Posted February 7, 2015 Something that would be nice to have is some sort of tutorial on using a debugger. I've never been able to figure out how they work after numerous attempts over the years. I've always relied on seeing the results of the code I've written to determine where an error might be, then going back to look at the code where the program went astray and altering it until I got the results I was looking for. I know some of you guys here know how to use a debugger, so how about a tutorial? Gazoo 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.