Newsgroups: comp.sys.apple2,comp.sys.apple2.programmer Followup-To: comp.sys.apple2.programmer Subject: Re: Hires calculations From: dempson@actrix.gen.nz (David Empson) Date: Mon, 3 May 1999 23:08:11 +1200 Message-ID: <1dr91kz.1b3krhd1dkdbuoN@dempson.actrix.gen.nz> References: <7gigif$gtu$1@nnrp1.dejanews.com> Organization: Empsoft X-Newsreader: MacSOUP 2.3 NNTP-Posting-Host: 202.49.157.176 X-Trace: 3 May 1999 23:06:21 NZST, 202.49.157.176 Lines: 98 Path: news1.icaen!news.uiowa.edu!NewsNG.Chicago.Qual.Net!137.192.241.248!newshub.nntp.mr.net!coop.net!denver-news-feed1.bbnplanet.com!su-news-hub1.bbnplanet.com!lsanca1-snf1!news.gtei.net!news.netgate.net.nz!news.xtra.co.nz!news.iprolink.co.nz!news.actrix.gen.nz!dempson Xref: news1.icaen comp.sys.apple2:147433 comp.sys.apple2.programmer:10549 [Note crosspost and followups to comp.sys.apple2.programmer] wrote: > How do I calculate the MEMORY LOCATION of a byte on the LEFT SIDE of the > Hires screen, given the Y location? With a rather complex calculation. I wrote one as part of a hi-res graphics drawing program I wrote back in high school. There is probably a CALL you could make into Applesoft BASIC to access the internal routine, but here is the brute force and ignorance method. The hi-res screen is divided into three bands, each of which has eight sub-bands, each of which is eight lines. The memory addresses start at 8192 ($2000), advance across the line, then jump down to the middle third ($2028), advance across the line, then jump down the bottom third ($2050), advance across the line, then run off the screen for eight bytes ($2078 to $207F). The next 128 bytes start eight lines below the first 128. This pattern repeats eight times. You are now $0400 bytes after the start of the screen, and the entire pattern repeates one line below the previous pass. Repeat the whole thing eight times and you reach the end of the screen. In total, there are 192 lines. If you write out the line number in binary, you can divide it into three fields: Bits 7 and 6 select between thirds of the screen (a value of 3 is illegal). Bits 5, 4 and 3 select between blocks of eight lines. Bits 2, 1 and 0 select between individual lines. Call these fields C, B and A. The formula for the start address of a designated line, relative to the base address of the screen, is: C * 40 + B * 128 + A * 1024 The tricky part is breaking the line number up into the three fields. It is very easy in machine code, using shift and AND operations, but BASIC can't do this efficiently. The following code would work: 1000 REM Convert line number in Y into address in ADDR 1010 C = INT(Y / 64): TMP = Y - C * 64 1020 B = INT(TMP / 8): A = TMP - B * 8 1030 ADDR = C * 40 + B * 128 + A * 1024 + 8192 1040 RETURN The assembly language version would go something like this (off the cuff, and reasonably well optimised hence suitably cryptic, but untested): HBASCALC: * * Input: * A register contains line number * Zero page location HADDR contain high byte of start address of screen * * Output: * Zero page locations HBASL and HBASH contain address of line. tax ; Save line in X register and #$C0 ; Extract bits 7 and 6 sta HBASL ; Save top bits multiplied by 64 lsr lsr ora HBASL ; Now have (bits 7-6 shift right 6) * 80 sta HBASL txa ; Get the line back and #$38 ; Extract bits 5, 4 and 3 lsr lsr lsr lsr sta HBASH ; Store (bits 5-4 shift right 4) * 128 ror HBASL ; Fix low byte, include bit 7 txa ; Get the line back again and #$07 ; Extract bits 2, 1 and 0 asl asl ; Now have (bits 2-0) * 1024 ora HADDR ; Set appropriate high order bits ($20 or $40) ora HBASH ; and appropriate low order bits sta HBASH ; Done! rts -- David Empson dempson@actrix.gen.nz Snail mail: P.O. Box 27-103, Wellington, New Zealand