erichenneke Posted March 21, 2015 Share Posted March 21, 2015 Checking to see if this is a known issue, and if there is any way around it without wasting a DPEEK. I wanted to have a ML routine return a large number value to basic by storing the lo byte in location 212 and hi byte in location 213, which should return the decimal value to basic into the assigned variable X ( since I used X=USR in the ML call). Works fine in Turbo Basic XL. Exactly as I thought it would behave. However, when I compile the program it does not return the same value to X and the value seems unpredictable. Is this a known issue? I know I could just store the values in a couple of other known memory locations and the DPEEK them in turbo basic xl, but that seems like a waste since it should just be returned to the variable defined in the USR call from turbo basic xl. Attached is the simple test TBXL code, and below is the simple ASM code used in the USR call. If you run the basic code you will see it works fine. Then compile it and it will not. Thanks, Eric PLA lda $9C54 ldx $9C55 adc $9c56 sta $d4 txa adc $9c57 sta $d5 RTS tryfp.bas Quote Link to comment Share on other sites More sharing options...
Rybags Posted March 21, 2015 Share Posted March 21, 2015 $9Cxx - that would be screen Ram wouldn't it? Possibly a compiled program executes with the screen at $Bcxx which might affect things. Quote Link to comment Share on other sites More sharing options...
flashjazzcat Posted March 21, 2015 Share Posted March 21, 2015 I may be wrong... I probably am... But why do I recall a known bug which results in USR results not being passed back properly in compiled programs. Quote Link to comment Share on other sites More sharing options...
erichenneke Posted March 21, 2015 Author Share Posted March 21, 2015 $9Cxx - that would be screen Ram wouldn't it? Possibly a compiled program executes with the screen at $Bcxx which might affect things. Thanks for the quick response. However, i don't think that's causing it. Screen memory is starting at 45152 so I am way below that. Also, I just checked the 40000-41000 block of memory in basic and again during a compiled program execution and in both cases that area is empty. And as far as i can tell the screen memory is still at 45152 when compiled as well. Quote Link to comment Share on other sites More sharing options...
flashjazzcat Posted March 21, 2015 Share Posted March 21, 2015 (edited) Try and DPEEK $D4 after calling the USR routine to see what's actually there. State of carry flag is indeterminate at start of assembly language routine as well. Right: just traced this in Altirra and it looks like the runtime does indeed trash FR0 when it comes out of a USR call. Edited March 21, 2015 by flashjazzcat Quote Link to comment Share on other sites More sharing options...
erichenneke Posted March 21, 2015 Author Share Posted March 21, 2015 Try and DPEEK $D4 after calling the USR routine to see what's actually there. Well, no, it is not but that is the way it works in both basic and compiled. a DPEEK of 212 comes back with a value of 212 every time ( in basic as well ). Even if you say Poke 212,0 and then immediately ? Peek(212) it will come back with 212. But the way it is supposed to work is if you put lo byte in 212 and hi byte in 213 during the USR routine, then it should return the full decimal value into the variable X in the X=USR call. Works in basic, doesn't work compiled though. Here is what I am basic it on from atari memory map... 212-217 D4-D9 FR0 Floating point register zero; holds a six-byte internal form of the FP number. The value at locations 212 and 213 are used to return a two-byte hexadecimal value in the range of zero to 65536 ($FFFF) to the BASIC program (low byte in 212, high byte in 213). The floating point package, if used, requires all locations from 212 to 255. All six bytes of FR0 can be used by a machine language routine, provided FR0 isn't used and no FP functions are used by that routine. To use 16 bit values in FP, you would place the two bytes of the number into the least two bytes of FR0 (212, 213; $D4, $D5), and then do a JSR to $D9AA (55722), which will convert the integer to its FP representation, leaving the result in FR0. To reverse this operation, do a JSR to $D9D2 (55762). Quote Link to comment Share on other sites More sharing options...
flashjazzcat Posted March 21, 2015 Share Posted March 21, 2015 (edited) See my edited comment above. Edited March 21, 2015 by flashjazzcat Quote Link to comment Share on other sites More sharing options...
Rybags Posted March 21, 2015 Share Posted March 21, 2015 The reason you "corrupt" $D4 (212) is that it's used by the FP for conversion of binary <--> BCD. A PEEK or DPEEK function would have it's lookup address stored there. When a USR function is called, the 2 bytes on entry should contain the address of the ML routine. On exit, Basic simply does the FP call to convert binary back to FP to give you the result of the USR function (or at least that's the theory except in this case). 2 Quote Link to comment Share on other sites More sharing options...
+JAC! Posted March 22, 2015 Share Posted March 22, 2015 (edited) >simply does the FP call to convert binary back to FP to give you the result of the USR function That's exactly what the compiled code is doing. Unfortunately, as opposed to BASIC and TBXL Interpreter, the compiler runtime does load the result word from D4/D5 into the registers/different locations before it calls the BCD conversion. The only way around this I see is to store the result yourself and a different location an read it from there via DPEEK. Edited March 22, 2015 by JAC! Quote Link to comment Share on other sites More sharing options...
flashjazzcat Posted March 22, 2015 Share Posted March 22, 2015 You mean does NOT load the result from $D4/D5: indeed it purposefully obliterates what the user's code just stored there. Quote Link to comment Share on other sites More sharing options...
Kyle22 Posted March 22, 2015 Share Posted March 22, 2015 (edited) See my edited comment above. Capture.PNG I tried putting an RTS at $E909, but it doesn't work. It returns strange values, or causes ERROR-3. I wish there was complete, commented source code for the TBXL package. What ever happened to Frank Ostrowski? The snapshot of my test program DOES NOT WORK! Well, the program works, but the RUNTIME needs more patching. It's just a quick and dirty search/replace patcher I wrote quickly to test this. If anyone knows what all needs patched, you could modify this (and post results here) Edited March 22, 2015 by Kyle22 Quote Link to comment Share on other sites More sharing options...
erichenneke Posted March 22, 2015 Author Share Posted March 22, 2015 >simply does the FP call to convert binary back to FP to give you the result of the USR function That's exactly what the compiled code is doing. Unfortunately, as opposed to BASIC and TBXL Interpreter, the compiler runtime does load the result word from D4/D5 into the registers/different locations before it calls the BCD conversion. The only way around this I see is to store the result yourself and a different location an read it from there via DPEEK. Yep, that's exactly how i am handling it for now but i was hoping to avoid extra DPEEK in the mainloop of my program execution by just using the result returned to the variable in the X=USR call. No big deal, but it is a wasted DPEEK. Bummer. 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.