Path: utzoo!attcan!uunet!lll-winken!ames!uhccux!munnari.oz.au!uqcspe!bunyip!lance!grue From: grue@lance.hss.bu.oz (Frobozz) Newsgroups: comp.sys.mac.programmer Subject: Re: Can anyone anser these Questions? Message-ID: <2138@lance.hss.bu.oz> Date: 25 Aug 89 01:30:32 GMT References: <864@eutrc3.urc.tue.nl> Reply-To: grue@lance.hss.bu.oz (Frobozz) Organization: Language Centre, Bond University, Australia. Lines: 136 In article <864@eutrc3.urc.tue.nl> rcbaem@eutrc3.uucp writes: > I have a very nice calculator, called a PC-2 (Radio Shack) known as a >PC-1500 (Sharp) as well (it's originally a Sharp machine). Since the only so do I its a HP-28 :-) >calculator resembling an existing one, on the Mac, I know of is a DA >version of HP's HP12, I desided to write my own one. > The program is finished (took one evening :) except for one (essential) thing: >I have to write an interpreter for the PC-2's machine code. The PC-2 is >both BASIC and Machine-code programmable, so I'll HAVE to write an >interpreter implementing the PC-2's microprocessor. > >The problems: > >1: The interpreter is probably going to be very slow. It may actually be faster than the original calculator (the PC-1500 wasn't exactly the fastest machine in the world). >2: The PC-2 can access 64K bytes of memory. Therefore I allocated a 64K > locked object, with a pointer to it. Let's call this pointer memStart. > > Then I got a terrible fight with Pascal... > > The PC-2's processor has 16bit registers. So I have to access bytes > in the 64K memory block. An instruction like LDA (P) could > be implemented as follows (in pascal): (A is a Byte, P is an integer > resembling a register of the PC-2's processor) > > A := Ptr(LongInt(memStart) + P)^; > > PROBLEM!! Assume P has the (integer) value -1. (=$FFFF) and say > memStart = 0; (LongInt(memStart) + P) then gives -1 instead of $FFFF.. > Whatever typecasting I tried, I end up with $FFFF beging extended > to the LongInt $FFFFFFFF... I finally found a solution as follows: > > type register = record case boolean of > true: (h:integer; > l:integer); > false:(hl:LongInt) > end; > > var P:register; > > When at initialisation time P.hl is set to 0 the following DOES work > as expected: > P.hl := 0; > > p.l := 0; > p.l := p.l - 1; (p.l is now $FFFF (or -1)) > > A := Ptr(LongInt(memStart) + p.hl)^; > > (When memStart had the value 0, then this addition would indeed give > the wanted address $FFFF). You have managed to simulate unsigned long integers :-) > >Some suggestions of mine are: > >1: a) Don't try to write this program, it's bound to be slow. It can be made reasonable, there exist emulators for 8088/6502/z80 already for the mac and although they are slow they are not impossibly slow. ( I started on a 0.8MHz 8080A machine :-) > b) Write it in assembly instead of in Pascal. (But LSP's code is > rather efficient, I found extremely nice trics wandering through > disassembled LSP compiled programs..) Assembly would be faster and for a production program trying to get maximal speed it might be advisable, but for personal usage only it would not be necessary. > c) Claim the program runs on 68030 Macs only :) nice idea! > >2: Pascal is a terribly rotten language thanks to it's excellent type > restrictions. Write it in Assembly or in C.. The problem mentioned above doesn't occur in C [ just make everything unsigned ] and in assembler anything goes. But, the lack of type-checking and array-bounds checking has caused me major problems [ that why I'm currently using Simula ] but often it does save pulling some interesting tricks. > >Okay, but I don't have an Assembler, nor a C compiler.. > >Any ideas? enter hex via a debugger (real programmers use octal, but hex is so much cleaner). my real suggestions: 1) Define a function that does the required conversion ( runs very slow ) 2) try and trick the compilier into generating inline code for the operation declare the following: FUNCTION Convert(x: Integer): LongInt; INLINE $7000,$301F,$2E80; which defines the following assembly: moveq #0, d0 move.w (sp)+, d0 move.l d0, (sp) which I hope will perform the necessary conversion without the overhead of making a function call. It is not as efficient as doing it in assembly code directly since the argument is push onto the stack and the result has to be poped off again, but the overhead is a lot less than a function call. I am not sure that the above assembly is correct since I haven't actually run the code, but I think it is ok. Also the inlined op-codes could be incorrect since I hand assembled the stuff (actually I first produced the hex & then had to dis-assemble it by hand :-) Also, my pascal could be wrong [ I personally HATE the language ]. The technique using the variant record is probably more efficient than what I suggest above ( especially if the record is declared globally and the hi-word is set to zero during program initialization. 3) Use the PC-1500 ;-} I hope this has been of some use to you. Pauli seeya SNIF --