Newsgroups: comp.sys.atari.st Path: utzoo!lsuc!jimomura From: jimomura@lsuc.on.ca (Jim Omura) Subject: A-Line Solution, AES and VDI Message-ID: <1990Nov6.171858.11434@lsuc.on.ca> Reply-To: jimomura@lsuc.on.ca (Jim Omura) Organization: Consultant, Toronto Date: Tue, 6 Nov 90 17:18:58 GMT I've received a number of responses regarding my questions and I think I've replied to most of them. This will summarize the information I have received. Regarding AES and VDI calls from a .TTP program: It seems this is possible. Some of you have done it. I'll read my reference material again with this in mind and I think eventually I may try it out on one of the programs I'm working on. Regarding A-Line Calls: The problem is solved! But before I get to the solution, I'll mention some other things that have arisen. 1. Sozobon C and bugs. This wasn't the problem, but it seems that early versions of Sozobon C had problems with some bitwise code on the assembler level. I have not current evidence if my version has such problems. I should state that I'm using a slightly modified version of Sozobon 1.2. The modifications were made to the TOP optimizer by Ian Lepore on BIX. The information I have is that TOP is NOT reliable and should NOT BE USED AT ALL unless you know how to correct it. Ian's version has been submitted to the Sozobon authors and the last I heard, no decision had been made about his corrections. I trust Ian's judgement on this matter and I'm using his corrected version of the TOP optimizer. Although I've found a couple of other bugs since then (one HCC level bug and one Dlib level bug and maybe one or two others), it's been quite usable. 2. I have received a header #include file from J. Henders. When I double checked my version of DLIBS, my documentation doesn't indicate support for the A-Line functions listed in the header file. Either they simply didn't document it or you've got a later version of DLIBS. Be that as it may, looking at the header was helpful, but I decided not to use it. The problem is one of standardization. I'm basing my variables on the information in "Atari ST Internals." Despite the bugs in the book, they claim to be using "official" Atari Corp. variable names. I think there might be some value in developing code using these names as much as possible, so I've decided to keep them. Otherwise, looking at the variable names for inherent value, it's sort of a toss up. Both sets of variable names have some good points and some bad points. 3. THE SOLUTIONS to my A-Line routine problems: The problem seems to have been caused by my using d3, d4 and a3 registers without storing and restoring contents. I'll start at the beginning. The Sozobon documentation regarding register usage says only this: P. 5 "Any of the basic data types may be declared as register variables. Pointers occupy the A registers, all other types are placed in D registers. Five data registers and three address registers are available for use by register variables." P. 6 "The components of the Sozobon compiler were developed by replacing pieces of the Alcyon compiler one by one." " ... The output of the compiler is suitable for input to other compatible assemblers such as Alcyon's assembler or the MadMac assembler." The Sozobon Assembler likewise produces object files that will link under Alcyon and Sozobon's linker will accept Alcyon object files and libraries. As such, Sozobon can be assumed to be using Alcyon register usage practices. That's nice, but I don't have Alcyon documentation, so I had no idea what those standard practices are. :-) P. 7 "The compiler uses the 'normal' 68000 C calling conventions. Register A6 is used as a frame pointer, and function return values are placed in D0. Registers D3-D7 and A3-A5 are used to hold register variables." I'll assume that this is somehow "normal." I haven't really looked closely at a lot of C compilers, but it still left out a lot. At this point I did my usual trick of partially compiling a "model" program to see how variables were being passed and started in writing my functions. And they worked. At least they worked as far as I tested them. I assumed MISTAKENLY that the compiler was storing 'register' variables *before* making the function call and restoring after the return. This is my own convention when I write pure assembly language. As has been pointed out to me long ago, this is not necessarily the way a compiler will do it. So the first possible solution was simply to stack and unstack the registers I used inside the functions I've written. Hugh Redelmeier provided what is probably a better solution. It's the solution I'm using for now. The problem is that it is based on an assumption. But it's a fairly safe assumption. Apparently it is common to use A0, D0 and D1 as scratchpad registers. Looking at the documentation again, it seemed likely that Sozobon assumes A0 to A2 and D0 to D2 all as scratchpad registers. Proper usage of a scratchpad register assumes that these registers can be corrupted in any called function, so a called function should not have to stack them and unstack them. Hugh provided a version of the function that worked. In fact, I decided to *slowly* mutate my function closer to his version so I could try a few things along the way and see the results. I've learned quite a bit. .text .globl _fgrnd _fgrnd: ; fgrnd(spntr,colour) ; LINE_A spntr ; int colour ; Line-A binding function for Sozobon C ; By Jim Omura ; ;var 4 8 _spntr ;var 2 12 _colour ; link a6,#-0 ; movea.l 8(a6),a0 ; A0 = spntr lea 24(a0),a0 ; A0 points at Plane 1 move.w 12(a6),d1 ; D1 = Colour Reg. moveq #3,d2 ; D2 = Loop Counter ; DISTLP: ; Start Loop "Distribute Bits" ; lsr.b #1,d1 ; Shift bytewide right ; NOTE: Last Bit shifted out sets CCR Carry and eXtend Flags ; bcs ODD ; Branch Carry Set ; move.w #0,(a0)+ ; Bit Plane = 0 & Incr. A3 ; bra NEXT ;ODD: move.w #1,(a0)+ ; Bit Plane = 1 & Incr. A3 ; *** Hugh's version: clr.w (a0) lsr.w #1,d1 roxl.w (a0)+ ; Store remainder in Bit Plane & incr. ; NEXT: dbra d2,DISTLP ; End of Loop ; unlk a6 rts .data The above version has been tested and works. I've changed all the functions I've written to conform to the assumptions that the lower number registers are scratchpad and can be used in this way. Unless I find out otherwise, this will be the style I'll be using in the future. One difference from Hugh's version was my NOT using D0. Since D0 is used for return values, I tend to leave it till I need it. This can be helpful when writing long, complex functions. That is to say, sometimes it affects optimizing if you plan your register usage backwards. In this case it's fairly clear that it won't matter, but I've had it strongly ingrained, so I've not used D0. No real reason not to. :-) -- Jim Omura, 2A King George's Drive, Toronto, (416) 652-3880 lsuc!jimomura Byte Information eXchange: jimomura