Mercurial > hg > Members > kono > nitros9-code
changeset 1416:f48bed2bdf44
Successful back-port to 6809 from NitrOS-9/6309 by Robert Gault
author | boisy |
---|---|
date | Sun, 30 Nov 2003 22:00:40 +0000 |
parents | 76137b27060d |
children | b7b173926ea1 |
files | level2/cmds/grfdrv.asm |
diffstat | 1 files changed, 6834 insertions(+), 3752 deletions(-) [+] |
line wrap: on
line diff
--- a/level2/cmds/grfdrv.asm Sun Nov 30 21:59:59 2003 +0000 +++ b/level2/cmds/grfdrv.asm Sun Nov 30 22:00:40 2003 +0000 @@ -1,960 +1,1943 @@ +******************************************************************** +* GrfDrv - NitrOS-9 Windowing Driver +* +* $Id$ +* +* Copyright (c) 1982 Microware Corporation +* Modified for 6309 Native mode by Bill Nobel - Gale Force Enterprises +* Also contains Kevin Darlings FstGrf patches & 1 meg routines +* +* Ed. Comments Who YY/MM/DD +* ------------------------------------------------------------------ +** 08/11/92 - Active in Native mode No apparent bugs +** Additional bugfixes/optomizations by Bill Nobel & L. Curtis Boyle +** 09/01/92 - present +** NitrOS9 V1.10 +** 05/26/93 - 3 cycle speedup in hardware text alpha put @ L0F6B +** NitrOS9 V1.11 +** 07/14/93 - Eliminated useless LDB 8,Y @ L01B5 +** 07/14/93 - Eliminated BMI's from L01D2; replace BGT's with BHI's +** 07/15/93 - Save 1 cycle/byte in Composite conversion in Select routine +** - Changed some pixel calcs in L06xx to use LSLD instead of +** MUL's by 8 (longer, but ends up being 12 cycles faster) +** - Moved L017C routine to be near Gfx cursor updates (1 cycle +** faster their and for Points with Pset buffers as well) +** - Moved L0118 routine near Alpha Put area to speed text output +** by 4 cycles (whether error or not) +** - Modified routine @ L0F04 to save up to 2 cycles per line +** of PutBlk +** - Modified L0E2F & L0F20 routines to speed up checks for +** stopping non-TFM PutBlk's +** - Changed LEAX B,X to ABX in FFill @ L1C5F +** Also change LEAS -2,s / PSHS D to PSHS X,D @ L1DCB (FFill) +** 07/16/93 - Changed L012B routine to LDX first, then PSHS, eliminating +** the need for the STX 2,S (saves 2 bytes/6 cycles) +** - Got rid of LEAY/PSHS Y/PULS Y in L012B since 8 bit addressing +** is same speed as 5 +** 07/20/93 - Modified Alpha Put to have a shortcut if writing to the +** same window as GRFDRV wrote to the last time it was run +** - Moved L1F08 & L1F18 routines closer to LINE to allow BSR's +** - Removed redundant BRA L0FF8 in 2 color gfx text put routine +** - Replaced 2 BRA L102D's with PULS A,PC (same size but saves +** 3 cycles) +** - Replaced BRA L0A38 in L0A1C routine with PULS PC,Y,A +** - Replaced BRA L0AA6 in L0A75 routine with PULS PC,Y,X,B +** - Replaced BRA L0BE1 in L0BA2 routine with CLRB / LBRA L0118 +** - Replaced BRA L1ADD's in L1A9D routines with PULS PC,X,D's +** (In Ellipse/Circle/Arc routines) +** 07/28/93 - Modified L11CA routine to eliminate 1 LBRA (saves 4 cycles) +** - Modified pixel XOR routine to save 3 cycles (used by Gfx +** Cursor) +** - Changed CMPW to CMPF when checking gfx coords @ L1E86 +** 08/06/93 - Changed BSR Lxxxx / RTS to BRA Lxxxx in following locations: +** L13AD (2), Just before L0516, L0798, Just before L1A97, L1D3C +** NitrOS9 V1.16 +** 08/30/93 - Took out DECD/DECB @ L0D27 (GPBuf wrap checks), changed BHI's +** to BHS's +** 08/30/93 - L0E14 replaced LDA / ANDA with TIM +** 08/31/93 - L0B79 changed registers around for split or normal Move buffer +** to shrink & speed up copy slightly +** 09/01/93 - L0C96 - change BLE in overwrap GP Buffer to BLO ($4000 is in +** next block) +** 09/22/93 - Moved L1BE8 to eliminate BSR (only called once) +** - Moved L1BDD to L18B7 (only called once) +** - Optomized 1BC9 by 7 cycles (multiply 5 byte integer x2) +** 09/23/93 - Remarked out L1B4B (never called-for filled circle/ellipse?) +** - Moved L1B5D to L1BB4 (only called once) +** 09/27/93 - Moved L1BF3 to L1BCB (only called once) +** 09/28/93 - Sped up/shrunk RGB color copy in Select routine with LDQ +** - Sped up of 2 color text by 18 cycles/character (changed +** branch compare order @ L1051 +** - Sped up of normal gfx text @ L10ED, and shortened code @ +** L10FE/L1109 by moving PULS B, and optomized L1109 branch +** compare order (same as L1051) +** - Changed <$A9,u vector to use ,W instead (<>2 color txt on gfx +** (NOTE: Type 7 window (640x200x4) tests are over 8% faster) +** 10/04/93 - Shortened L0FD6 (changed BNE/BRA to a BEQ/fall through) so +** Proportional & 2 color fonts are faster +** - Moved L122F to before L121A (eliminate BRA for wrap to next +** line) +** - Did optomization @ L127E for non-full screen width screen +** scrolls (also called by Insert line & Delete line) +** - Took out redundant LDB <$60 @ L13E3 (clear to end of screen) +** - Attempted opt of L10A4 to eliminate EXG X,Y +** - Re-arranged L10FA (Gfx text, not 2 color/normal) so it is +** optomized for actual text, not the cursor +** 10/08/93 - Changed L1E2C to use LEAX B,U (since B always <$80) since +** same speed but shorter +** - Changed BHI L1DEB @ L1DCB to LBHI L1C93 (1 byte longer but +** 2 cycles shorter) +** - Changed L017C (map GP Buffer blocks, both in GRFDRV DAT & +** immediate) to use DP instead of <xxxx,u vars. +** - Changed L0E70 to not bother changing U because of L017C change +** - Modified Gfx screen map-in routine @ MMUOnly to use +** DP addressing instead of ,X (eliminates LEAX too), saving +** mem & 11 cycles per map +** - Also removed PSHSing X in above routine & calls to it since +** not needed anymore +** - Changed L01FB to use LDX #$1290 instead of LEAX >$190,u +** - Changed all [...],u to use DP or immediate mode whenever +** possible +** - Changed EXG X,Y @ L03FF to TFR X,Y (since X immediately +** destroyed) (part of DWEnd to check if last window on scrn) +** - Eliminated useless BRA PutIt2 @ L0C96 +** - Removed PSHS/PULS of U in L0C8F (L0E70 no longer destroys U) +** 10/19/93 - Change L1F18 to use LDB #1/ABX instead of LEAX 1,X (2 cycles +** faster) +** - Removed LDU #$1100 @ L0EB2 since change to L0E70 (GP buffer) +** 10/20/93 - BUG FIX: Changed CMPF <$1E,Y @ L1E86 to CMPW <$1D,Y (otherwise +** routines that use th 16 bit Y coord for calculations screwed +** up on values >255) - MAY WANT TO TO CHANGE LATER TO HAVE HARD +** CODED 0 BYTE AS MSB OF Y COORDS AND SWITCH ALL CALCS POSSIBLE +** TO 8 BIT (OR LEAVE 16 BIT FOR VERTICAL SCROLLABLE SCREEN +** OPTIONS) +** - Moved L1E86 to L1DF8 (eliminates BRA from most X,Y coord pairs) +** - Moved L1F1D/L1F2C/L1F42 (right direction FFill vectors) to +** within FFill (only called once, eliminates LBSR/RTS) +** - Moved L1CC2 to eliminate BRA (eats coords off of FFill stack?) +** - L1D1E subroutine removed, embedded in places where called +** - L1DAA: eliminated LDD <$47 & changed CMPD <$4B to CMPW <$4B +** - L1DCB: changed to use both D & W to save code space & time +** 10/21/93 - L1D14 subroutine removed, embedded in 2 places where called +** - Changed BHI L1D03 to LBHI L1C93 @ L1D55 & eliminated L1D03 +** label +** - Changed BRA L1C93 at end of L1CF8 to LBRA L1CF8 +** - Moved L1186 (CurXY) to before L1129 (CTRL codes) to allow +** 3 LBEQ's to change to BEQ's (Cursor left,right & up) - +** shrinks GRFDRV by 6 bytes +** - Modified L158B (update cursor) to not PSHS/PULS Y unless on +** Gfx screen (speeds text cursor updates by 9 cyc/1 byte) +** - Changed LBSR to BSR (L15BF) in PutGC (L1531) +** - Attempted to move L06A4-L1FB2 to just before Point (L1635) +** & changed leax >L1FA3,pc to LEAX <L1FA3,pc in L15FE (saves +** 2 cycles & 2 bytes) +** 10/25/93 - Changed GRFDRV entry point to use LDX instead of LEAX +** (2 cycles faster) +** - Changed all LEA* xxxx,pc to use LDX #GrfStrt+xxxx (2 cyc fstr) +** - Changed GRFDRV entry point to do LDX / JMP ,X (1 byte shorter & +** 2 cycles faster) +** 11/02/93 - Modified Init routine to be shorter & faster +** - Took old 2 line L18B3 routine, put the label in front of +** stx <$A1 just past L18BF +** 11/03/93 - Removed the last of [<$xx,u] labels, changed FFill to use +** JSR ,U instead of JSR [$<64,U] +** - Removed LDU 4,s from L0B2E, and remove PSHS/PULS U from +** L0ACD, L0B35, L0B38 +** - In L0B79 (Move Buffer command), optomized to not PSHS/PULS +** Y, use U instead for ptr (13 cyc faster/72 byte block, 5 bytes +** shorter) +** - Added LDU <$64 in L0E97, changed JSR [$>1164] in L0EE1 to +** JSR ,U (PutBlk on different screen types) +** 11/04/93 - Change all LBRA xxxx to JMP GrfStrt+xxxx (1 cycle faster) +** 11/10/93 - Added window table references from cc3global.defs +** - Added screen table references from cc3global.defs +** - Added graphics table references from cc3global.defs +** - Added graphics buffer references from cc3global.defs +** 11/12/93 - Removed code that has been moved to WindInt/GrfInt +** 12/15/93 - Changed TST Wt.BSW,y @ L0F8E to LDB Wt.BSW,y (cycle faster) +** 12/21/93 - Moved L1E9D to near next line routine to speed up some alpha +** writes. Also used U instead of Y in L1E9D (smaller & a cycle +** faster) +** 02/23/94 - Moved L0BE4 error routine earlier to allow short branch to it +** from L0B3F (GPLoad), also optomized for no-error (5 cycles +** faster, 2 bytes smaller) +** 02/24/94 - Changed lbcs L0BE7 @ L0B52 to BCS +** 04/14/94 - Changed CMPB >$FFAC to CMPB <$90 (saves 1 byte/cycle & poss- +** ibly fixes bug for >512K machines) in L012B & L0173 +** - Got rid of CLR >$1003 @ L0177, changed BSR L012B to BSR L0129 +** - Changed CMPD #$4000 to CMPA #$40 @ L0B79 & L0C96 (also fixed +** bug @ L0B79-changed BLS MoveIt to BLO MoveIt) +** 04/15/94 - Changed L0E14 & L0E24 to use 640/320 base to eliminate INCD, +** also optomized by using LSRD instead of 2 separate LDD's +** - Moved INCB from L0E2F to L0E03 to allow L0E24 to fall through +** faster (by also changing LDB #MaxLine to LDB #MaxLine+1) +** 04/21/94 - Change all occurences of >$1003 (last window GRFDRV accessed) +** to <$A9 (since now free) to speed up/shrink checks. +** - Attempted mod for hware text screens: faster if >1 window +** being written to at once +** 04/25/94 - Removed LDX #$FF90 from late in L08A4, changed STD 8,x to +** STD >$FF98 (Select routine-saves 4 cycles/2 bytes +** - Attempted mod @ L05C0: Changed 1st TST <$60 to LDE <$60, and +** 2nd to TSTE (also changed 3 LSLD's in Y coord to LSLB's) +** (CWArea routine) +** 04/26/94 - Changed L11E1 (Home cursor) to move CLRD/CLRW/STQ Wt.CurX,y +** to end (just before RTS) to allow removal of CLRD/CLRW @ +** L1377 (CLS) +** 04/27/94 - Changed GFX text routines (non-2 color) to use U as jump +** vector instead of W (has changes @ L0FEC,L10D9,L10FE,L15A5) +** - Changed pixel across counter from <$97 to E reg in Gfx text +** routine (changes @ L10D1,L10FE) +** 05/04/94 - Attempted to remove PSHS X/PULS X from L0C0B (used by GetBlk +** and Overlay window saves) +** Also changed LBSR L0CBD to BSR @ L0BEA (part of OWSet save) +** 05/05/94 - Changed L0B79: Took out TFR A,B, changed CLRA to CLRE, changed +** TFR D,W to TFR W,D (reflects change in WindInt) +** 05/08/94 - Eliminated LDB #$FF @ L108C, change BNE above it to go to +** L108E instead (saves 2 cyc/bytes in proportional fonts) +** - Change to L127E to move LDF to just before BRA (saves 3 cyc +** on partial width screen scrolls) +** - Changed TST <$60 @ L1260 to LDB <$60 (saves 1 cycle) +** 06/15/94 - Changed TST >$1038 @ L0080 to LDB >$1038 (saves 1 cycle) +** - Changed TST St.Sty,x @ L0335 to LDB St.Sty,x (save 1 cyc) +** - Eliminated LDA St.Sty,x @ L0343 +** - Changed TST <$59 to LDB <$59 @ L046A (OWSet) +** - Changed TST Wt.FBlk,y @ L0662 to LDB Wt.FBlk,y (Font) +** NitrOS9 V1.21 Changes +** 10/16/94 - Changed L0FBE to BSR L100F instead of L1002, added L100F (PSHS +** A), saves 5 cycles per alpha put onto graphics screen +** 10/22/94 - Eliminated useles LDB <$60 @ L029B +** - Eliminated PSHS X/PULS X @ L0366 by changing PSET/LSET vector +** settings to use Q since immediate mode instead of indexed now +** (saves 6 bytes/>12 cycles in Window Inits) +** - Changed L106D: changed LDX/STX to use D, eliminated LDX ,S +** (Part of font on multi-colored windows;saves 2 bytes/4 cyc) +** 10/30/94 - Changed L126B (full width screen scroll) by taking out label, +** (as well as L1260), and taking out PSHS/PULS X +** - Changed TST <$60 to LDB <$60 @ L12C5, changed BRA L128E @ +** L12DC to BRA L1354 (Saves 3 cycles when using Delete Line on +** bottom line of window) +** - Moved CLRE in L142A to just before L142A (saves 2 cycles per +** run through loop) (same thing with CLRE @ L1450) +** - Deleted L146F, moved label for it to PULS pc,a @ ClsFGfx +** ATD: +** 12/23/95 - have SCF put text-only data at $0180, and have new call +** to grfdrv to do a block PUT of the text data. +** Added new L0F4B, and labels L0F4B.1 and L0F4B.2 +** cuts by 40% the time required for alpha screen writes! +** 12/26/95 - moved Line/Bar/Box common code to i.line routine +** +6C:-40B, only called once per entry, so it's OK +** 12/28/95 - added LBSR L0177 just before font set up routine at L1002 +** changed lbsr L0177, lbsr L1002 to lbsr L0FFF: gets +0C:-3B +** par call from L1478, L116E, L1186, L1129 +** - replaced 3 lines of code at L1641, i.line, L1C4F with +** lbsr L1884: map in window and verify it's graphics +** it's only called once per iteration, so we get 3 of +11C:-6B +** 02/08/96 - added fast fonts on byte boundaries to L102F +** - added TFM for horizontal line if LSET=0 and no PSET +** - removed most of graphics screen CLS code for non-byte +** boundary windows. They don't exist, the code is unnecessary. +** - changed many ADDR D,r to LEAr D,r where speed was unimportant +** 02/13/96 - fixed font.2 routine to properly handle changes in foreground +** and background colors: ~13 bytes smaller. (other changes???) +** - added special code to fast horizontal line routine at L16E0 +** to do the line byte by byte: saves a few cycles, but 2B larger +** 02/14/96 - added 'ldu <$64' U=pset vector to i.line, bar/box. -6 bytes, +** and timed at -18 clock cycles/byte for XOR to full-screen +** or 14/50 = 0.28 second faster per screen (iteration) +** 02/16/96 - shrunk code for $1F handler. Smaller and faster. +** 02/18/96 - Discovered that NitrOS-9 will allow GetBlk and PutBlk on +** text screens! Checked: GET on text and PUT on gfx crashes +** the system, ditto for other way around. Stock OS-9 does NOT +** allow PutBlk or GetBlk on text! No error, but no work, either. +** - Added code to PutBlk to output E$IWTyp if mixing txt and gfx +** GetBlk/PutBlk, but we now allow Get and put on text screens. +** 02/20/96 - minor mods to update video hardware at L08A4: use U +** - Added 'L1B63 LDD #1' to replace multiple LDD #1/lbsr L1B64 +** - moved code around to optimize for size in arc/ellipse/circle +** without affecting speed at all. +** 02/24/96 - added special purpose code for LSET AND, OR, XOR and NO PSET +** to put pixels 2 bytes at a time... full-screen BAR goes from +** 1.4 to .35 seconds, adds ~75 bytes. +** - Added code to check for 24/25 line windows in video set code +** from DWSET: Wt.DfSZY=24 uses old 192 line video defs +** 02/25/96 - removed 24/25-line check code, optimized video hardware update +** 02/26/96 - fixed fast TFM and XOR (double byte) horizontal line to +** update <$47 properly +** - rearranged BOX routine to cut out extra X,Y updates +** 02/29/96 - optimized BOX routine: smaller and marginally faster +** 03/05/96 - moved PSET setup routines to L1884 for Point, Line, Bar, Box +** Arc, Circle, Ellipse, and FFill. +** - modified FFILL to do left/right checking, and right painting +** to do byte operations, if possible. Speeds up FFILL by >20% +** 03/07/96 - modified FFILL to search (not paint) to the right, and to +** call the fast horizontal line routine. 2-color screen FFILLs +** take 1/10 the time of v1.22k: 16-color takes 1/2 of the time! +** 03/17/96 - added TFM and left/right pixel fixes so non-PSET/LSET odd +** pixel boundary PutBlks can go full-speed. +** 03/18/96 - optimized the fast-font routine. 16-color screens ~5% faster +** 04/05/96 - addeed special-purpose hardware text screen alpha put routine +** about 30% faster than before: 5 times over stock 'Xmas GrfDrv' +** - merged cursor On/Off routines at L157A: smaller, ~10c slower +** - saved 1 byte in invert attribute color routine +** - moved FastHTxt routine (i.e. deleted it: smaller, 3C slower) +** - L0516 and L0581: added 'xy.intoq' routine to set up X,Y size +** for text/graphics screens +** V2.00a changs (LCB) +** 05/25/97-05/26/97 - added code to support 224 char fonts on graphics +** screens +** - Changed 3 LBSR's to BSR's (@ L01B5,L1BB4,L1D40) +** 12/02/97 - Attempted to fix GetBlk, PutBlk & GPLoad to handle full width +** lines @ L0BAE (GetBlk), L0CBB (PutBlk), +** NOTE: TO SAVE SPACE GRFDRV, MAYBE HAVE WINDINT DO THE INITIAL +** DEC ADJUSTMENTS, AND JUST DO THE INC'S IN GRFDRV +** 07/10/98 - Fixed OWSet/CWArea bug: changed DECB to DECD @ L05C0 +** 07/21/98 - Fixed screen wrap on CWAREA or Overlay window on hardware text +** screens by adding check @ ftxt.ext +** 07/28/98 - Fixed FFill "infinite loop" bug (See SnakeByte game), I think. +** 07/30/98 - Filled Circle/Ellipse added ($1b53 & $1b54) +** 09/17/03 - Added trap for windows overlapping 512K bank; RG. +** Required changing a bsr L0306 to lbsr L0306 near L02A7 +** 09/25/03 - Many changes for 6809 only code. Use <$B5 to store regW +** Probably could use some trimming. RG +***************************************************************************** +* NOTE: The 'WHITE SCREEN' BUG MAY BE (IF WE'RE LUCKY) ALLEVIATED BY CLR'ING +* OFFSET 1E IN THE STATIC MEM FOR THE WINDOW, FORCING THE WINDOWING DRIVERS +* TO RESTART RIGHT FROM THE DEVICE DESCRIPTOR, INSTEAD OF ASSUMING THE DATA IN +* STATIC MEM TO BE CORRECT?? + nam GrfDrv - ttl OS9 System Module - -* Disassembled 03/09/13 23:38:06 by Disasm v1.6 (C) 1988 by RML -* Disassembly by R.Gault with tables from SF project for nlevel2 -* Patched rountine for >512K RAM just before L0762 9/15/03 RG - + ttl NitrOS-9 Windowing Driver ifp1 use defsfile endc -tylg set Systm+Objct + +GrfStrt equ $4000 Position of GRFDRV in it's own task + +tylg set Systm+Objct atrv set ReEnt+rev rev set $01 - mod eom,name,tylg,atrv,start,size -u0000 rmb 0 +edition equ 14 + +* NOTE: Following set has meaning only if 25 text line mode is selected +TV set $00 Set to 1 for 25 line TV res. (200 vs. 225) + + mod eom,name,tylg,atrv,entry,size size equ . + fcb $07 -name equ * - fcs /GrfDrv/ - fcb $12 -start equ * - ldx #$40F4 - pshs x,b,a - tfr u,d - tfr a,dp - leax <L002b,pcr - ldb $01,s - ldd b,x - leax d,x - puls b,a - jmp ,x -L002b fdb L008B-L002b * fcb $00,$60 - fdb L00E4-L002b *$00,$b9 - fdb L016E-L002b *$01,$43 - fdb L035C-L002b *$03,$31 - fdb L0360-L002b *$03,$35 - fdb L03FA-L002b *$03,$cf - fdb L04B0-L002b *$04,$85 - fdb L04DD-L002b *$04,$b2 - fdb L06F9-L002b *$06,$ce - fdb L0579-L002b *$05,$4e - fdb L0654-L002b *$06,$29 - fdb L062F-L002b *$06,$04 - fdb L05A0-L002b *$05,$75 - fdb L05E8-L002b *$05,$bd - fdb L063E-L002b *$06,$13 - fdb L05FF-L002b *$05,$d4 - fdb L065C-L002b *$06,$31 - fdb L067E-L002b *$06,$53 - fdb L0622-L002b *$05,$f7 - fdb L06EC-L002b *$06,$c1 - fdb L06F1-L002b *$06,$c6 - fdb L06F5-L002b *$06,$ca - fdb L0801-L002b *$07,$d6 - fdb L094A-L002b *$09,$1f - fdb L0A40-L002b *$0a,$15 - fdb L0A78-L002b *$0a,$4d - fdb L0AAA-L002b *$0a,$7f - fdb L0BC6-L002b *$0b,$9b - fdb L0E25-L002b *$0d,$fa - fdb L0E66-L002b *$0e,$3b - fdb L1055-L002b *$10,$2a - fdb L105C-L002b *$10,$31 - fdb L138C-L002b *$13,$61 - fdb L1068-L002b *$10,$3d - fdb L140A-L002b *$13,$df - fdb L13F1-L002b *$13,$c6 - fdb L156F-L002b *$15,$44 - fdb L157B-L002b *$15,$50 - fdb L169F-L002b *$16,$74 - fdb L17A4-L002b *$17,$79 - fdb L17EC-L002b *$17,$c1 - fdb L185C-L002b *$18,$31 - fdb L17FB-L002b *$17,$d0 - fdb L1C1C-L002b *$1b,$f1 - fdb L16A5-L002b *$16,$7a - fdb L17E7-L002b *$17,$bc - fdb L1857-L002b *$18,$2c - fdb L1536-L002b *$15,$0b -L008B tst <$38 - bmi L00E2 - lda #$FF - sta <$0038 - leax >$0180,u - ldb #$FF - ldy #$0020 -L009D std ,x -L009F leax <$40,x - leay -$01,y - bne L009D - leay <$10,y -L00A9 clr $01,x - leax <$20,x - leay -$01,y - bne L00A9 - leax <$18,x - stx <$003B - clra - clrb - std <$0030 - std <$002E - stb <$0032 - stb <$0035 - std <$0039 - std <$003D - std <$003F - incb - std <$00B3 - ldb #$20 - std <$00B5 - exg a,b - std <$00B7 - lda #$7E - ldx #$414F - sta <$00B9 - stx <$00BA - ldx #$4154 - sta <$00BC - stx <$00BD -L00E2 clrb - rts -L00E4 clr <$0038 - clr <$007D - ldb <$0032 - beq L00F3 - ldx <$0033 - lbsr L0963 - bcc L00E4 -L00F3 rts -L00F4 pshs cc - orcc #$50 - ldx >$1007 - clr >$1002 - clra + +name fcs /GrfDrv/ + fcb edition + +****************************** +* Main entry point +* Entry: B=Internal function code (from GRFINT or WINDINT) +* A=Character (for Write routine) +* U=Pointer to GRFDRV memory area ($1100 in system) +* Y=Current window Window Table Pointer +* Stack area is from $1b80 to $1fff in block 0 +* When function call vector is executed via JMP ,X +* DP has been set to $11 to allow direct page access to GRFDRV variables + + +entry equ * + IFNE H6309 + lde #$11 Direct page for GrfDrv + tfr e,dp + ELSE + pshs a + lda #$11 tfr a,dp puls a - jmp [>$00A9] -L0107 pshs y,x,b,a - ldx -$10,y - stx $02,s -L010D leay $0F,y - ldd $07,y - std <$0064 - ldd $05,y - std <$0068 - ldd -$09,y - std <$0061 - ldd $0C,y - std <$006A - ldd $0E,y - std <$006C - ldb ,x - andb #$8F - stb <$0060 - ldb $04,x - stb <$0063 - ldb $01,x -L012F leax >$008F,u - ldy #$FFAC - clra -L0138 std ,x++ - stb ,y+ - incb - cmpy #$FFAF - bls L0138 - puls pc,y,x,b,a -L0145 pshs y,x,b,a - bra L012F -L0149 pshs y,x,b,a - ldx -$10,y - bra L010D - bsr L0107 - lbra L13FB - clr <$0089 - stb <$008A - stb >$FFA9 - rts -L015C pshs a - os9 F$AllRAM - puls pc,a -L0163 pshs a - os9 F$AlHRAM - puls pc,a -L016A os9 F$DelRAM - rts -L016E bsr L0198 - bcs L0197 - lda <$0060 - cmpa #$FF - bne L0182 - lda [<-$10,y] - sta <$0060 - lbsr L13FB - bra L0187 -L0182 lbsr L01D5 - bcs L0197 -L0187 lbsr L0107 - lbsr L02EE - lda #$FF - sta -$0E,y - ldb $08,y - lbsr L129C - clrb -L0197 rts -L0198 lda <$0060 - cmpa #$FF - bne L01A1 - lda [<-$10,y] -L01A1 leax <L01CF,pcr - anda #$01 - ldb -$0B,y - cmpb a,x - bhi L01CB - addb -$09,y - cmpb a,x - bhi L01CB - lda [<-$10,y] - anda #$30 - ldb #$10 - mul - ldb -$0A,y - leax <L01D1,pcr - cmpb a,x - bhi L01CB - addb -$08,y - cmpb a,x - bhi L01CB - clrb - rts -L01CB comb - ldb #$BD + ENDC + tstb initialization? + bne grfdrv.1 no, do other stuff + bra L0080 do relative jump to the init routine + +grfdrv.1 ldx #GrfStrt+L0028 Point to function vector table + jmp [b,x] Execute function + +* GrfDrv function code vector table +L0028 fdb L0080+GrfStrt Initialization ($00) + fdb L0104+GrfStrt Terminate ($02) + fdb L019D+GrfStrt DWSet ($04) + fdb fast.chr+GrfStrt buffered writes... ($06) + fdb L03CB+GrfStrt DWEnd ($08) + fdb L046A+GrfStrt OWSet ($0A) + fdb L053A+GrfStrt OWEnd ($0C) + fdb L056E+GrfStrt CWArea ($0E) + fdb L07D7+GrfStrt Select ($10) + fdb L0611+GrfStrt PSet ($12) + fdb $0000 Border ($14) NOW IN WINDINT + fdb $0000 Palette ($16) NOW IN WINDINT + fdb L063C+GrfStrt Font ($18) + fdb L068B+GrfStrt GCSet ($1A) + fdb $0000 DefColor ($1C) NOW IN WINDINT + fdb L06A4+GrfStrt LSet ($1E) + fdb L0707+GrfStrt FColor ($20) + fdb L0726+GrfStrt BColor ($22) + fdb $0000 TChrSW ($24) NOW IN WINDINT + fdb $0000 PropSW ($26) NOW IN WINDINT + fdb $0000 Scale ($28) NOW IN WINDINT + fdb $0000 Bold ($2A) NOW IN WINDINT + fdb L08DC+GrfStrt DefGB ($2C) + fdb L0A3A+GrfStrt KillBuf ($2E) + fdb L0B3F+GrfStrt GPLoad ($30) + fdb L0B79+GrfStrt Move buffer ($32) + fdb L0BAE+GrfStrt GetBlk ($34) + fdb L0CBB+GrfStrt PutBlk ($36) + fdb L0F31+GrfStrt Map GP buffer ($38) + fdb L0F4B+GrfStrt Alpha put ($3A) + fdb L1129+GrfStrt Control codes ($3C) + fdb L116E+GrfStrt Cursor on/off ($3E) + fdb L1478+GrfStrt $1f codes ($40) + fdb L1186+GrfStrt Goto X/Y ($42) + fdb L151B+GrfStrt PutGC ($44) + fdb L1500+GrfStrt Update Cursors ($46) + fdb L1635+GrfStrt Point ($48) + fdb L1654+GrfStrt Line ($4A) + fdb L1790+GrfStrt Box ($4C) + fdb L17FB+GrfStrt Bar ($4E) + fdb L1856+GrfStrt Circle ($50) + fdb L18BD+GrfStrt Ellipse ($52) + fdb L1860+GrfStrt Arc ($54) + fdb L1C4F+GrfStrt FFill ($56) + +* Initialization entry point +* Entry: U=$1100 +* DP=$11 +* B=$00 +L0080 ldb >WGlobal+g0038 have we been initialized? + bmi L0102 yes, exit + coma + sta >WGlobal+g0038 Put it back +* Initialize window entries + ldx #WinBase-$10 Point to start of window tbl entries + IFNE H6309 + ldq #$2040FFFF Max # window/size of each entry/Table init code +L0097 stw ,x Initialize table pointer + abx Move to next entry + deca Done? + bne L0097 No keep going + ELSE + pshs u + ldd #$2040 + ldu #$FFFF +L0097 stu ,x + abx + deca + bne L0097 + stu <$B5 + puls u + ENDC +* Initialize screen tables + ldx #STblBse+1 Point to 2nd byte of scrn tbls - 1st block # used + ldd #$1020 smaller than the ldb/lde +* ATD: doing CLR is slightly slower than STA, but this code is executed only +* once, so we optimize for size, not speed +L00A9 clr ,x Set first block # used (A=0 from L0097 loop) + abx Move to next entry + deca Done? + bne L00A9 No, keep goin +* Initialize DAT image + clrb Set System bank as first one (a already 0) + std <$87 + IFNE H6309 + ldq #$333E333E Get blank image + std <$89 Save it in rest +* NOTE: IF 16K GRFDRV DONE,CHANGE FOLLOWING LINE TO STD <$8F +* Set entire table as this will be reset below as needed. RG. + stq <$8D + stq <$91 + std <$95 + ELSE + ldd #$333E Since 6809 version is >8K save some steps + std <$89 + std <$8F + std <$91 + std <$93 + std <$95 +* std <$B5 + ENDC + tfr pc,d Get current location in memory + lsra Calculate DAT image offset + lsra + lsra + lsra + anda #$0E Mask off rest of bits + ldy >D.SysPrc Get system process descriptor pointer + leay <P$DATImg,y Point to DAT Image +* NOTE: IF 16K GRFDRV DONE,WILL HAVE TO COPY 4 (NOT 2) BYTES OF DAT IMAGE + IFNE H6309 + ldd a,y Get the DAT image of myself + std <$8B Save it to new task + ELSE + leay a,y + ldd ,y++ + std <$8B + ldd ,y get next two bytes + std <$8D + ENDC + ldy >D.TskIPt Get task image pointer + ldx #GrfMem+gr0087 Point to grfdrv DAT image tbl + stx 2,y Save it as second task +* ATD: changed from $1C98 for more lee-way on the stack + ldd #$1CB0 low address for stack: L1DC4, L1DEE + std <$3B Save in GRFDRV mem + IFNE H6309 + clrd Get screen table initialization + clrw (CLRQ) + stq <$2e Init current screen table ptr & window entry + stq <$3d Init X/Y coords Gfx cursor was last ON at + ELSE + clra + clrb + std <$2e + std <$30 + std <$3d + std <$3f +* std <$B5 + ENDC + stb <$32 Clear out block #'s for G/P buffer (Current, + stb <$35 previous) + std <$39 Text cursor & gfx cursors off +L0102 clra + tfr a,dp Set DP to 0 for Wind/GrfInt, which need it there + rts Return + +* Termination routine +L0104 clr <$0038 Clear group # + clr <$007D Clear buffer block # + ldb <$0032 Get last block used + beq L0115 If 0, return to system + ldx <$0033 Get offset into last block we used + lbsr L0A55 Deallocate that buffer + bcc L0104 Keep doing until all are deallocated + jmp >GrfStrt+L0118 Return to system with error if can't +L0115 jmp >GrfStrt+L0F78 Exit system + +* Setup GrfDrv memory with data from current window table +* Entry: Y=Window table ptr +* Puts in following: +* PSET/LSET vectors & offsets +* Foreground/background palettes +* Maximum X&Y coords for window +* Screen type +* Start block # of screen +* # bytes / row of text +* NOTE: USING A 2 BYTE FREE MEMORY LOCATION SOMEWHERE IN BLOCK 0, KEEP A +* 'LAST WINDOW' ACCESSED COPY OF THE WINDOW TABLE PTR. IF IT HAS NOT CHANGED +* WHEN IT GETS HERE (OR WHATEVER CALLS HERE) FROM THE 'LAST WINDOW' ACCESSED, +* SKIP THIS ENTIRE ROUTINE +L0129 clr <$A9 Special entry pt for DWSet,Select,UpdtWin,PutGC +L012B ldx Wt.STbl,y Get screen table ptr + pshs d Preserve register + ldd Wt.PVec,y Get PSet vector for this window + IFNE H6309 + ldw Wt.POff,y Get PSet offset for this window + stq <$64 Save Pset vector & PSet offset + ELSE + std <$64 + ldd Wt.POff,y + std <$66 + ENDC + ldd Wt.LVec,y Get LSet vector + std <$68 Save it for this window + ldd Wt.Fore,y Get Foreground/Background prn + std <$61 Save it for this window + IFNE H6309 + ldq Wt.MaxX,y Get max. X & Y coords from table + stq <$6A Save in Grfdrv mem + ELSE + ldd Wt.MaxX,y + std <$6A + ldd Wt.MaxX+2,y + std <$6C + std <$B5 + ENDC + lda St.BRow,x Get # bytes per row + sta <$63 Save it for this window + ldd St.Sty,x Get screen type & first block # + sta <$60 Save screen type for this window +* Setup Task 1 MMU for Window: B=Start block # of window +* As above, may check start block # to see if our 4 blocks are already +* mapped in (just check block # in B with block # in 1st DAT entry). +* Since 4 blocks are always mapped in, we know the rest is OK +* This routine always maps 4 blocks in even if it is only a text window +* which only has to map 1 block. Slight opt (2 cycles) done 03/01/93 +* Attempted opt: cmpb/beq noneed 03/12/93 +MMUOnly cmpb <$90 Is our screen block set already here? + beq noneed Yes, don't bother doing it again + clra Get block type for DAT image + std <$8f Save screen start in my image + stb >$FFAC Save 1st screen block to MMU + + tst <$60 Hardware text (only 1 block needed?) + bmi noneed yes, no need to map in the rest of the blocks + + incb Get 2nd block + std <$91 Save it in my image + stb >$FFAD Save it to MMU + incb Get 3rd block + std <$93 Save it to my image + stb >$FFAE Save it to MMU + incb Get 4th block + std <$95 Save it to my image + stb >$FFAF Save it to MMU +noneed puls d,pc Restore D & return + +* Setup the MMU only: called twice from the screen setup routines +* This could be just before MMUOnly, with a 'fcb $8C' just before the PSHS +* to save one more byte, but L0129 is called a lot more often than this is +L0173 pshs d save our registers + bra MMUOnly go set up the MMU registers, if necessary + +* Entry point for Alpha Put +L0175 cmpy <$A9 Same as previous window GRFDRV alpha putted to? + lbeq L150C Yes, skip map/setup, update cursors +* Normal entry point +L0177 bsr L0129 Mark Tbl Ptr bad, map in window,set up GRFDRV vars for it +L0179 jmp >GrfStrt+L150C Update text & gfx cursors if needed + +* DWSet routine +* ATD: Next 9 lines added to support multiple-height screens. +* We MUST have a screen table in order to do St.ScSiz checks (24, 25, 28). +* GrfDrv is a kernel task (not task switched), so we point X to the possible +* screen table +L019D ldx Wt.STbl,y get screen table + bpl L01A0 $FFFF is a flag saying it's unallocated + lbsr L0287 find a screen table + bcs L01C5 exit on error + clr St.ScSiz,x clear screen size flag: not defined yet + +L01A0 bsr L01C8 Check coordinates and size + bcs L01C5 Error, exit + lda <$60 Get screen type requested + cmpa #$FF Current screen? + bne L01B0 No, go create a new screen for the window + bsr L01FB Make sure window can be fit on current screen + bcs L01C5 Nope, return with error + lbsr L150C Update Text & Gfx cursors + bra L01B5 Do hardware setup for new window & return to system + +* Make window on new screen : have to change so it sets up defaults & colors +* BEFORE it clears the screen +L01B0 lbsr L0268 Go set up a new screen table (INCLUDES CLR SCRN) + bcs L01C5 If error, return to system with that error +* All window creates come here +L01B5 equ * + IFNE H6309 + bsr L0129 go setup data & MMU for new window + ELSE + lbsr L0129 + ENDC + lbsr L0366 setup default values + lda #$FF Change back window# link to indicate there is none + sta Wt.BLnk,y +* ATD: same next 3 lines as at L03F4 + lbsr L1377 Call CLS (CHR$(12)) routine + clrb No errors +L01C5 jmp >GrfStrt+L0118 return to system + +* Check screen coordinates +* Entry: X = screen table pointer +L01C8 lda <$60 get current window STY marker + cmpa #$FF current screen? + bne L01D2 no, go on + lda ,x Get current screen type (from screen table ptr) +L01D2 ldu #GrfStrt+L01F9 Point to width table + anda #$01 only keep resolution bit (0=40 column, 1=80) + ldb Wt.CPX,y get current X start +* cmpb a,u within range? +* bhi L01F5 no, exit with error + addb Wt.SZX,y calculate size + bcs L01F5 added line: exit if 8-bit overflow + cmpb a,u still within range? + bhi L01F5 no, error out + +* ATD: These lines added for screen size support + lda St.ScSiz,x get screen size + bne L01E0 skip ahead if already initialized + lda #25 get maximum screen size in A + +L01E0 ldb Wt.CPY,y get current Y start + IFNE H6309 + cmpr a,b within maximum? + ELSE + pshs a + cmpb ,s+ + ENDC + bhi L01F5 no, error out + addb Wt.SZY,y calculate size: Now B = maximum size of the window + bcs L01F5 added line: exit if 8-bit overflow + IFNE H6309 + cmpr a,b still within maximum? + ELSE + pshs a + cmpb ,s+ + ENDC + bhi L01F5 no, error out + + cmpa St.ScSiz,x do we have the current screen size? + beq L01F3 yes, skip ahead + + cmpb #24 do we have a 24-line screen? + bhi L01F1 no, it's 25: skip ahead + deca 25-1=24 line screen, if window <= 24 lines + +L01F1 sta St.ScSiz,x save the size of the screen +L01F3 clrb clear carry + rts return + +L01F5 comb Set carry + ldb #E$ICoord Get error code for Illegal co-ordinate + rts Return +* Maximum widths of text & graphic windows table +L01F9 fcb 40,80 + +* Check if Current screen DWSET request can be honored (carry set & b=error +* # if we can't) +* Entry: Y=Ptr to our (new window) window table +* NOTE: It has to check all active windows. If it it fits without overlap +* on all of them, then it will obviously fit with several on the same +* screen. +L01FB ldx #WinBase Point to start of window tables + IFNE H6309 + lde #MaxWind Get maximum number of windows (32) + ELSE + pshs a + lda #MaxWind + sta <$B5 + puls a + ENDC +L0206 equ * + IFNE H6309 + cmpr y,x Is this our own window table entry? + ELSE + pshs y + cmpx ,s++ + ENDC + beq L021B Yes, skip it (obviously) + ldd Wt.STbl,x Get screen table pointer of search window + bmi L021B High bit set means not active, skip to next + cmpd Wt.STbl,y Same screen as ours? + bne L021B No, skip to next + lda Wt.BLnk,x Is this entry for an overlay window? + bpl L021B Yes, useless to us + bsr L0224 Go make sure we will fit + bcs L0223 Nope, return with error +L021B ldb #Wt.Siz Move to next entry (originally leax $40,x, but + abx believe it or not, this is faster in native) + IFNE H6309 + dece Done? + ELSE + dec <$B5 + ENDC + bne L0206 No, go back + clrb Clear errors +L0223 rts Return + +* Routine to make sure a 'current screen' DWSet window will fit with other +* windows already on that screen +* Entry: X=Ptr to window table entry that is on same screen as us +* Y=Ptr to our window table entry +* Exit: Carry clear if it will fit + +L0224 equ * + IFNE H6309 + tim #Protect,Wt.BSW,x Is this window protected? + ELSE + pshs b + ldb Wt.BSW,x + bitb #Protect + puls b + ENDC + beq L0262 No, window can overlap/write wherever it wants + lda Wt.CPX,y get our new window's requested Left border + cmpa Wt.DfCPX,x Does it start on or past existing windows left border? + bge L023A Yes, could still work - check width + adda Wt.SZX,y add in our requested width + cmpa Wt.DfCPX,x Does our right border go past existing's left border? + bgt L0246 Yes, could still work if Y is somewhere empty(?) + clrb No X coord conflict at all...will be fine + rts +* Comes here only if our window will start past left side of existing window +L023A ldb Wt.DfCPX,x Get existing windows left border value + addb Wt.DfSZX,x Calculate existing window's right border + IFNE H6309 + cmpr b,a Our X start greater than existing windows right border? + ELSE + pshs b + cmpa ,s+ + ENDC + bge L0262 Yes, legal coordinate +* X is fine, start checking Y +L0246 lda Wt.CPY,y Get our new window's requested top border value + cmpa Wt.DfCPY,x Compare with existing window's top border +L024B bge L0256 If we are lower on screen, jump ahead + adda Wt.SZY,y Calculate our bottom border + cmpa Wt.DfCPY,x Is it past the top border of existing window? + bgt L0264 Yes, illegal coordinate + clrb Yes, window will fit legally, return with no error + rts + +* Comes here only if our window will start below top of existing window +L0256 ldb Wt.DfCPY,x Get existing window's top border value + addb Wt.DfSZY,x Calculate existing window's bottom border + IFNE H6309 + cmpr b,a Our Y start less than bottom of existing? + ELSE + pshs b + cmpa ,s+ + ENDC + blt L0264 Yes, would overlap, return error +L0262 clrb Yes, window will fit legally, return with no error rts -L01CF fcb 40,80 -L01D1 fcb $18,$19,$46,$46 -L01D5 bsr L01F4 - bcs L01F3 - stx -$10,y - ldb <$0060 - stb ,x - bsr L0208 - bcs L01F3 - ldb <$005A - stb $05,x - lbsr L06D2 - stb $06,x - lbsr L02A0 - lbsr L0640 -L01F2 clrb -L01F3 rts -L01F4 leax >$0980,u - ldb #$10 -L01FA tst $01,x - beq L01F2 - leax <$20,x - decb - bne L01FA - comb - ldb #$C1 - rts -L0208 pshs y - ldb <$0060 - bpl L0228 - leay >$0980,u - lda #$10 -L0214 tst ,y - bpl L0220 - ldb $01,y - beq L0220 - bsr L026F - bcc L0247 -L0220 leay <$20,y - deca - bne L0214 - ldb <$0060 -L0228 leay <L0262,pcr - andb #$0F - ldb b,y - lbsr L0163 - bcs L0258 - ldy #$8000 - pshs y,b - lbsr L0145 +L0264 comb Window won't fit with existing windows + ldb #E$IWDef +L0286 rts + +* Setup a new screen table +*L0268 bsr L0287 search for a screen table +* bcs L0286 not available, return +* X=Screen tbl ptr, Y=Window tbl ptr +L0268 stx Wt.STbl,y save the pointer in window table + ldb <$60 get screen type + stb St.Sty,x save it to screen table + bsr L029B go setup screen table (Block & addr #'s) + bcs L0286 couldn't do it, return + ldb <$5A get border color + stb St.Brdr,x save it in screen table +* This line added + ldb Wt.Back,y Get background color from window table + lbsr L0791 get color mask for bckgrnd color + lbsr L0335 clear the screen (with bckgrnd color) + leax St.Pals,x Point to palette regs in screen table + ldd >WGlobal+G.DefPal Get system default palette pointer + IFNE H6309 + ldw #16 16 palettes to copy + tfm d+,x+ Copy into screen table + ELSE + pshs b,y + tfr d,y + ldb #8 + stb ,s +L0287b ldd ,y++ + std ,x++ + dec ,s + bne L0287b + puls b,y + ENDC + clrb No error & return + rts Get back scrn tbl ptr & return + +* Search for a empty screen table +L0287 ldx #STblBse+1 Point to screen tables+1 + ldd #$10*256+St.Siz get # table entrys & entry size +L028D tst ,x already allocated a block? + bne Yes Yes, go to next one + leax -1,x Bump pointer back by $980 based + clrb No error & return + rts + +Yes abx move to next one + deca done? + bne L028D no, keep looking + comb set carry for error + ldb #E$TblFul get error code + rts return + +* Setup screen table +* Entry: Y=Window table ptr +* B=screen type (flags still set based on it too) +L029B pshs y preserve window table pointer + bpl L02BB Screen type not text, go on + ldy #STblBse Point to screen tables + lda #$10 get # screen tables +* Search screen tables +L02A7 ldb St.Sty,y is it text? + bpl L02B3 no, go to next one + ldb St.SBlk,y get memory block # + beq L02B3 don't exist, go to next one + lbsr L0306 search window block for a spot + bcc L02DE found one, go initialize it +L02B3 leay St.Siz,y move to next screen table + deca done? + bne L02A7 no, keep going + +* No screen available, get a new screen block +* NOTE: Should be able to change L02F1 loop to use W/CMPE to slightly +* speed up/shrink + ldb <$60 get STY marker +L02BB lda #$FF preset counter + sta <$B3 unused grfdrv space + ldy #GrfStrt+L02FA-1 Point to RAM block table + andb #$F make it fit table + ldb b,y get # blocks needed + stb <$B4 save number of blocks, unused space +OVLAP inc <$B3 update counter, unused space + ldb <$B4 get number of blocks needed + os9 F$AlHRAM AlHRAM Allocate memory *********** + bcs L02EF no memory, return error + pshs b save starting block # + andb #$3f modulo 512K + pshs b save modulo starting block + ldb <$B4 regB now # blocks requested + decb set to base 0 + addb ,s + andb #$3f final block # modulo 512K + cmpb ,s+ compare with first block + blo OVLAP overlapped 512K boundary so ask for more RAM + bsr DeMost + puls b get starting block # + lda <$B3 + leas a,s yank temps + ldy #$8000 get default screen start + pshs b,y save that & start block # + lbsr L0173 setup MMU with screen +* Mark first byte of every possible screen in block with $FF ldb #$FF -L023F stb ,y - bsr L025A - bcs L023F - puls y,b -L0247 stb $01,x - sty $02,x - lda <$0060 - anda #$0F - leay <L0268,pcr - lda a,y - sta $04,x - clrb -L0258 puls pc,y -L025A leay >$0800,y - cmpy #$A000 -L0262 rts -L0263 fcb $02,$02,$04,$04,$01 -L0268 fcb $01,$50,$50,$a0,$a0,$a0,$50 -L026F pshs y,x,b,a - lbsr L0145 - ldy #$8000 - ldb #$FF -L027A cmpb ,y - beq L0285 -L027E bsr L025A - bcs L027A -L0282 comb - puls pc,y,x,b,a -L0285 lda <$0060 - anda #$8F - cmpa #$86 - beq L029A - leax >$0800,y - cmpx #$A000 - bcc L0282 - cmpb ,x - bne L027E -L029A clrb - puls x,b,a - leas $02,s - rts -L02A0 pshs y,x - stb <$0097 - stb <$0098 - lda ,x - bpl L02AE - ldb #$20 - stb <$0097 -L02AE pshs x - ldd -$0B,y - bne L02C9 - ldb ,x - leax >L01CF,pcr - andb #$01 - abx - ldd -$09,y - cmpa ,x - bne L02C9 - cmpb #$18 - bne L02C9 - puls pc,y,x,b,a -L02C9 puls x - ldy $02,x +L02D6 stb ,y save marker + bsr L02F1 move to next one + blo L02D6 not done, keep going + puls b,y restore block # & start address +* Initialize rest of screen table +L02DE stb St.SBlk,x save block # to table + sty St.LStrt,x save logical screen start + lda <$0060 get screen type + anda #$F make it fit table + ldy #GrfStrt+L0300-1 Point to width table + lda a,y get width + sta St.BRow,x save it to screen table + clrb clear errors +L02EF puls y,pc return + +* Get rid of allocated blocks that overflowed 512K bank; RG. +DeMost tst <$B3 if none then return + beq DA020 + lda <$B3 + pshs a,x + leay 6,s a,x,rts,b; point to first bad group +DA010 clra + ldb ,y+ get starting block number + tfr d,x + ldb <$B4 number of blocks + os9 F$DelRAM de-allocate the blocks *** IGNORING ERRORS *** + dec ,s decrease count + bne DA010 + puls a,x +DA020 rts + +* Move to next text screen in memory block +L02F1 leay >$0800,y move Y to next text screen start + cmpy #$A000 set flags for completion check +L02F9 rts return + +* Memory block requirement table (# of 8K banks) +L02FA fcb 2 640 2 color + fcb 2 320 4 color + fcb 4 640 4 color + fcb 4 320 16 color + fcb 1 80 column text + fcb 1 40 column text + +* Screen width in bytes table (# bytes/line) +L0300 fcb 80 640 2 color + fcb 80 320 4 color + fcb 160 640 4 color + fcb 160 320 16 color + fcb 160 80 column + fcb 80 40 column text + +* Look for a empty window in a text screen memory block +L0306 pshs d,x,y Preserve regs + lbsr L0173 go map in the screen + ldy #$8000 get screen start address + ldb #$FF get used marker flag +L0311 cmpb ,y used? + beq L031C no, go see if it will fit +L0315 bsr L02F1 move to next screen + bcs L0311 keep looking if not outside of block +L0319 comb set carry + puls d,x,y,pc return + +L031C lda <$0060 get screen type + cmpa #$86 80 column text? + beq L032F yes, return + leax $0800,y move to next screen to check if it will fit + cmpx #$A000 will it fit in block? + bhs L0319 no, return error + cmpb ,x is it already used? + bne L0315 yes, return error +L032F clrb clear error status + puls d,x + leas 2,s dump screen table pointer to keep screen address + rts return + +* Clear screen (not window, but whole screen) +* Entry: B=Background color mask byte (from $6,x in window table) +* X=Ptr to screen table +* Currently comes in with foreground color though. +* ATD: only called once, from just above... +L0335 pshs x,y save regs + lda #C$SPAC get a space code + std <$0097 init screen clear value to $00 (or attribute) + ldb St.Sty,x is window text? +L0343 ldy St.LStrt,x get screen start + andb #$F make it fit table + lslb adjust for 2 bytes entry + ldx #GrfStrt+L035A-2 Point to screen length table + IFNE H6309 + ldw b,x get length + ELSE + pshs x + ldx b,x + stx <$B5 + puls x + ENDC + cmpb #$8 Text mode? + bls ClrGfx No, do Graphics screen clear +* Clear text screen + ldx <$0097 get screen clear codes ($2000) + IFNE H6309 + tfr w,d Move count to D + tfr y,w Move ptr to faster indexing register +L0352 stx ,w++ Store blank char on screen + decd Dec counter + bne L0352 + ELSE + ldd <$B5 +L0352 stx ,y++ + subd #1 + bne L0352 Do until done screen + sty <$B5 + ENDC + puls x,y,pc Get back regs & return + +* Screen length table +L035A fdb 80*MaxLines*8 640 2 color (gfx are 1 byte counts) + fdb 80*MaxLines*8 320 4 color + fdb 160*MaxLines*8 640 4 color + fdb 160*MaxLines*8 320 16 color + fdb 160*Maxlines/2 80 column text (txt are 2 byte counts) + fdb 80*MaxLines/2 40 column text + +* Clear a graphics screen +ClrGfx ldx #$1098 Point to clear code char. + IFNE H6309 + tfm x,y+ Clear screen + ELSE + pshs a lda ,x - anda #$0F - lsla - leax <L02E0,pcr - ldx a,x - ldd <$0097 -L02DA std ,y++ - leax -$01,x - bne L02DA -L02E0 puls pc,y,x -L02E2 fdb $1F40 - fdb $1F40 - fdb $3E80 - fdb $3E80 - fdb $07D0 - fdb $03E8 -L02EE pshs x - clra - sta <$18,y - sta $0A,y - sta $0E,y - ldx #$5F9A - stx <$14,y - ldx #$5F83 - stx <$16,y - lda #$89 - sta $09,y - bsr L0325 - stb <$0061 - bsr L032F - stb <$0062 - lbsr L06DC - puls x - ldd $02,x - bsr L0337 - clr $0B,y - ldd #$C801 + ldx <$B5 +ClrGfx2 sta ,y+ + leax -1,x + bne ClrGfx2 + stx <$B5 + puls a + ENDC + puls x,y,pc Restore regs & return + +* Part of window init routine +* Entry: Y=Window table ptr +* X=Screen table ptr +L0366 ldd #(TChr!Scale!Protect)*256 Transparency off & protect/Scale on + stb Wt.GBlk,y Graphics cursor memory block #0 + std Wt.BSW,y Character switch defaults & Lset type 0 + stb Wt.PBlk,y Pset block #0 + IFNE H6309 +* Assembler can't do $10000x# +* ldq #(GrfStrt+L1FA9)*65536+(GrfStrt+L1F9E) Normal LSET/PSET vector + fcb $cd + fdb GrfStrt+L1FA9,GrfStrt+L1F9E + stq Wt.LVec,y Save vectors + ELSE + ldd #GrfStrt+L1F9E + std Wt.LVec+2,y + std <$B5 + ldd #GrfStrt+L1FA9 + std Wt.LVec,y + ENDC + ldb Wt.Fore,y Get foreground palette # + lbsr L074C Get bit mask for this color + stb Wt.Fore,y Store new foreground bit mask + stb <$0061 Store new foreground bit mask in GRFDRV's global + ldb Wt.Back,y Get background palette # + lbsr L074C Get bit mask for this color + stb Wt.Back,y Store new background bit mask + stb <$0062 Store bckground bit mask in GRFDRV's global mem + lbsr L079B Set default attributes to new colors + ldd St.LStrt,x Get screen logical start + bsr L03A9 Go copy scrn address/X&Y start to defaults area + clr Wt.FBlk,y Font memory block to 0 (no font yet) +* get group & buffer for font + ldd #$C801 Default group/buffer number for font std <$0057 - lbsr L05A2 - clrb + lbsr L0643 Go set up for font + clrb No error and return rts -L0325 ldb $06,y - lbsr L0698 - stb $06,y - rts -L032D bsr L0325 -L032F ldb $07,y - lbsr L0698 - stb $07,y +* Move screen start address, X & Y coordinate starts of screen to 'default' +* areas. The first set is for what the window is currently at (CWArea +* changes, for example), and the second set is the maximums of the window +* when it was initialized, and thusly the maximums that can be used until +* it is DWEnd'ed and DWSet'ed again. +* Entry :x= Screen table ptr +* y= Window table ptr +* d= Screen logical start address +L03A9 lbsr L0581 Go set up window/character sizes + IFNE H6309 + ldq Wt.LStrt,y Get screen start addr. & X coord start + stq Wt.LStDf,y Save as 'window init' values + ELSE + ldd Wt.LStrt,y + std Wt.LStDf,y + ldd Wt.LStrt+2,y + std Wt.LStDf+2,y + std <$B5 + ENDC + ldd Wt.SZX,y Get Y coord start + std Wt.DfSZX,y Set default Y coord start rts -L0337 lbsr L04ED - ldd -$0D,y - std <$24,y - ldd -$0B,y - std <$26,y - clr -$0B,y - clr -$0A,y - ldd -$09,y - std <$28,y - rts -L034E tsta - beq L0355 - orb $09,y - bra L0358 -L0355 comb - andb $09,y -L0358 stb $09,y - bra L038E -L035C ldb #$01 - bra L034E -L0360 jsr <$00B9 - ldd #$FFFE - std -$10,y - bsr L0390 - bcs L0387 - bsr L03A8 - cmpy <$002E - bne L038E - clra - clrb - std <$002E - std <$0030 - ldx #$FFB0 - ldd #$1008 - stb >$FF9A -L0381 stb ,x+ - deca - bhi L0381 - rts -L0387 ldb $06,x - stb <$0062 - lbsr L129C -L038E clrb - rts -L0390 pshs y - leay >$0190,u - ldb #$20 -L0398 cmpx -$10,y - beq L03A5 - leay <$40,y - decb - bne L0398 - clrb - bra L03A6 -L03A5 comb -L03A6 puls pc,y -L03A8 pshs y - lda ,x - bpl L03D0 - ldy $02,x - ldb #$FF + +* DWEnd entry point : NOTE: the LDD #$FFFF was a LDD #$FFFE from Kevin +* Darling's 'christmas' patch. It is supposed to have something to do +* with INIZ'ed but not screen allocated windows. +L03CB lbsr L0177 Go map in window + ldd #$FFFF Set screen table ptr to indicate not active + std Wt.STbl,y +* This routine checks to see if we are the last window on the current screen +* Carry set if there is there is another window on our screen +* (Originally a subroutine...moved to save 2 bytes & 5 cycles +* Entry: Y=window table ptr +* X=Screen table ptr? +L03FF pshs y,x Preserve window table & screen table ptrs + tfr x,y Move for ABX + ldx #WinBase Point to window table entries + ldd #MaxWind*256+Wt.Siz Get # entries & size +L0407 cmpy Wt.STbl,x Keep looking until we find entry on our screen + beq L0414 Found one, error + abx Bump to next one + deca Keep doing until all 32 window entries are done + bne L0407 + clrb We were only window on screen, no error +*ATD: FCB $21: BRN = skip 1 byte +* bra L0415 + fcb $21 BRN foo = skip one byte, same speed 1 byte less +L0414 comb Set flag (there is another window on screen) +L0415 puls y,x Restore window table & screen table ptrs + bcs L03F4 Not only window, CLS our area before we exit + bsr L0417 Only one, deallocate mem for screen if possible + cmpy <$002E Our window table ptr same as current ptr? + bne L03F4 No, Clear our screen & exit + IFNE H6309 + clrd Yes, clear current window & screen table ptrs + clrw + stq <$2E + ELSE + clra + clrb + std <$2E + std <$30 + std <$B5 + ENDC +* Clear palettes to black + sta >$ff9a Border + IFNE H6309 + stq >$ffb0 And all palette regs + stq >$ffb4 + stq >$ffb8 + stq >$ffbc + ELSE + pshs b,x + ldx #$ffb0 + ldb #16 +L03FCb sta ,x+ + decb + bne L03FCb + puls b,x + ENDC +L03FC jmp >GrfStrt+L0118 Return to system + +* CLS our old screen with background color & leave if we weren't only window +* on the screen (for Multi-Vue, for example) +L03F4 ldb St.Back,x Get background palette reg from screen table + stb <$0062 Put into background RGB Data + lbsr L1377 CLS the area we were in +* clrb No errors + jmp >GrfStrt+L0F78 Return to system + +* Called by DWEnd if we were only window on physical screen +* Entry: Y=window table ptr +* X=screen table ptr +L0417 pshs y Preserve window table pointer + lda St.Sty,x Get screen type + bpl L043F Graphics screen, can definately de-allocate +* Text window - could be others still active in 8K block + ldy St.LStrt,x Get screen phys. addr from screen table + ldb #$FF Mark this part of 8K block as unused stb ,y - anda #$CF - cmpa #$85 - bne L03BF - stb >$0800,y -L03BF ldy #$8000 -L03C3 cmpb ,y - bne L03E6 - lbsr L025A - bcs L03C3 - ldb #$01 - bra L03D8 -L03D0 anda #$0F - leay >L0262,pcr + cmpa #$85 Is this an 80 column hardware text window? + bne L042E No, 40 column so just mark the 1 half + leay >$0800,y 80 column so mark both halves as unused (since + stb ,y routine below checks for 40 column markers) +L042E ldy #$8000 Point to first of 4 possible windows in block +* Check if entire 8K block is empty... if it is, deallocate it +L0432 cmpb ,y Is this one already marked as unused? + bne L0455 No, can't deallocate block so skip ahead + lbsr L02F1 Yes, move to next text screen start in block + blo L0432 Not last one, keep checking + ldb #$01 # of memory blocks in this screen + bra L0445 Deallocate the block from used memory pool +* If a graphics screen, get # blocks to deallocate +L043F ldy #GrfStrt+L02FA-1 Get # mem blocks for this screen ldb a,y -L03D8 pshs x,b - clra - ldb $01,x - tfr d,x - puls b - lbsr L016A - puls x -L03E6 clr $01,x - puls pc,y -L03EA puls b,a - pshs y,b,a - ldb -$0E,y - lda #$40 +* Deallocate memory block(s) from screen since they are now unused +L0445 pshs x,b Preserve screen table ptr & # blocks + clra clear MSB of D + ldb St.SBlk,x Get MMU start block # for screen + tfr d,x Move to X + puls b Get back # blocks to deallocate + os9 F$DelRAM Deallocate the memory +* 03/02/92 MOD: A BAD DELRAM CALL WOULD LEAVE X ON THE STACK WHEN IT BCS'ED +* TO L0458, SO THE PULS & BCS ARE SWAPPED TO SET THE STACK CORRECTLY + puls x get screen table ptr back + bcs L0458 If error, return with error flags +L0455 clrb No error and set start block # to 0 (to indicate + stb St.SBlk,x not used) +L0458 puls pc,y Restore window table ptr & return + +* Part of OWSet +* Entry: Y=New overlay window table ptr +* Exit: Overlay window table ptr on stack, Y=Parent window table ptr +L045A puls d Get RTS address + pshs y,d Swap RTS address & Y on stack + ldb Wt.BLnk,y Get parent window # + lda #Wt.Siz Size of window table entries mul - leay >$0190,u - leay d,y + ldy #WinBase Point to start of window tables + leay d,y Point to parent window entry rts -L03FA bsr L03EA - jsr <$00B9 + +* OWSet Entry point +L046A bsr L045A Get parent window table ptr + lbsr L0177 Map in parent window & setup grfdrv mem from it + ldd ,s Y=parent, d=overlay + exg y,d d=parent, y=overlay + std ,s Stack=Parent window ptr, Y=Overlay window ptr + bsr L049D Check legitamacy of overlay coords & size + bcs L049A Illegal, exit with Illegal Coord error + ldd Wt.STbl,x Get root window's screen table ptr + std Wt.STbl,y Dupe into overlay window's screen table ptr + bsr L04CC Set up overlay window table from root table + ldb <$0059 Save switch on? + beq L0490 No, don't save original area (or clear it) + lbsr L0516 Calculate sizes + bcs L049A error, return to system + ldb Wt.Back,y Get background color + stb <$62 Make current background color + lbsr L1377 CLS the overlay window area +L0490 puls x Get parent's window table ptr + cmpx <$002E Is it the current window? + bne L0499 No, exit without error + sty <$002E Make overlay window the current window +L0499 clrb No errors +L049A jmp >GrfStrt+L0118 Return to system + +* Make sure overlay window coords & size are legit +L049D bsr L04BA Get pointer to 'root' device window into X +L049F ldb Wt.CPX,y Get X coord start of overlay window + bmi L04B7 If >=128 then exit with error + addb Wt.SZX,y Add current X size to X start + bcs L04B7 added line: exit if 8-bit overflow + cmpb Wt.DfSZX,x Compare with maximum X size allowed + bhi L04B7 Too wide, exit with error + ldb Wt.CPY,y Get current Y coord start + bmi L04B7 If >=128 then exit with error + addb Wt.SZY,y Add current Y size to Y start + bcs L04B7 added line: exit if 8-bit overflow + cmpb Wt.DfSZY,x Compare with maximum Y size allowed + bhi L04B7 Too high, exit with error + clrb Will fit, exit without error +L04CB rts + +L04B7 jmp >GrfStrt+L01F5 Exit with illegal coordinate error + +* Search for device window entry at the bottom of this set of overlay windows +* Entry: Y=Current window ptr +* Exit: X=Pointer to 'root' device window (in case of multiple overlays) +L04BA tfr y,x Move current window ptr to X +L04BC ldb Wt.BLnk,x Get back window # link + bmi L04CB If overlay window itself, skip ahead + ldx #WinBase Point to start of window tables + lda #Wt.Siz Size of each entry + mul Calculate address of back window table entry + IFNE H6309 + addr d,x + ELSE + leax d,x + ENDC + bra L04BC Keep looking back until device window is found + +* Set up new overlay window table based on root window information +* Entry: X=root window ptr, Y=overlay window ptr +L04CC clr Wt.OBlk,y Overlay memory block #=0 + lbsr L079B Go make default attribute byte from FG/BG colors + lda Wt.Attr,x Get the default attribute byte from root + anda #$C0 Mask out all but Blink & Underline + ora Wt.Attr,y Merge with overlay window's colors + sta Wt.Attr,y Save new attribute byte + IFNE H6309 + ldq Wt.BSW,x Set up other defaults in overlay based on root + stq Wt.BSW,y + ldq Wt.LVec,x + stq Wt.LVec,y + ELSE + ldd Wt.BSW,x + std Wt.BSW,y + ldd Wt.BSW+2,x + std Wt.BSW+2,y + ldd Wt.LVec,x + std Wt.LVec,y + ldd Wt.LVec+2,x + std Wt.LVec+2,y + ENDC + ldd Wt.FOff+1,x + std Wt.FOff+1,y + ldb Wt.GBlk,x + stb Wt.GBlk,y + ldd Wt.GOff,x + std Wt.GOff,y + ldb Wt.Fore,y Get foreground palette + lbsr L074C Get bit mask if gfx window + stb Wt.Fore,y Store color or mask + ldb Wt.Back,y Get background palette + lbsr L074C Get bit mask if gfx window + stb Wt.Back,y Store color or mask + ldd Wt.LStrt,x Get screen logical start address + jmp >GrfStrt+L03A9 Set up rest of window table & return + +* Entry: X=root window table ptr +* Y=Overlay window table ptr +* Exit: <$4F=X screen size (chars if hware text, pixels if Gfx) +* <$51=Y screen size (char lines if hware text, pixels if Gfx) +L0516 pshs x Preserve root window table ptr + bsr xy.intoq get X,Y size for text/gfx into Q + IFNE H6309 + stq <$4F Save X and Y screen size (chars or pixels) + ELSE + pshs d + std <$4F + ldd <$B5 + std <$51 + puls d + ENDC + clrb + std <$0047 Set current X coordinate to 0 + lbsr L0BEA Calculate # bytes wide overlay is + puls pc,x Restore root window table ptr & return + +* OWEnd entry point +L053A lbsr L0177 Map in window & set up Grfdrv mem from it + cmpy <$2E Is this the current interactive window? + bne L054A No, skip ahead + lbsr L045A Yes, get parent window tbl ptr into Y + sty <$002E Make parent window the new interactive window + puls y Get overlay window tbl ptr back +L054A ldb Wt.OBlk,y Get MMU block # of overlay window + beq L0562 If none, save switch was off, so skip ahead + lbsr L017C Map in get/put block + stb <$007D Save block # + ldd Wt.OOff,y Get ptr to buffer start in block + std <$007E Save that too + lbsr L0CF8 Go put it back on the screen + lbsr L092B Hunt down the overlay window GP Buffer + lbsr L0A55 Kill the buffer (free it up) +L0562 ldd #$FFFF Mark window table entry as unused + std Wt.STbl,y + bra L057D Exit without error + +L0569 comb + ldb #E$IllCmd Exit with Illegal Command error + bra L057E + +* CWArea entry point +L056E lbsr L0177 Map in the window + tfr y,x Move window tbl ptr to X + lbsr L049F Make sure coords will fit in orig. window sizes + bcs L057E No, exit with error + ldd Wt.LStDf,y get screen logical start + bsr L0581 go do it +L057D clrb No error +L057E jmp >GrfStrt+L0118 return to system + +* This routine is ONLY called from L0516 (CWArea) and L0581 (OWSet) +* As these routines are not called too often, we can add 10 clock cycles +xy.intoq clra clear carry for ROLW, below + ldb Wt.SZY,y Get current Y size of overlay window into W + IFNE H6309 + tfr d,w move Y-size into W + ELSE + std <$B5 + ENDC + ldb Wt.SZX,y Get current X size of overlay window into D + tst <$60 Test screen type + bmi L0530 If hardware text, exit without doing more shifts + IFNE H6309 + rolw multiply by 8 for # pixels down + rolw + rolw E=$00 and CC.C=0 from above,so this is really ASLW + lslb Multiply by 8 for # pixels across + lsld A=$00 from CLRA, above. Max 80 + lsld + ELSE + lsl <$B6 + rol <$B5 + lsl <$B6 + rol <$B5 + lsl <$B6 + rol <$B5 + lslb + lslb + rola + lslb + rola + ENDC +L0530 rts + +* Entry :x= Screen table ptr +* y= Window table ptr +* d= Screen logical start address +L0581 pshs d,x Preserve Screen start & screen tbl ptr + ldb <$0060 get STY marker + andb #$0F keep only first 4 bits + ldx #GrfStrt+L05E1-1 Point to # bytes/text char table + ldb b,x get number bytes/char + stb Wt.CWTmp,y Preserve # bytes/char + lda Wt.SZX,y get current X size (of window) + mul Calculate # bytes wide window is + stb Wt.XBCnt,y Preserve #bytes wide window is + clra #bytes per row MSB to 0 + ldb <$0063 Get #bytes per row on screen + tst <$0060 Text or graphics screen? + bmi L05A1 If text, we already have # bytes per row + IFNE H6309 + lsld If graphics, multiply x 8 since each text row + lsld is 8 sets of lines + lsld + ELSE + lslb + rola + lslb + rola + lslb + rola + ENDC +L05A1 std Wt.BRow,y Preserve # bytes/text row (8 lines if gfx) + clra + ldb Wt.CPY,y Get Upper left Y coord of window + IFNE H6309 + muld Wt.BRow,y Calculate Y coordinate start + stw <$0097 save Y offset + ELSE + pshs x,y,u + ldx Wt.BRow,y + lbsr MUL16 + stu <$97 + stu <$B5 + puls x,y,u + ENDC + lda Wt.CPX,y get X coordinate start + ldb Wt.CWTmp,y get # bytes per text character + mul calculate where X starts + addd ,s++ add it to screen start address + addd <$0097 add in Y offset + std Wt.LStrt,y get screen logical start + lbsr L11E1 home cursor + ldb <$0060 get STY marker + bmi L05C0 text, don't need scale factor + bsr L05E7 calculate scaling factor +* Calculate window X size in either pixels or characters +* Q is D:W D=X size, W=Y size +L05C0 bsr xy.intoq get X and Y for text/gfx into Q + IFNE H6309 + decw adjust Y to start at 0 + decd adjust X to start at 0 + stq Wt.MaxX,y save maximum X co-ordinate + ELSE + subd #1 + std Wt.MaxX,y + pshs d + ldd <$B5 + subd #1 + std <$B5 + std Wt.MaxX+2,y + puls d + ENDC + puls x,pc restore & return + +* # bytes for each text char +L05E1 fcb $01 640 2 color + fcb $02 320 4 color + fcb $02 640 4 color + fcb $04 320 16 color + fcb $02 80 column text (includes attribute byte) + fcb $02 40 column text (includes attribute byte) + +* Graphic window scaling constants (When multiplied by the maximum width/ +* height of the screen in characters, they equal 256. The resulting figure +* is rounded up by 1 if the result has a fraction >=.8. +* The resulting rounded figure (1 byte long) is then used by multiplying +* it with the coordinate requested, and then dividing by 256 (dropping +* the least significiant byte). The resulting 2 byte number is the scaled +* coordinate to actually use.) +* The actual scaling factor is a 16x8 bit multiply (Scale factor by # of +* columns/rows) into a 3 byte #. If the LSB is >=$CD (.8), then round up +* the 2nd byte by 1 (MSB is unused). The 2nd byte is the scaling factor. +* X scaling constants for 640x screen +XSclMSB fdb $0333 X Scaling factor (~3.2) + +* Y scaling constants (note: fractional part of 200 line has changed from +* $3f to $3e, since that is closer to get the 256 mod value) +YScl192 fdb $0AAB Y Scaling factor for 192 row scrn (~10.668) +YScl200 fdb $0A3E Y Scaling factor for 200 row scrn (~10.2422) + +* Calculate scaling factors for a graphics window (# row/columns*scale factor) +* Must be as close to 256 as possible +L05E7 clra D=# of columns + ldb Wt.SZX,y + IFNE H6309 + muld <XSclMSB,pc Multiply by X scaling factor + cmpf #$cd Need to round it up if >=.8? + ELSE + pshs x,y,u + ldx <XSclMSB,pc + lbsr MUL16 + stu <$B5 + tfr u,d + cmpb #$cd tfr y,d - ldy ,s - std ,s - bsr L042D - bcs L042B - ldd -$10,x - std -$10,y - lbsr L0149 - bsr L045C - tst <$0059 - beq L0421 - bsr L048E - bcs L042B - ldb $07,y - stb <$0062 - lbsr L129C -L0421 ldx ,s - cmpx <$002E - bne L042A - sty <$002E -L042A clrb -L042B puls pc,x -L042D bsr L044A -L042F ldb -$0B,y - bmi L0447 - addb -$09,y - cmpb <$28,x - bhi L0447 - ldb -$0A,y - bmi L0447 - addb -$08,y - cmpb <$29,x - bhi L0447 - clrb + puls x,y,u + ENDC + blo saveXscl No, save result + IFNE H6309 + ince Round it up +saveXscl ste Wt.SXFct,y Save X scaling multiplier + ELSE + inc <$B5 +saveXscl pshs a + lda <$B5 + sta Wt.SXFct,y + puls a + ENDC + ldb Wt.SZY,y D=# of rows (A=0 from MULD already) + cmpb #25 Is it the full 25 lines? + blo useold No, use old scaling factor for compatibility + IFNE H6309 + muld <YScl200,pc Multiply by 200 line Y scaling factor + ELSE + pshs x,y,u + ldx <YScl200,pc + lbsr MUL16 + stu <$B5 + tfr y,d + puls x,y,u + ENDC + bra chkrnd +useold equ * + IFNE H6309 + muld <YScl192,pc Multiply by 192 line Y scaling factor + ELSE + pshs x,y,u + ldx <YScl192,pc + lbsr MUL16 + stu <$B5 + tfr y,d + puls x,y,u + ENDC +chkrnd equ * + IFNE H6309 + cmpf #$cd Need to round it up if >=.8? + ELSE + pshs b + ldb <$B6 + cmpb #$cd + puls b + ENDC + blo saveYscl No, save result + IFNE H6309 + ince Round it up + ELSE + inc <$B5 + ENDC +saveYscl equ * + IFNE H6309 + ste Wt.SYFct,y Save Y scaling multiplier + ELSE + pshs a + lda <$B5 + sta Wt.SYFct,y + puls a + ENDC + rts + +* PSet entry point - Change <$16,y vector to proper pattern drawing +L0611 ldb <$0057 get group mem block # + bne L061D If a pattern is wanted, go find it + stb Wt.PBlk,y Set memory block # to 0 (PSET patterning off) + ldx #GrfStrt+L1F9E Point to normal PSET vector + bra L0635 Go preserve vector & exit without error + +L061D lbsr L0930 Go search buffers for the one we want + bcs L0639 If the buffer doesn't exist, exit with error + stb Wt.PBlk,y Save PSET block # + leax Grf.Siz,x Skip Gfx buffer header + stx Wt.POff,y Save offset to actual graphics data + ldb [Wt.STbl,y] Get screen type from screen table + ldx #GrfStrt+L1FB4-1 Point to table (-1 since scrn type 0 illegal) + ldb b,x Get unsigned offset for vector calculation + abx Calculate address of vector +L0635 stx Wt.PVec,y Preserve PSET vector +L0638 jmp >GrfStrt+L0F78 Return to system, without any errors + +* Font entry point +L063C lbsr L0177 Map in window + bsr L0643 Go set font group # +L0639 jmp >GrfStrt+L0118 Return to system + +L0643 ldb <$0057 get block number for font buffer + bne L064A If there is one, go set it up + stb Wt.FBlk,y Set font memory block # to 0 (no fonts) rts -L0447 lbra L01CB -L044A tfr y,x -L044C ldb -$0E,x - bmi L045B - leax >$0190,u - lda #$40 - mul - leax d,x - bra L044C -L045B rts -L045C clr <$11,y - lda $09,x - sta $09,y - lbsr L06DC - lda $08,x - anda #$C0 - ora $08,y - sta $08,y - ldd #$050A - bsr L0481 - ldd #$0714 - bsr L0481 - lbsr L032D - ldd -$0D,x - lbsr L0337 + +L064A lbsr L1002 Go set the font ('.' font default if none) + lbsr L0930 Search buffers for proper one + bcs L0684 Error, skip ahead + pshs x,b Preserve graphics buffer table ptr & b + ldd Grf.XSz,x Get X size of buffer + cmpd #6 6 pixel wide buffer? + beq L0662 Yes, go on + cmpd #8 8 pixel wide buffer? + bne L0685 Not a font, report buffer # error +* It is a buffer size that matches those acceptable to fonts +L0662 ldd Grf.YSz,x Get Y size of buffer + cmpd #8 8 pixel high buffer? + bne L0685 No, report buffer # error + stb Grf.XBSz,x Preserve font height + ldd Grf.XSz,x Get X size of buffer again + cmpd <$006E Get X pixel count + beq L067D Same, set up normally + ldb Wt.FBlk,y Check font block # + beq L067D If there is none, exit normally (pointing to '.') + lbsr L11CD If not, do CR & set up width of line +L067D puls x,b Get back regs + stb Wt.FBlk,y Store block # where font is + stx Wt.FOff,y Store offset to font within 8K block + clrb No error and return +L0684 rts + +* Can't do font +L0685 puls x,b Get block # and graphics table buffer ptr back + ldb #E$BadBuf bad buffer # error + coma Set error flag rts -L0481 pshs a -L0483 lda b,x - sta b,y - incb - dec ,s - bne L0483 - puls pc,a -L048E pshs x - clra - ldb -$09,y - tst <$0060 - bmi L049A - lda #$08 - mul -L049A std <$004F - clra - ldb -$08,y - tst <$0060 - bmi L04A6 + +* GCSet entry point +L068B lbsr L0177 Map in window + ldb <$0057 Get group # for graphics cursor + bne L0697 There is one, go process + stb Wt.GBlk,y Set to 0 to flag that graphics cursor is off + bra L0639 Return to system +L0697 lbsr L0930 Go search graphics buffers for the one we want + bcs L0639 Can't find, return to system with error + stb Wt.GBlk,y Store block # of graphics cursor + stx Wt.GOff,y Store offset into block for graphics cursor + bra L0638 Return to system with no errors + +* FColor entry point +L0707 ldb [Wt.STbl,y] Get screen type from screen table + stb <$0060 Save as current screen type + ldb <$005A Get palette number from user + bsr L074C Go get mask for it + stb Wt.Fore,y Save foreground palette # + IFNE H6309 + tim #Invers,Wt.BSW,y Inverse on? + ELSE + ldb Wt.BSW,y regB does not need to be preserved + bitb #Invers + ENDC + bne L0738 Yes, go process for that +L0719 ldb <$005A get palette register number + lslb Move into foreground of attribute byte lslb lslb - lslb -L04A6 std <$0051 - clrb - std <$0047 - lbsr L0AF5 - puls pc,x -L04B0 jsr <$00B9 - cmpy <$002E - bne L04BF - lbsr L03EA - sty <$002E - puls y -L04BF ldb <$11,y - beq L04D6 - jsr <$00BC - stb <$007D - ldd <$12,y - std <$007E - lbsr L0C01 - lbsr L084C - lbsr L0963 -L04D6 ldd #$FFFF - std -$10,y - bra L04EB -L04DD jsr <$00B9 - tfr y,x - lbsr L042F - bcs L04EC - ldd <$24,y - bsr L04ED -L04EB clrb -L04EC rts -L04ED pshs x,b,a - ldb <$0060 - andb #$0F - leax >L0548,pcr - ldb b,x - stb $03,y - lda -$09,y - mul - stb $02,y - clra - ldb <$0063 - tst <$0060 - bmi L050A - lda #$08 - mul -L050A std $04,y - ldb -$0A,y - ldx $04,y - lbsr L1E21 - std <$0097 - lda -$0B,y - ldb $03,y - mul - addd ,s++ - addd <$0097 - std -$0D,y - lbsr L10A7 - ldb <$0060 - bmi L0529 - bsr L054F -L0529 clra - ldb -$09,y - tst <$0060 - bmi L0533 - lda #$08 - mul -L0533 subd <$00B3 - std <$1B,y - clra - ldb -$08,y - tst <$0060 - bmi L0542 - lda #$08 - mul -L0542 subb #$01 - std <$1D,y - puls pc,x -L0548 equ *-1 -L0549 fcb 1,2 - fcb 2,4 - fcb 2,2 -L054F pshs x - clra - ldb -$09,y - tfr d,x - lda #$03 - mul + andb #$38 Clear out blink/underline & background + lda Wt.Attr,y Get default attributes + anda #$C7 Mask out foreground + bra L0742 OR in new foreground + +* BColor entry point +L0726 ldb [Wt.STbl,y] Get screen type from screen table + stb <$0060 save it in global + ldb <$005A get palette register # + bsr L074C + stb Wt.Back,y save background into window table + IFNE H6309 + tim #Invers,Wt.BSW,y Inverse on? + ELSE + ldb Wt.BSW,y regB does not need to be preserved + bitb #Invers + ENDC + bne L0719 If set, do masking to switch fore/bck ground colors + +L0738 ldb <$005A Get palette register # + andb #$07 Force to 0-7 only + lda Wt.Attr,y Get default attributes + anda #$F8 Mask out background +L0742 equ * + IFNE H6309 + orr b,a Merge the color into attribute byte + ELSE pshs b - ldb #$33 - lbsr L1E00 - addb ,s+ - stb -$07,y - clra - ldb -$08,y - tfr d,x - lda #$0A - mul - pshs b - ldb #$AB - lbsr L1E00 - addb ,s+ - stb -$06,y - puls pc,x -L0579 ldb <$0057 - bne L0584 - stb $0E,y - ldx #$5F83 - bra L059B -L0584 lbsr L0851 - bcs L059F - stb $0E,y - leax <$20,x - stx $0F,y - ldx -$10,y - ldb ,x - ldx #$5F0A - ldb b,x - leax b,x -L059B stx <$16,y -L059E clrb -L059F rts -L05A0 jsr <$00B9 -L05A2 ldb <$0057 - bne L05A9 - stb $0B,y - rts -L05A9 lbsr L0F31 - lbsr L0851 - bcs L05E2 - pshs x,b - ldd $07,x - tsta - bne L05E3 - cmpb #$06 - beq L05C0 - cmpb #$08 - bne L05E3 -L05C0 ldd $09,x - cmpd #$0008 - bne L05E3 - stb $0B,x - ldd $07,x - cmpd <$006E - beq L05DB - tst $0B,y - beq L05DB - lbsr L112D - lbsr L1119 -L05DB puls x,b - stb $0B,y - stx $0C,y - clrb -L05E2 rts -L05E3 ldb #$C2 - coma - puls pc,x,a -L05E8 jsr <$00B9 - ldb <$0057 - bne L05F2 - stb <$18,y - rts -L05F2 lbsr L0851 - bcs L059F - stb <$18,y - stx <$19,y - bra L059E -L05FF leax <L0616,pcr - ldb $0A,y - cmpb #$05 - bhi L0612 - lslb - ldd b,x - leax d,x - stx <$14,y - bra L062D -L0612 comb - ldb #$BB + ora ,s+ + ENDC + sta Wt.Attr,y Store new default attribute +L0748 clr <$A9 No error, clear flag & return to system + jmp >GrfStrt+L0118 + +* Convert color to allowable ones for screen type +* NOTE: see if we can swap a/b roles to allow ABX instead of LEAX A,X +L074C pshs x,a Preserve screen table ptr & a + lda <$0060 get STY marker + bmi L075D text or same screen, return + ldx #GrfStrt+L075F-1 Point to mask table + lda a,x Get offset to proper mask set + leax a,x Point to the mask table + andb ,x+ Mask out bits we can't use on this type screen + ldb b,x Get bit mask for the foreground color +L075D puls pc,x,a restore regs & return + +L075F fcb L0763-(L075F-1) $05 (640/2 color table offset) + fcb L0766-(L075F-1) $08 (320/4 color table offset) + fcb L0766-(L075F-1) $08 (640/4 color table offset) + fcb L076B-(L075F-1) $0d (320/16 color table offset) + +* Color masks for 640 2 color +L0763 fcb $01 + fcb $00,$ff + +* Color masks for 640 and 320 4 color +L0766 fcb $03 + fcb $00,$55,$aa,$ff + +* Color masks for 320 16 color +L076B fcb $0f + fcb $00,$11,$22,$33,$44,$55,$66,$77 + fcb $88,$99,$aa,$bb,$cc,$dd,$ee,$ff + +* Get foreground color mask +L0791 tst ,x Check screen type? + bpl L074C If graphics, mask out values scrn type can't use + andb #$07 Just least significiant 3 bits + rts + +* Make default attribute byte from current fore/background colors (blink & +* underline forced off) +L079B ldb Wt.Fore,y Get foreground palette # + andb #$07 Use only 0-7 + lslb Shift to foreground color position + lslb + lslb + lda Wt.Back,y Get background palette # + anda #$07 Use only 0-7 + IFNE H6309 + orr a,b Merge foreground & background + ELSE + pshs a + orb ,s+ + ENDC + stb Wt.Attr,y Set new default attributes rts -L0616 fdb $1984 - fdb $1982 - fdb $1989 - fdb $197E - fdb $1972 - fdb $1976 -L0622 ldb 9,y - orb #$80 - tsta - beq L062B - andb #$7F -L062B stb $09,y -L062D clrb - rts -L062F ldb <$0086 - ldx -$10,y - leax <$10,x - lda <$005A - anda #$0F - stb a,x - bra L062D -L063E ldx -$10,y -L0640 pshs y,x - leay <$10,x - ldx >$1019 - clra -L0649 ldb ,x+ - stb a,y - inca - cmpa #$0F - ble L0649 - puls pc,y,x -L0654 ldb <$005A - ldx -$10,y - stb $05,x - bra L0696 -L065C bsr L0673 - stb $06,y - ldb $09,y - bitb #$04 - bne L0688 -L0666 ldb <$005A - lslb - lslb - lslb - andb #$38 - lda $08,y - anda #$C7 - bra L0690 -L0673 ldx -$10,y - ldb ,x - stb <$0060 - ldb <$005A - bsr L0698 - rts -L067E bsr L0673 - stb $07,y - ldb $09,y - bitb #$04 - bne L0666 -L0688 ldb <$005A - andb #$07 - lda $08,y - anda #$F8 -L0690 stb <$0097 - ora <$0097 - sta $08,y -L0696 clrb - rts -L0698 pshs x,a - lda <$0060 - bmi L06A2 - tfr b,a - bsr L06AC -L06A2 puls pc,x,a -L06A4 leax <L06B4,pcr - ldb <$0060 - ldb b,x - rts -L06AC bsr L06A4 - leax b,x - anda ,x+ - ldb a,x -L06B4 rts -L06B5 fcb L06B9-L06B4 - fcb L06BC-L06B4 - fcb L06BC-L06B4 - fcb L06C1-L06b4 -L06B9 fcb 1 - fcb 0,$FF -L06BC fcb 3 - fcb 0,$55,$AA,$FF -L06C1 fcb 15 - fcb 0,$11,$22,$33,$44,$55,$66,$77 - fcb $88,$99,$AA,$BB,$CC,$DD,$EE,$FF -L06D2 tst ,x - bpl L06D9 - andb #$07 - rts -L06D9 bsr L0698 - rts -L06DC ldd $06,y - anda #$07 - lsla - lsla - lsla - andb #$07 - stb <$0097 - ora <$0097 - sta $08,y - rts -L06EC ldb #$10 -L06EE lbra L034E -L06F1 ldb #$08 - bra L06EE -L06F5 ldb #$20 - bra L06EE -L06F9 ldx <$002E - pshs y,x - ldy -$10,y - lda $01,y - ldx $02,y - lbsr L07E9 - ldx #$FF90 - ldb >$0090 - andb #$7F - stb >$0090 - stb ,x - leax <L078D,pcr - ldb ,y - andb #$0F - lslb - abx - lda >$0098 - anda #$78 - ora ,x+ - ldb ,y - andb #$10 - lslb - orb ,x - ldx #$FF90 - std >$0098 - std $08,x - ldd <$0082 - lsra - rorb - ror <$0084 - lsra - rorb - ror <$0084 - lsra - rorb - ror <$0084 - sta $0B,x !!!!!!!!!!!new instruction!!!!!!!!!! RG - clra - std >$009C - std $0C,x - lda <$0084 - clrb - std >$009E - std $0E,x - ldb $05,y - leay <$10,y - ldb b,y - stb >$009A - bsr L079B - stb $0A,x - ldx #$FFB0 - lda #$10 -L0762 ldb ,y+ - bsr L079B - stb ,x+ - deca - bhi L0762 - ldy ,s++ - beq L0772 - jsr <$00B9 -L0772 puls y - lbsr L0107 - sty <$002E - stx <$0030 - ldb >$1000 - stb >$1001 - ldd <$003D - std <$005B - ldd <$003F - std <$005D - lbsr L142A -L078D clrb - rts - suba #$14 - suba #$15 - suba #$1D - suba #$1E - com <$0015 - com <$0005 -L079B pshs x - tst >$1009 - bne L07A7 - leax <L07A9,pcr - ldb b,x -L07A7 puls pc,x -L07A9 fcb $00,$0C,$02,$0E,$07,$09,$05,$10 + +* Select entry point +* Entry: Y=Newly selected window pointer +* ATD: !! Save DP, too. +L07D7 pshs y save Window table ptr we will be going to + ldy <$002E get window table ptr we are going from + beq L07E1 If none, skip ahead + lbsr L0177 set variables/MMU & update cursors on old window +L07E1 ldb >WGlobal+G.CurTik Reload counter for # ticks/cursor updates + stb >WGlobal+G.CntTik + ldy ,s get 'to' window table pointer + lbsr L0129 Map in window & setup grfdrv mem for new window + sty <$002E save it as current window entry + stx <$0030 set current screen table pointer + tfr x,y Move to Y reg +L08DB ldx #$FF90 point to Gime registers +*ATD: Do a TFR 0,DP: larger but faster? + ldu #$0090 point to shadow RAM for GIME hardware + IFNE H6309 + aim #$7f,,u remove Coco 1/2 compatibility bit: set from VDGInt + ldb ,u get new value + ELSE + ldb ,u + andb #$7f + stb ,u + ENDC + stb ,x save it to GIME +* Calculate extended screen address for 1 or 2 Meg upgrade +* Entry: X=$FF90 (start of GIME regs) +* Y=Screen table ptr +* Exits: With GIME (and shadow regs) pointing to proper GIME screen address & +* proper 512k bank (via Disto's DAT) that screen is in (0-3 for up to +* 2 Meg of RAM) + clra + sta $0F,x Set horizontal scroll to 0 + sta $0F,u And set it's shadow + ldb St.SBlk,y Get block # of screen + IFNE H6309 + lsld Multiply by 4 (to shift which 512k bank into A) + lsld + ELSE + lslb + rola + lslb + rola + ENDC + stb <$0082 Remainder is the block #(0-3F) in this 512k bank +* No, remainder is V.OFF1 of this block. RG. + clrb vertical scroll=0 + std $0B,x Set which of up to 4 512K banks video is from + std $0B,u And set it's shadow, along with vertical scroll + ldd St.LStrt,y Get screen logical start + suba #$80 Subtract $80 from MSB of that address + IFNE H6309 + lsrd Divide result by 8 + lsrd + lsrd + ELSE + lsra + rorb + lsra + rorb + lsra + rorb + ENDC + adda <$0082 Add to MSB of 24 bit extended screen address + std $0D,x Store result into GIME's vertical offset register + std $0D,u and it's shadow + + ldx #GrfStrt+L086A.24-2 GIME setup table for 24-line screens + ldb St.ScSiz,y get screen size into B + cmpb #24 24-line screens? + beq L0840 if so: skip ahead; else get 25-line pointer + ldx #GrfStrt+L086A.25-2 GIME setup table for 25-line screens + +L0840 ldb ,y get screen type we need + andb #$0F keep only first 4 bits + lslb multiply by 2 (2 bytes per entry) + abx find entry + lda $08,u get current GIME video mode register + anda #$78 keep only non video bits + ora ,x bring in new video mode + ldb 1,x get Video resolution +* ATD: for new 'garbage-less' CLRing, and new clock, save these values +* at $08,u, and set $06,u: The clock will clear the flag at $0096, and update +* the GIME video hardware at the _start_ of the IRQ process. + std $08,u save new GIME shadow registers + std >$FF98 save it to GIME +* Set up colors on GIME for newly selected window + ldb St.Brdr,y Get current border palette # + leay St.Pals,y Point to palette register data in scrn tbl + IFNE H6309 + ldf >WGlobal+G.MonTyp Get monitor type in F for faster translates + ENDC + ldb b,y Get border color + stb $0A,u Save new border color to GIME shadow + IFNE H6309 + tstf Need to convert color? + ELSE + tst >WGlobal+G.MonTyp + ENDC + bne DoBord Nope + ldx #GrfStrt+L0884 Point to translation table + ldb b,x Get composite version +DoBord stb >$ff9a Save it on GIME + ldu #$FFB0 U=GIME palette reg. ptr + IFNE H6309 + tstf Rest of colors need translation? + ELSE + tst >WGlobal+G.MonTyp + ENDC + bne FstRGB No, use TFM +* Composite translate here + lda #$10 A=# of colors +L0851 ldb ,y+ Get RGB color + ldb b,x Get composite version + stb ,u+ Save it to GIME + deca Done? + bhi L0851 No, keep going + bra DnePaltt Done, go do Gfx cursor +FstRGB equ * + IFNE H6309 + ldw #$0010 Palette register ptr & # palette regs + tfm y+,u+ Move them onto GIME + ELSE + pshs d + ldb #16 +FstRGB2 lda ,y+ + sta ,u+ + decb + bne FstRGB2 + clra + std <$B5 + puls d + ENDC + +* ATD: PULS DP, too +DnePaltt puls y Restore window entry + IFNE H6309 + ldq <$3D Get last coords that Gfx cursor was ON at + stq <$5B Save as current coords of Gfx cursor + ELSE + ldd <$3F + std <$5D + std <$B5 + ldd <$3D + std <$5B + ENDC + lbsr L153B Update 'last gfx cursor on' position to new one + jmp >GrfStrt+L0F78 return to system: no errors + +* GIME graphics register values +* 1st byte goes to $ff98 +* 2nd byte goes to $ff99 +* NOTE: To change to 25 line TV res (200 not 225), change $0475 & $0465 to +* $033D & $032D respectively (approx $825 in V1.15+) +* ifeq MaxLines-25 +L086A.25 fdb $8034 640x200 2 color + fdb $8035 320x200 4 color + fdb $803D 640x200 4 color + fdb $803E 320x200 16 color + ifeq TV-1 + fdb $033D 80x25, 200 line screen + fdb $032D 40x25, 200 line screen + else + fdb $0475 80x25, 225 line screen + fdb $0465 40x25, 225 line screen + endc + +* else +L086A.24 fdb $8014 640x192 2 color + fdb $8015 320x192 4 color + fdb $801D 640x192 4 color + fdb $801E 320x192 16 color + fdb $0315 80x24, 192 line screen + fdb $0305 40x24, 192 line screen +* endc + +* 64 color translation table for RGB to composite monitor +L0884 fcb $00,$0c,$02,$0e,$07,$09,$05,$10 fcb $1c,$2c,$0d,$1d,$0b,$1b,$0a,$2b fcb $22,$11,$12,$21,$03,$01,$13,$32 fcb $1e,$2d,$1f,$2e,$0f,$3c,$2f,$3d @@ -962,590 +1945,959 @@ fcb $19,$2a,$1a,$3a,$18,$29,$28,$38 fcb $14,$04,$23,$33,$25,$35,$24,$34 fcb $20,$3b,$31,$3e,$37,$39,$3f,$30 -L07E9 clrb - lsra - rorb - lsra - rorb -L07EE lsra - rorb - std <$0082 - clr <$0084 - tfr x,d - suba #$80 - addd <$0083 - std <$0083 - bcc L0800 - inc <$0082 -L0800 rts -L0801 ldd <$0080 - addd #$001F -L0806 andb #$E0 - std <$0080 - ldb <$0057 - cmpb #$FF - beq L0818 - tst <$0032 - beq L0818 - bsr L0851 - bcc L0848 -L0818 ldd <$0080 - cmpd <$00B7 - bhi L0829 - bsr L0891 - bcs L0829 - lda #$01 - sta $0F,x - bra L082E -L0829 lbsr L08C1 - bcs L0847 -L082E stb <$007D - stx <$007E - lbsr L090D - ldd <$0057 - std $03,x - ldd <$0080 - std $05,x - clra - clrb - std $07,x - std $09,x - std $0C,x - stb $0E,x -L0847 rts -L0848 comb - ldb #$C2 + +* DefGPB entry point +L08DC bsr L08E1 go do it + jmp >GrfStrt+L0118 return to system + +* Entry point for internal DefGPB (Ex. Overlay window) +L08E1 ldd <$80 get buffer length requested + addd #$001F round it up to even multiples of 32 bytes + andb #$E0 (to allow for header) + std <$80 Preserve new value + ldb <$57 get group + cmpb #$FF overlay window save? + beq L08F8 yes, skip ahead + tst <$32 No, has there been any buffers? + beq L08F8 no, go make one + bsr L0930 Yes, see if we can fit one in + bcc L096A Return Bad/Undefined buffer error +L08F8 ldd <$80 get requested length including header + cmpd #$2000 over 8k? + bhi L090A yes, skip ahead + bsr L0975 Find block & offset to put it (new or old) + bcs L090A If couldn't find/allocate, skip ahead + lda #$01 1 8K block used for this buffer + sta Grf.NBlk,x + bra L090F Skip ahead +* Couldn't find existing block that would fit it +L090A lbsr L09A8 Go allocate blocks & map 1st one in + bcs L0928 Error, exit with it +L090F stb <$007D Save start block # + stx <$007E Save offset into block + lbsr L09FC Update get/put buffer header & last used in global + ldd <$0057 Get group & buffer # + std Grf.Grp,x save group & buffer # into buffer header + ldd <$0080 Get buffer size (not including header) + std Grf.BSz,x save buffer size in buffer header + IFNE H6309 + clrd + clrw + stq Grf.XSz,x Init X and Y sizes to 0 + ELSE + clra + clrb + std Grf.XSz,x + std Grf.XSz+2,x + std <$B5 + ENDC + std Grf.LfPx,x Init Pixel masks for 1st & last bytes in block + stb Grf.STY,x set internal screen type marker +L0928 rts + +* Set vector for overlay window buffer search +L092B ldx #GrfStrt+L093F Point to overlay window bffr search routine + bra L0933 set the vector & do search + +* Set vector for graphics buffer search +L0930 ldx #GrfStrt+L0949 Point to normal buffer search routine +L0933 stx <$A1 save the search routine vector + bsr L096E initialize previous table pointers + ldb <$32 get the last block # we used for buffers + beq L096A Wasn't one, return error + ldx <$33 get last offset + bra L0961 go map it in & do search routine + +* Overlay window buffer search +L093F cmpb Wt.OBlk,y is this the right overlay? + bne L0957 no, move to next one and come back again + cmpx Wt.OOff,y set conditions for offset match + bra L0955 go check it + +* Graphics buffer search +L0949 lda <$0057 get group we're looking for + cmpa Grf.Grp,x find it? + bne L0957 nope, keep looking + lda <$0058 get buffer # + beq L0968 done, return + cmpa Grf.Buff,x match? +L0955 beq L0968 yes, return +L0957 stb <$007D save it as previous block # + stx <$007E save previous offset + ldb Grf.Bck,x get back block # link + beq L096A there isn't one, return + ldx Grf.Off,x get offset +L0961 lbsr L017C go map it in + jmp [>GrfMem+gr00A1] Do search again +L0968 clra No error & exit + rts +L096A comb Bad buffer # error & exit + ldb #E$BadBuf + rts + +* Initialize previous buffer pointers +L096E equ * + IFNE H6309 + clrd + ELSE + clra + clrb + ENDC + stb <$7D Buffer block # + std <$7E Buffer offset # rts -L084C leax <L0860,pcr - bra L0854 -L0851 leax <L086A,pcr -L0854 stx <$00A1 - bsr L088A - ldb <$0032 - beq L0848 - ldx <$0033 - bra L0882 -L0860 cmpb <$11,y - bne L0878 - cmpx <$12,y - bra L0876 -L086A lda <$0057 - cmpa $03,x - bne L0878 - lda <$0058 - beq L0888 - cmpa $04,x -L0876 beq L0888 -L0878 stb <$007D - stx <$007E - ldb ,x - beq L0848 - ldx $01,x -L0882 jsr <$00BC - jmp [>$00A1,u] -L0888 clra - rts -L088A clra - clrb - stb <$007D - std <$007E - rts -L0891 pshs y,b - ldy <$0080 - ldx #$49E2 - stx <$00A1 - lbsr L09D5 - bcs L08BF - stb ,s - ldd $05,x - subd <$0080 - bne L08B5 - pshs x - lbsr L092D - puls x - ldb ,s - jsr <$00BC - bra L08BE -L08B5 subd <$00B5 - std $05,x - leax <$20,x - leax d,x -L08BE clra -L08BF puls pc,y,b -L08C1 ldd <$0080 - addd <$00B5 - std <$0097 - addd #$1FFF - lsra + +* Called by DefGPB +* Find get/put buffer & block # with room (or make new one) +* Exit: B=Block #, X=Ptr to where next GP buffer could go +L0975 pshs b,y Preserve regs + ldy <$0080 get size of buffer requested + ldx #GrfStrt+L0AE0,pc Set vector to find empty space in a block big + stx <$00A1 enough to fit the size we want + lbsr L0ACD Go find it + bcs L09A6 Couldn't find, exit with carry set + stb ,s Change B on stack to block # we found + ldd Grf.BSz,x Get buffer size from GP header + subd <$0080 Subtract the buffer size we need + bne L099B If not exact fit, skip ahead + pshs x Preserve GP buffer ptr a sec + lbsr L0A1C Map in previous block or new block? + puls x Restore GP buffer ptr + ldb ,s Get block # we found + lbsr L017C Go map it in + bra L09A5 exit without error +L099B subd #$0020 Don't include GP header in GP's buffer size + std Grf.BSz,x Store size into GP header's size + leax Grf.Siz,x Point to start of actual GP buffer data + leax d,x Point to where next GP buffer will go +L09A5 clra No error +L09A6 puls pc,y,b Restore regs and return + +* If initial search couldn't find/fit block, or if size>8K, go here +* Some of stack pushing/Temp storing could be done in E/F instead +* Particularily <$99 +* Map in buffer needed (or 1st block of it if >8K) +L09A8 ldd <$80 Get original size we wanted + addd #$0020 Add block header size + std <$97 Preserve into temp area + addd #$1FFF Round up to 8K + lsra Divide by 32 for # blocks needed lsra lsra lsra lsra - tfr a,b - stb <$0099 - lbsr L015C - bcs L090C - pshs b - ldb <$0099 - cmpb #$01 - bhi L0901 - ldd <$00B7 - subd <$0097 - anda #$1F - std <$009B - beq L0901 - ldd <$00B7 - subd <$009B - addd <$00B7 - tfr d,x - ldb ,s - addb <$0099 - decb - jsr <$00BC - bsr L091D - ldd <$009B - subd <$00B5 - std $05,x -L0901 ldx <$00B7 - puls b - jsr <$00BC - lda <$0099 - sta $0F,x - clra -L090C rts -L090D pshs b,a - lda <$0032 - sta ,x - stb <$0032 - ldd <$0033 - std $01,x - stx <$0033 - puls pc,b,a -L091D pshs b,a - lda <$0035 - sta ,x - stb <$0035 - ldd <$0036 - std $01,x - stx <$0036 - puls pc,b,a -L092D pshs y,a - lda ,x - ldy $01,x + tfr a,b Dupe into B + IFNE H6309 + tfr a,f And into F + ELSE + sta <$B6 + ENDC + os9 F$AllRAM Allocate memory + bcs L09FB Couldn't allocate, return with error + IFNE H6309 + tfr b,e Preserve start block # + cmpf #$01 + ELSE + stb <$B5 + ldb <$B6 regB does not need to be preserved + cmpb #1 + ENDC + bhi L09EE If more than 1 block requested, skip ahead + ldd #$2000 8k + subd <$97 Calculate # bytes left in block after our buffer + anda #$1F Round to within 8K + std <$9B Store in another temp + beq L09EE Exact size of 8K block, skip ahead + ldd #$2000 Size of block + subd <$9B subtract rounded size left in block + adda #$20 Add 8K so it points to address in GRFDRV's get/ + tfr d,x put buffer block (which is where it will be) + IFNE H6309 + tfr e,b B=Start block # of allocated RAM + ELSE + ldb <$B5 + ENDC + lbsr L017C map it in + bsr L0A0C Set up new block hdr's back links & current + ldd <$9B Get # bytes left in block + subd #$0020 Subtract header size + std Grf.BSz,x Preserve buffer size in header + +L09EE ldx #$2000 Start address of GRFDRV's get/put buffer block + IFNE H6309 + tfr e,b Move start block # to proper register + ELSE + ldb <$B5 + ENDC + lbsr L017C Map it in + IFNE H6309 + stf Grf.NBlk,x Save # of blocks needed for whole buffer + ELSE + lda <$B6 + sta Grf.NBlk,x + ENDC + clra No error & return +L09FB rts + +* Update last get/put buffer used info & Get/Put buffer header +* Updates $32 & $33-$34 +* Entry: D=Size left in second block +L09FC pshs d Preserve D + lda <$32 Get last mapped in block for Get/Put buffers + sta Grf.Bck,x Make that the block # for our header + stb <$32 Put our new last mapped block + ldd <$33 Get last mapped offset + std Grf.Off,x Put that into our header + stx <$33 Put our new offset into the last mapped offset + puls pc,d restore D & return + +* Update current get/put buffer info & Get/Put Buffer header +* Updates $35 & $36-$37 +*Entry: X=ptr to start of buffer header in GRFDRV's 2nd block (Get/put buffer) +L0A0C pshs d Preserve D + lda <$35 Get current block/group # + sta Grf.Bck,x Make new block's back ptrs. point to it + stb <$35 Make current ptr to start block we just allocated + ldd <$36 Get current offset + std Grf.Off,x Put into new block's offset + stx <$36 Make current offset our new one + puls pc,d Restore D and return + +* Make current GP buffer block & offset same as previous block & offset +* (or map in new one and set it's header up if there is no previous one) +L0A1C pshs y,a Preserve regs + lda Grf.Bck,x get back block link # + ldy Grf.Off,x Get offset in back block to it's header + ldx <$7E Get previous blocks offset to buffer + ldb <$7D and it's block # + bne L0A30 None mapped in, go map it in + sta <$35 Make into current block & offset + sty <$36 + puls pc,y,a Restore regs & return +L0A30 lbsr L017C Bring in 8K buffer block we need + sta Grf.Bck,x Set up GP block header + sty Grf.Off,x +L0A38 puls pc,y,a + +* KillBuf entry point +L0A3A ldb #$01 Set a temporary flag + stb <$0097 +L0A3E lbsr L0930 Go search for buffer (returns X=Buffer ptr) + bcs L0A4D Couldn't find it, exit + clr <$0097 Found it, clear flag + bsr L0A55 + bcs L0A52 + ldb <$0058 + beq L0A3E +L0A4D lda <$0097 Get flag + bne L0A52 Didn't get killed, return to system with error + clrb No error +L0A52 jmp >GrfStrt+L0118 Return to system + +L0A55 pshs y,x,b Preserve regs (Window tbl ptr,gfx bffr ptr,block#) + lda Grf.NBlk,x Get # blocks used + sta <$009F Save it + lda Grf.Bck,x Get back block # + ldy Grf.Off,x Get back block header offset + ldb <$007D Get current buffer block # + bne L0A6B There is one, continue + sta <$0032 Save back block as last block used + sty <$0033 And it's offset + bra L0A75 + +L0A6B lbsr L017C Go map in GP Block ldx <$007E - ldb <$007D - bne L0941 - sta <$0035 - sty <$0036 - bra L0948 -L0941 jsr <$00BC - sta ,x - sty $01,x -L0948 puls pc,y,a -L094A ldb #$01 - stb <$0097 -L094E lbsr L0851 - bcs L095D - clr <$0097 - bsr L0963 - bcs L0962 - ldb <$0058 - beq L094E -L095D lda <$0097 - bne L0962 - clrb -L0962 rts -L0963 pshs y,x,b - lda $0F,x - sta <$009F - lda ,x - ldy $01,x - ldb <$007D - bne L0979 - sta <$0032 - sty <$0033 - bra L0982 -L0979 jsr <$00BC - ldx <$007E - sta ,x - sty $01,x -L0982 ldb ,s + sta Grf.Bck,x + sty Grf.Off,x +L0A75 ldb ,s lda <$009F cmpa #$01 - bgt L09A9 + bgt L0A9E tfr b,a - bsr L09B3 - bcc L09A0 - leax <L09FA,pcr + bsr L0AA8 + bcc L0A94 + ldx #GrfStrt+L0AF4 stx <$00A1 - ldx $01,s - bsr L09D5 - jsr <$00BC - lbsr L091D - bra L09B1 -L09A0 ldx #$4A23 + ldx 1,s + bsr L0ACD + lbsr L017C + lbsr L0A0C + puls pc,y,x,b + +L0A94 ldx #GrfStrt+L0B1E stx <$00A1 - ldx $01,s - bsr L09D5 -L09A9 clra + ldx 1,s + bsr L0ACD +L0A9E clra tfr d,x ldb <$009F - lbsr L016A -L09B1 puls pc,y,x,b -L09B3 pshs x,b + os9 F$DelRAM Deallocate the memory +L0AA6 puls pc,y,x,b + +L0AA8 pshs x,b ldb <$0032 - beq L09CF + beq L0AC7 cmpa <$0032 - beq L09D2 + beq L0ACA ldx <$0033 -L09BF jsr <$00BC - cmpa ,x - beq L09D2 - tst ,x - beq L09CF - ldb ,x - ldx $01,x - bra L09BF -L09CF clrb + bra L0AC2 + +L0AB6 cmpa Grf.Bck,x + beq L0ACA + tst Grf.Bck,x + beq L0AC7 + ldb Grf.Bck,x + ldx Grf.Off,x +L0AC2 lbsr L017C + bra L0AB6 +L0AC7 clrb + puls pc,x,b +L0ACA comb puls pc,x,b -L09D2 comb - puls pc,x,b -L09D5 pshs u,x,b,a -L09D7 lbsr L088A - ldb <$0035 - beq L0A3D - ldx <$0036 - bra L0A33 - cmpy $05,x - bhi L0A27 - stb $01,s - stx $02,s - clrb - puls pc,u,x,b,a -L09EE tfr u,d - addd $05,u - addd <$00B5 - stx ,--s + +* Subroutine called by L0975 (of DefGPB) +* Entry: Y=Size of buffer requested (including $20 byte header) +L0ACD pshs d,x Preserve regs +L0ACF lbsr L096E initialize previous buffer ptrs to 0 ($7D-$7F) + ldb <$35 get last buffer block # + beq L0B35 If 0, exit with carry set + ldx <$36 get offset of last one into 8K block + bra L0B2E Go map in get/put memory block & continue + +* <8K buffer define vector goes here +* Entry: X=Offset to current buffer being checked in current 8K block +* Y=Size wanted +L0AE0 cmpy Grf.BSz,x Will requested size fit? + bhi L0B22 Too big, keep looking backwards + bra L0B38 Exit with carry clear & B=block #, X=offset + +L0AE7 tfr u,d + addd Grf.BSz,u + addd #Grf.Siz + IFNE H6309 + cmpr x,d + ELSE + pshs x cmpd ,s++ - rts -L09FA cmpb $01,s - bne L0A27 - ldu $02,s - ldb ,x - stb ,u - ldd $01,x - std $01,u - exg x,u - bsr L09EE - beq L0A14 - exg x,u - bsr L09EE - bne L0A27 -L0A14 stu $02,s - ldd $05,u - addd $05,x - addd <$00B5 - std $05,u -L0A1E lbsr L092D - bra L09D7 - cmpb ,s - beq L0A1E -L0A27 ldb <$008A - stb <$007D - stx <$007E - ldb ,x - beq L0A3D - ldx $01,x -L0A33 ldu $04,s - jsr <$00BC - ldu $04,s - jmp [>$00A1,u] -L0A3D comb - puls pc,u,x,b,a -L0A40 lbsr L0851 - bcs L0A54 - pshs b - ldd <$1F,y - cmpd $05,x - puls b - bls L0A61 - lbra L0AF1 -L0A54 ldd <$1F,y - std <$0080 - lbsr L0801 - bcc L0A5F - rts -L0A5F ldb <$007D -L0A61 stb <$21,y - clra - clrb - std <$0047 - ldb <$0060 - lbsr L0B36 - lbsr L0B74 - leax <$20,x - stx <$22,y - bra L0AEF -L0A78 pshs y - ldb <$21,y - stb <$0097 - jsr <$00BC - ldx <$22,y - leay >$0100,u -L0A88 ldb ,y+ - stb ,x+ - deca - beq L0A9E - cmpx #$4000 - bcs L0A88 - inc <$0097 - ldb <$0097 - jsr <$00BC - ldx <$00B7 - bra L0A88 -L0A9E puls y - ldb <$0097 - stb <$21,y - stx <$22,y - bra L0AEF -L0AAA lbsr L1DA2 - bcs L0AF4 - lbsr L1DAD - ldd ,x - subd <$00B3 - cmpd <$1B,y -L0ABA lbhi L1E44 - ldd $02,x - subd <$00B3 - cmpd <$1D,y - bhi L0ABA - jsr <$00B9 - bsr L0B16 - lbsr L0851 - bcc L0AD7 - lbsr L0801 - bcc L0AE2 - rts -L0AD7 stb <$007D - stx <$007E - ldd <$0080 - cmpd $05,x - bhi L0AF1 -L0AE2 lbsr L0B74 - lbsr L1E48 - stx <$0072 - ldx <$007E - lbsr L0B98 -L0AEF clrb + ENDC rts -L0AF1 comb - ldb #$BF -L0AF4 rts -L0AF5 ldd -$0D,y - std <$0072 - bsr L0B16 - ldd #$FFFF - std <$0057 - lbsr L0801 - bcs L0B15 - ldb <$007D - stb <$11,y - ldd <$007E - std <$12,y - bsr L0B74 - lbsr L0B98 - clrb -L0B15 rts -L0B16 pshs x - ldb <$0060 - bpl L0B23 - ldd <$004F - lslb - stb <$0009 - bra L0B25 -L0B23 bsr L0B36 -L0B25 ldb <$0009 - ldx <$0051 - lbsr L1E21 - std <$0080 - ldb <$0063 - subb <$0009 - stb <$000A - puls pc,x -L0B36 lda #$07 + +* A vectored routine (usually pointed to by $A1) +L0AF4 cmpb 1,s + bne L0B22 + ldu 2,s + ldb Grf.Bck,x + stb Grf.Bck,u + ldd Grf.Off,x + std Grf.Off,u + exg x,u + bsr L0AE7 + beq L0B0E + exg x,u + bsr L0AE7 + bne L0B22 +L0B0E stu 2,s + ldd Grf.BSz,u + addd Grf.BSz,x + addd #Grf.Siz + std Grf.BSz,u +L0B19 lbsr L0A1C + bra L0ACF +L0B1E cmpb ,s + beq L0B19 +* Search backwards through existing 8K blocks allocated for Get/Put buffers +* until we hit beginning +L0B22 ldb <$8A Get GrfDrv MMU block # for get/put buffer block + stb <$7D Move to block # + stx <$7E Save offset into block as well + ldb Grf.Bck,x Get back block link # + beq L0B35 None, exit with carry set + ldx Grf.Off,x Get back block header offset +* Entry: X=offset into current 8K buffer/block # last used for buffer +L0B2E lbsr L017C Map in Get/Put buffer memory block + jmp [>GrfMem+gr00A1] Jump to vector (can be AE0 below) + +L0B35 comb Set carry, restore regs & return + puls pc,x,d + +L0B38 stb 1,s Buffer fits, put block & offset into B & X + stx 2,s + clrb No error + puls pc,x,d Restore new regs and return + +* GPLoad entry point +L0B3F lbsr L0930 go look for group/buffer # requested + bcs L0B52 Didn't find, go create one + IFNE H6309 + ldw Wt.BLen,y Get size requested + cmpw Grf.BSz,x Will it fit in existing buffer? + ELSE + pshs d + ldd Wt.BLen,y Get size requested + std <$B5 + cmpd Grf.BSz,x Will it fit in existing buffer? + puls d + ENDC + bls L0B60 Yes, go do it + IFNE H6309 + bra L0BE4 No, exit with buffer size too small error + ELSE + lbra L0BE4 + ENDC + +L0B52 ldd Wt.BLen,y Get size requested + std <$0080 Save in grfdrv mem + lbsr L08E1 Go define a get/put buffer for ourselves + lbcs L0BE7 Couldn't find room, exit with error + ldb <$007D Get buffer block # +L0B60 stb Wt.NBlk,y Save buffer block # to GPLoad into + IFNE H6309 + clrd + ELSE + clra + clrb + ENDC + std <$47 Working X coord to 0? + ldb <$60 Get screen type +* Possible bug: doesn't check if text screen first? + lbsr L0C2B Directly into Graphics size calculation + lbsr L0C69 Go setup the GP buffer header + leax Grf.Siz,x Point past GP header (to where data would go) + stx Wt.NOff,y Save ptr to where next GPLoad will go + jmp >GrfStrt+L0F78 no errors, and exit + +* Move buffer entry point (This ONLY gets called via the Move Buffer vector +* from GRFINT or WINDINT) +* It's used to do Get/Put buffer loads in small chunks since GRFDRV's memory +* map can't fit a window's static mem +* Entry: F=Byte count (Maximum value=72 / $42) +* Y=Window table ptr +L0B79 ldb Wt.NBlk,y get block # for next graphic buffer + stb <$0097 save it + lbsr L017C go map it in + ldx Wt.NOff,y get offset into block + ldu #$1200 Point to buffer of where GRFInt/WindInt put info + IFNE H6309 + clre make 16 bit number in W + tfr w,d dupe count into D + addr x,d Point to current block offset+size of request + ELSE + clra + sta <$B5 + ldb <$B6 loaded in windint + pshs x + addd ,s++ addr x,d + ENDC + cmpa #$40 Past end of GP buffer's 8K block? + blo MoveIt No, go move whole thing in one shot +* Move data between 2 blocks of memory + ldd #$4000 calculate how much will fit in first pass + IFNE H6309 + subr x,d + subr d,w move leftover to D + exg d,w Move first chunk size to W + tfm u+,x+ move first chunk + tfr d,w move leftover back to W + ELSE + pshs x save regX + subd ,s++ subr x,d + pshs d,y save regD regY + ldd <$B5 + subd ,s subr d,w + std <$B5 this is the value of regW after tfm & tfr d,w + ldy ,s++ get counter regD after subr x,d & exg d,w + beq LMoveb +LMove lda ,u+ + sta ,x+ + leay -1,y + bne LMove +LMoveb puls y restore regY + lda <$B5 may not be needed + ENDC + inc <$0097 increment to next block # + ldb <$0097 get new block # + lbsr L017C map it in + ldx #$2000 reset pointer to start of block +MoveIt equ * + IFNE H6309 + tfm u+,x+ Block copy buffer into GP buffer + ELSE + pshs y + ldy <$B5 + beq LMove2b +LMove2 lda ,u+ + sta ,x+ + decb + leay -1,y + bne LMove2 + sty <$B5 +LMove2b puls y + ENDC +L0BA2 ldb <$0097 get the block # + stb Wt.NBlk,y update it in table + stx Wt.NOff,y save next offset in table + jmp >GrfStrt+L0F78 no errors, and exit grfdrv + +L0BE4 comb Buffer size too small error + ldb #E$BufSiz +L0BE7 jmp >GrfStrt+L0118 + +* GetBlk entry point +L0BAE lbsr L1DF6 Go scale X/Y coords @ <$47-$4A,check if in range + bcs L0BE7 No, exit with error + IFNE H6309 + ldq <$4f Get X/Y sizes + decd Bump down by 1 each since size, not coord + decw + stq <$4f Save + ELSE + ldd <$51 + subd #1 + std <$51 + std <$B5 + ldd <$4f + subd #1 + std <$4f + ENDC + lbsr L1E01 Go scale X/Y Sizes @ <$4f-$52,check if in range + bcs L0BE7 No, exit with error + IFNE H6309 + ldq <$4f Get X/Y sizes + incd Bump back up + incw + stq <$4f Save + ELSE + ldd <$51 + addd #1 + std <$51 + std <$B5 + ldd <$4f + addd #1 + std <$4f + ENDC + lbsr L0177 Map in window & setup some GRFDRV vars. + bsr L0C0B Calc width of buffer in bytes & next line offset + lbsr L0930 Go search for GP buffer + bcc L0BC9 Found it, skip ahead + lbsr L08E1 Couldn't, create one + bcc L0BD4 Got one, skip ahead + bra L0BE7 Otherwise, exit with error + +* Found GP buffer already defined +L0BC9 stb <$007D Save block # + stx <$007E Save offset into block + ldd <$0080 Get buffer length + cmpd Grf.BSz,x Within range of buffer's current length? + bhi L0BE4 No, exit with Buffer Size Too Small error +* GP buffer will fit requested data size +L0BD4 lbsr L0C69 Go set up the GP buffer's header + lbsr L1E9D Go calculate addr. on screen to start GETting @ + stx <$0072 Save it + ldx <$007E Get offset into GP buffer block + lbsr L0C8D Go copy from screen into buffer +L0BE1 jmp >GrfStrt+L0F78 exit with no errors + +* Save switch on- comes here to save screen contents under overlay window +* into a get/put buffer +* Entry: Y=Current (or current Overlay) window ptr +L0BEA ldd Wt.LStrt,y Get screen logical start address + std <$72 Make it the overlay window save start + bsr L0C0B Calculate sizes in bytes, etc. + ldd #$FFFF Group & buffer # to $FF + std <$57 + lbsr L08E1 Define get/put buffer for overlay window + bcs L0C0A Error defining buffer;exit with it + ldb <$007D Get MMU block # for overlay window copy + stb Wt.OBlk,y Save in window table + ldd <$007E Get offset into MMU block for overlay window copy + std Wt.OOff,y Save it in window table + bsr L0C69 Set up get/put buffer header + bsr L0C8D Preserve screen under overlay window + clrb No error & return +L0C0A rts + +* Setup # bytes wide overlay window is & offset to get to next line in overlay +* window when saving/restoring +* Entry: Y=Current (or current Overlay) window ptr +L0C0B ldb <$60 Get screen type + bpl L0C18 If gfx window, skip ahead + ldb <$50 Get LSB of X size of overlay window + lslb Multiply x2 (for attribute byte) + stb <$09 Save width of window (in bytes) + bra L0C1C Skip ahead + +L0C18 bsr L0C2B Calculate width info for Gfx windows + ldb <$09 Get # bytes for width of window +L0C1C lda <$52 Get height of window in bytes + mul Calculate total # bytes needed + std <$80 Preserve # bytes needed to hold saved area + ldb <$63 Get # bytes per row on screen + subb <$09 Subtract # bytes wide saved area will be + stb <$0A Store # bytes to next line after current width is done + rts Return + +* Calculate GP buffer width in bytes for graphics, & # pixels used in first & +* last bytes of each GP buffer line +* (Used by GetBlk, GPLoad, OWSet) +* Entry: B=Screen type +L0C2B lda #%00000111 2 color divide by 8 mask decb - beq L0B43 - lda #$01 - cmpb #$03 - beq L0B43 - lda #$03 -L0B43 sta <$0097 - ldb <$0048 - comb - andb <$0097 - incb - stb <$0006 - clra - cmpd <$004F - bge L0B5E - ldb <$0050 - subb <$0006 - andb <$0097 - bne L0B5E - ldb <$0097 - incb -L0B5E stb <$0007 - clra - ldb <$0048 - andb <$0097 - addd <$004F - addb <$0097 - adca #$00 -L0B6B lsra - rorb - lsr <$0097 - bne L0B6B - stb <$0009 - rts -L0B74 ldd <$004F - std $07,x - ldd <$0051 - std $09,x - ldb <$0060 - stb $0E,x - ldd <$0006 - std $0C,x - ldb <$0009 - stb $0B,x - clra - std <$004F + beq L0C38 For 640x200x2 screens + lda #%00000001 + cmpb #$03 If 320x200x16, divide by 2 mask + beq L0C38 + lda #%00000011 If any 4 color gfx window, divide by 4 mask +L0C38 sta <$97 Preserve mask for # pixels used in 1 byte + ldb <$48 Get working X coordinate LSB (0 from OWSet) + comb Make 'hole' to calculate # pixels + andb <$97 Use mask to calculate # pixels used + incb Make base 1 + stb <$06 Preserve # pixels used in 1st byte of GP line + clra D=# pixels used in last byte + cmpd <$4F More than # bytes on screen? + bge L0C53 Yes, + ldb <$50 Otherwise, get LSB of X size in bytes + subb <$06 Subtract # pixels used in first byte + andb <$97 Calculate # pixels in last byte + bne L0C53 If not 0, it is legit + ldb <$97 If it is 0, then use full byte's worth + incb +L0C53 stb <$07 Save # pixels used in last byte of GP line + clra D=# of pixels wide GP buffer is + ldb <$48 Get LSB of 'working' X coordinate + andb <$97 AND it with # pixels/byte + addd <$4F Add value to X size (in bytes) + addb <$97 Add # pixels/byte + adca #$00 Make into D register +* Divide loop: Divide by 4 for 16 color, by 8 for 4 color & by 16 for 2 color +L0C60 equ * + IFNE H6309 + lsrd Divide by 2 + ELSE + lsra + rorb + ENDC + lsr <$97 Shift right + bne L0C60 until we hit first 0 bit + stb <$09 # bytes for width of overlay window rts -L0B8C tfr y,x - lda <$0097 - sta <$000A - lda #$01 - sta <$0099 - bra L0B9A -L0B98 clr <$0099 -L0B9A pshs y - leay <$20,x - ldx <$0072 -L0BA1 lda <$0050 -L0BA3 tst <$0099 - bne L0BAD - ldb ,x+ - stb ,y+ - bra L0BB1 -L0BAD ldb ,y+ - stb ,x+ -L0BB1 cmpy #$4000 - bcs L0BBA - lbsr L0D63 -L0BBA deca - bne L0BA3 - ldb <$000A - abx - dec <$0052 - bne L0BA1 + +* Setup buffer header +L0C69 equ * + IFNE H6309 + ldq <$004F get X & Y sizes (in pixels) + stq Grf.XSz,x save it in buffer header + ELSE + ldd <$51 + std Grf.XSz+2,x + std <$B5 + ldd <$4F + std Grf.XSz,x + ENDC + ldb <$0060 get screen type + stb Grf.STY,x save it in header + ldd <$0006 Get start & end pixel masks (for uneven bytes) + std Grf.LfPx,x save them in header + ldb <$0009 Get width of buffer in bytes? + stb Grf.XBSz,x save it in header + clra D=B + std <$004F Save into working X coord + rts + +* Move get/put buffer to screen +* Entry: Y=Ptr to GP buffer? +L0C81 tfr y,x X=Ptr to GP buffer + lda <$0097 Get # bytes to start on next GP line on screen + sta <$000A Save in another spot + lda #$01 flag we're going to screen + fcb $21 skip 1 byte + +* Move get/put buffer to mem +L0C8D clra Flag we're going to memory + sta <$0099 save flag +* Move buffer to screen/mem +* Attempt reversing roles of D & W + pshs y preserve y + leay Grf.Siz,x get pointer to raw buffer data + ldx <$0072 get address of screen +L0C96 ldb <$0050 Get width count of buffer + bsr PutOneL put one line + ldb <$000A get width # bytes to start of next GP line on scrn + abx move to next line + dec <$0052 done height? + bne L0C96 no, go do next line + puls pc,y restore & return + +* put one line from a GP buffer onto the screen +PutOneL clra make 16-bit number of width of GP buffer + IFNE H6309 + tfr d,w copy it to W + addr y,d check if we will need to get next GP 8k bank + ELSE + std <$B5 + pshs y + addd ,s++ + ENDC + cmpa #$40 do we? + blo L0C98 nope, go do it + ldd #$4000 calculate # bytes we can do from this 8k bank + IFNE H6309 + subr y,d + subr d,w calculate leftover into W + exg d,w Swap for copy + ELSE + pshs y + subd ,s++ subr y,d + pshs d,u save regD & regU + ldd <$B5 get regW + subd ,s subr d,w regD now = regW + ldu ,s++ get regD + stu <$B5 exg d,w + puls u + ENDC + bsr L0C98 move first chunk + IFNE H6309 + tfr d,w Move remainder to W + ELSE + std <$B5 + ENDC + lbsr L0E70 go map in next block & reset buffer pointer + +* Move a graphics line of data +* Entry: W=# contigous bytes to move +L0C98 tst <$0099 going to screen or mem? + bne L0CA2 screen, go move it + IFNE H6309 + tfm x+,y+ Copy from screen to mem + rts + ELSE + pshs a,x,u + tfr x,u + ldx <$B5 + beq LMove3b +LMove3 lda ,u+ + sta ,y+ + leax -1,x + bne LMove3 + stx <$B5 + stu 1,s +LMove3b puls a,x,u,pc + ENDC + +L0CA2 equ * + IFNE H6309 + tfm y+,x+ Copy from mem to screen + rts + ELSE + pshs a,x,u + tfr x,u + ldx <$B5 + beq LMove4b +LMove4 lda ,y+ + sta ,u+ + leax -1,x + bne LMove4 + stx <$B5 + stu 1,s +LMove4b puls a,x,u,pc + ENDC + +* PutBlk entry point +* Entry from GRF/WINDInt: +* <$57=Group # +* <$58=Buffer # +* <$47=Upper left X coord +* <$49=Upper left Y coord +L0CBB lbsr L0177 Go map in window & setup some GRFDRV vars + lbsr L0930 search & map in get put buffer + bcs L0CF5 Error; exit with it + stb <$007D save block # of buffer + stx <$007E save offset into block buffer starts at + IFNE H6309 + ldq Grf.XSz,x Get X&Y Sizes of buffer + decd Adjust since width, not coord + decw + stq <$4F Save them + ELSE + ldd Grf.XSz+2,x + subd #1 + std <$51 + std <$B5 + ldd Grf.XSz,x + subd #1 + std <$4f + ENDC + lbsr L1DF6 Check validity/scale starting X/Y coords + bcs L0CF5 Error, exit with it + lbsr L1E01 Check validity/scale X&Y sizes + bcs L0CF5 Error; exit with it + IFNE H6309 + ldq <$4f Adjust widths back + incd + incw + stq <$4f + ELSE + ldd <$51 + addd #1 + std <$51 + std <$B5 + ldd <$4f + addd #1 + std <$4f + ENDC + lbsr L1E9D calculate screen address & start pixel mask + stx <$0072 save screen address + stb <$0074 Save start pixel mask + ldy <$007E get ptr to GP buffer + lda #$01 Flag to indicate we have to check size vs. window + bsr L0D14 Go set up start/end pixel masks & check scrn types + bcs L0CEE If screen type different or has to be clipped, go + lbsr L0D9D Screen types same & fits; do normal putting + bra L0CF4 return without error +* Get/put width buffer's original screen type being different from actual +* screen type or will go ever edge of window go here +L0CEE lbsr L0E03 ??? Do set up for screen type conversions + lbsr L0E97 Do actual PUTting +L0CF4 clrb No error & return to system +L0CF5 jmp >GrfStrt+L0118 + +* Place Overlay window's original contents back on screen +L0CF8 pshs y Preserve window table ptr + ldd Wt.LStrt,y get screen logical start address + std <$0072 Save it + IFNE H6309 + clrd + ELSE + clra + clrb + ENDC + std <$0047 'Working' X Coord to 0 + ldy <$007E Get offset to buffer + bsr L0D14 Go verify that overlay can fit back on screen + bcs L0D0F Couldn't put, exit with error + lbsr L0C81 Move get/put buffer to screen (fast put) + clrb No error & return puls pc,y -L0BC6 jsr <$00B9 - lbsr L1F65 - lbsr L0851 - bcs L0C00 - stb <$007D - stx <$007E - ldd $07,x - std <$004F - ldd $09,x - std <$0051 - lbsr L1DA2 - bcs L0C00 - lbsr L1DAD - lbsr L1E48 - stx <$0072 - stb <$0074 - ldy <$007E - lda #$01 - bsr L0C1D - bcs L0BF9 - lbsr L0CAE - bra L0BFF -L0BF9 lbsr L0D00 - lbsr L0D88 -L0BFF clrb -L0C00 rts -L0C01 pshs y - ldd -$0D,y - std <$0072 - clra - clrb - std <$0047 - ldy <$007E - bsr L0C1D - bcs L0C18 - lbsr L0B8C - clrb - puls pc,y -L0C18 comb - ldb #$BE +L0D0F comb + ldb #$BE get internal integrity check error puls pc,y -L0C1D pshs x - ldb <$0060 - cmpb $0E,y - bne L0C6C - tstb - bpl L0C30 - ldb #$FF - stb <$0000 - stb <$0001 - bra L0C61 -L0C30 tsta - beq L0C4A - ldd <$0047 - addd $07,y - subd #$0001 - cmpd <$006A - bhi L0C6C - ldb $0A,y - addb <$004A - decb - cmpb <$006D - bhi L0C6C - ldb <$0060 -L0C4A leax <L0C79-1,pcr - lda <$0048 - coma - anda b,x - inca - cmpa $0C,y - bne L0C6C - bsr L0C6F - sta <$0000 - ldd $0D,y - bsr L0C6F - stb <$0001 -L0C61 bsr L0C9D - ldb <$0063 - subb <$0050 - stb <$0097 - clrb + +* Check for common screen type between window & buffer, and check if the +* PUT will need to be clipped. If screen types different or clipping +* required, exit with carry set +L0D14 pshs x Save screen address + ldb <$0060 get screen type + cmpb Grf.STY,y Same as screen type of GP buffer's screen type? + beq GdTyp Yes, no problem so far +* 03/03/93 mod: 4 color windows will count as same type + tstb (to properly check high bit) + bmi L0D63 If text, exit with carry set + bitb #$02 Check 4 color mode bit + beq L0D63 Not a 4 color mode, so set carry & exit + IFNE H6309 + tim #$02,Grf.STY,y Check 4 color mode bit in buffer's screen type + ELSE + pshs a + lda Grf.STY,y + bita #2 + puls a + ENDC + beq L0D63 It's no a 4 color mode, so set carry & exit +GdTyp tstb graphics window? + bpl L0D27 yep, go on + ldb #$FF Group # forced to $FF (overlay window) + stb <$0000 Set right based pixel mask to all + stb <$0001 Ditto for left based + bra L0D58 Skip ahead +* Process graphics put (A=1 if straight from PutBlk,0 if from OWEnd) +* If A=1, need to see if window fits (L0D27 routine) +* If A=0, we already know it did, so we can skip size checks + +* Should change CLIPPING checks so that it just changes some DP variables +* for # bytes to print line, # bytes per line on screen & # bytes per line +* in GP buffer. That way even byte/same color mode clipped GP buffers will go +* full speed as well. +L0D27 bsr L0D94 set up <$50 = X-count, <$52 = y-count + tsta Do we already know size is legit? + beq L0D3F Yes, skip ahead +* don't bother for now to do clipping on X-boundaries, i.e. off rhs of the +* screen + ldd Grf.XSz,y size in pixels of the GP buffer + ldd <$0047 Get upper left X coord of PUT + addd Grf.XSz,y Add X size of GP buffer + cmpd <$006A past max X coord.? (i.e. 319) + bls L0D30 no, don't clip it + IFNE H6309 + decd are we overflowing by one pixel (i.e.320) + ELSE + subd #1 + ENDC + cmpd <$006A check against highest allowed X + bne L0D63 not the same, so we go clip it +L0D30 ldd Grf.YSz,y Get Y size: ATD: 16-bit, so we can check for >256! + addd <$0049 add it to upper left Y coord. ( max 199) + cmpd <$006C past max Y coord.? + blo L0D3F no, don't bother clipping it +* Y coord clipping added 03/10/96 by ATD + ldd <$006C get max. Y coord + subd <$0049 take out starting Y coord + IFNE H6309 + incd make it PUT at least one line... + ELSE + addd #1 + ENDC + stb <$52 save y-count of pixels to do + +* Divide by # pixels / byte to see if even byte boundary +L0D3F ldb <$0060 get screen type + ldx #GrfStrt+L0D70-1 Point to powers of 2 division table + lda <$0048 get LSB of X coord. + coma invert it + anda b,x Get # ^2 divisions + inca Add 1 + cmpa Grf.LfPx,y Same as # pixels used in 1st byte of GP buffer? + bne L0D63 No, set carry indicating non-even byte boundary + bsr L0D66 Go get starting/ending pixel masks + sta <$0000 Save right-based mask + ldd Grf.RtPx,y Get right based pixel mask & GP buffer type + bsr L0D66 Go get starting/ending pixel masks + stb <$0001 Save left-based pixel mask + fcb $8C skip setting up +* Text put comes here with B=Group # ($FF) for overlay windows +* Entry: B=buffer block # +L0D58 bsr L0D94 Move x-size to $50 y-size to $52 + ldb <$0063 Get # bytes/row for screen + subb <$0050 subtract LSB of X size + stb <$0097 Save width of buffer + clrb No error, restore screen address & return puls pc,x -L0C6C comb - puls pc,x -L0C6F leax <L0C7D-1,pcr - ldb b,x - abx - lsla - ldd a,x -L0C78 rts -L0C79 fcb 7,3,3,1 -L0C7D fcb L0C81-(L0C7D+1) - fcb L0C91-(L0C7D+1) - fcb L0C91-(L0C7D+1) - fcb L0C99-(L0C7D+1) +L0D63 comb Different screen types or clipping required, set + puls pc,x carry, restore screen address & return + +* Entry: B=Gfx screen type (1-4) +* A=# pixels to go in? +L0D66 ldx #GrfStrt+L0D74-1 Point to table + ldb b,x Get vector offset to proper table + abx Calculate vector + lsla 2 bytes/entry + ldd a,x Get both masks & return + rts + +* Some sort of bit mask table - appears to be used in a LSR loop after inverted +* ,will continue loop until the carried bit changes to 0 +L0D70 fcb %00000111 640x200x2 + fcb %00000011 320x200x4 + fcb %00000011 640x200x4 + fcb %00000001 320x200x16 + +* Vector table based on screen type (points to following 3 tables) +L0D74 fcb L0D78-(L0D74+1) 640x200x2 + fcb L0D88-(L0D74+1) 320x200x4 + fcb L0D88-(L0D74+1) 640x200x4 + fcb L0D90-(L0D74+1) 320x200x16 * 2 color masks (2 bytes/entry) -L0C81 fcb %00000001,%10000000 +L0D78 fcb %00000001,%10000000 fcb %00000011,%11000000 fcb %00000111,%11100000 fcb %00001111,%11110000 @@ -1555,2424 +2907,4154 @@ fcb %11111111,%11111111 * 4 color masks -L0C91 fcb %00000011,%11000000 +L0D88 fcb %00000011,%11000000 fcb %00001111,%11110000 fcb %00111111,%11111100 fcb %11111111,%11111111 - + * 16 color masks -L0C99 fcb %00001111,%11110000 +L0D90 fcb %00001111,%11110000 fcb %11111111,%11111111 - -L0C9D ldd $0A,y - stb <$0050 - sta <$0052 - rts -L0CA4 ldd <$0047 - std <$00AB - ldx <$0072 - leay <$20,y + +* Copy X Size & Y size from GP buffer header +* Entry: Y=GP buffer header ptr +L0D94 ldb Grf.XBsz,y Get X size of GP buffer in bytes + stb <$50 Save X size of GP buffer in bytes + ldb Grf.YSz+1,y Get Y size of GP buffer in bytes + stb <$52 Save Y size of GP buffer in bytes (pixels) rts -L0CAE lbsr L0E3F - pshs y - bsr L0CA4 - inc <$0097 - dec <$0050 -L0CB9 ldd <$00AB - std <$0047 - ldb <$0000 - lda <$0050 - beq L0CE8 - sta <$0099 - bra L0CC9 -L0CC7 ldb #$FF -L0CC9 lda ,y+ - lbsr L1F06 - ldd <$0047 - addb <$0005 - bcc L0CD5 - inca -L0CD5 std <$0047 - leax $01,x - cmpy #$4000 - bcs L0CE2 - lbsr L0D63 -L0CE2 dec <$0099 - bne L0CC7 - ldb <$0001 -L0CE8 lda ,y+ - lbsr L1F06 - cmpy #$4000 - bcs L0CF5 - bsr L0D63 -L0CF5 ldb <$0097 + +* Put buffer with buffer's screen type matching actual screen type +L0D9D ldb <$60 Get screen type + ldx #GrfStrt+L16B1-1 Point to table + lda b,x Get # pixels per byte for this screen type + tfr a,b Dupe for D comparison +* no PSET? + ldx #GrfStrt+L1F9E Point to 'normal' PSET vector + cmpx <$64 Is that the current one? + bne L0DBE No, use slow PUT +* no LSET? + ldx #GrfStrt+L1FA9 Point to 'normal' LSET vector + cmpx <$68 Is that the current one? + bne L0DBE Yes, can use TFM PUT +* no even byte boundary? + cmpd Grf.LfPx,y Even byte boundary on both left & right sides? + lbeq L0C81 yes, go do fast TFM put +* odd pixel boundaries: do 1st pixel slow, use TFM for the rest + sta <$0099 flag we're copying to the screen + ldd <$00 masks for pixels to keep from GP buffer + IFNE H6309 + comd + ELSE + coma + comb + ENDC + std <$20 masks for pixels to keep from screen + ldx <$0072 get start address for PUT + leay $20,y skip GP buffer header +* do first byte of the line: almost a complete TFM +Put.ATFM lda ,x grab first byte + anda <$20 get only pixels we want to keep + ldb ,y grab pixels from GP buffer + andb <$00 get the ones we want to keep + IFNE H6309 + orr b,a OR the pixels together + ELSE + pshs b + ora ,s+ + ENDC + sta ,y save in the GP buffer + ldd <$4F get width of GP buffer in bytes + IFNE H6309 + decd account for 0th byte + ELSE + subd #1 + ENDC + lda d,x get right hand byte from the screen + pshs a save end byte + IFNE H6309 + incd + ELSE + addd #1 + ENDC + lbsr PutOneL blast it over using TFM +* do the last byte of the line +* this kludge is necessary because doing it the proper way would add a LOT +* of code to check for GP buffer 8k block boundaries. It won't be noticed +* except for really large PutBlks. Oh well. + lda <$0001 get end pixel mask + anda -1,x keep only the pixels we want + ldb <$0021 inverted mask + andb ,s+ AND in with original screen data + IFNE H6309 + orr b,a OR in the pixel we put on the screen + ELSE + pshs b + ora ,s+ + ENDC + sta -1,x save it + ldb <$0097 get width of the screen + abx go to the next line + dec <$52 count down one line + bne Put.ATFM + rts + +* Either not even byte, or PSET/LSET or not defaults:use slow PUT +L0DBE sta <$05 Save # pixels/byte + pshs y Save Get/Put buffer ptr + ldu <$64 Get PSET vector + IFNE H6309 + ldw <$68 Get LSET vector (for PSET routine) + ELSE + ldx <$68 + stx <$B5 + ENDC + leay <$20,y Skip buffer header + ldx <$72 Get address of where to start PUTting on scrn + inc <$97 Save # bytes to start of next line GP buffer + dec <$50 Adjust X byte count down for base 0 +* Loop from here to end of L0DFA - Move Get/Put buffer onto screen using LSET +* logic. +* This outside part does the 1st byte's worth of pixels +* NOTE: X=ptr to current byte being done on screen +* Y=ptr to current byte being done in GP buffer +L0DCB ldb <$00 Get pixel mask for 1st byte of 1st line in buffr + lda <$50 Get LSB of X size + beq L0DED If 0, just 1 byte to do - use last byte routine + sta <$99 Save LSB of X size +* This part does all the full-byte pixels +L0DD5 ldb #$FF Mask byte- all bits +L0DD7 lda ,y+ Get bits to set from GP buffer + jsr ,u Put on screen + ldb #1 Screen ptr bump count + abx Bump screen ptr + cmpy #$4000 Done current 8K block of Get/put buffer? + blo L0DE7 No, continue normally + lbsr L0E70 Yes, go map in next block +L0DE7 dec <$99 Dec X byte count + bne L0DD5 Continue moving until done X size +* This part does the last byte's worth of pixels + ldb <$01 Get pixel mask for last byte of last line +L0DED lda ,y+ Get last byte for current line in GP buffer + jsr ,u Put it on screen + cmpy #$4000 Done 8K block yet? + blo L0DFA No, skip ahead + lbsr L0E70 Yes, go map in next block +L0DFA ldb <$0097 Get # bytes to beginning of next line + abx Point to start of next line + dec <$0052 Dec # of lines counter + bne L0DCB Continue putting until done + puls pc,y Restore GP buffer ptr & return + +* Put buffer with buffer's screen type different than original +L0E03 pshs y Save GP buffer ptr? + ldd <$006A Get max. allowed X coordinate + subd <$0047 Subtract working X coordinate + IFNE H6309 + incd Base 1 + ELSE + addd #1 + ENDC + std <$009B Save width of some sort + ldb <$006D Get max. allowed Y coordinate + subb <$004A Calc height of some sort + incb Make base 1 + bra L0E2F Save it + +i.iwtyp comb + ldb #E$IWTyp + jmp >GrfStrt+L0118 + +* Called from Mouse cursor routine @ L15FE +L0E14 pshs y Preserve GP buffer ptr + ldd #320 Default res to 320 (Base 1) + IFNE H6309 + tim #$01,<$60 Get res bit from screen type + ELSE + pshs a + lda <$60 + bita #1 + puls a + ENDC + beq L0E24 It is 320 mode, skip ahead + IFNE H6309 + lsld Multiply by 2 to get 640 + ELSE + lslb + rola + ENDC + +L0E24 subd <$3D Subtract last X coord Gfx cursor was ON at + std <$009B Save # pixels to end of screen + ldb #MaxLine+1 Full height of screen + subb <$0040 Calculate # pixels remaining + +L0E2F stb <$00A0 Save it + lbsr L1EF1 Setup pix mask & shift vector ($79 & $7A) + lbsr L0D94 Set up element X&Y sizes (in bytes) +* B=Height of GP buffer (also in <$52) in bytes + cmpb <$00A0 Compare with room left on window Y axis + bls FullSz + ldb <$00A0 Get remaining # lines on window + stb <$0052 Save as our single counter of lines left +FullSz ldd Grf.LfPx,y Get # pixels used in 1st byte & last byte + std <$0006 Save them + ldx #GrfStrt+L075F-1 Point to color mask table index + ldb <$0060 Get screen type +* ATD: Added to get around problem of GetBlk on text screen, and PutBlk +* on gfx screen crashing the system! +* We now allow GETBlk and PutBlk on text screens, too! + eorb Grf.STY,y EOR with buffer sty type + bmi i.iwtyp exit IMMEDIATELY if mixing text and gfx puts + ldb <$0060 get screen type again + ldb b,x Calc. offset to proper color mask table abx - inc <$004A - dec <$0052 - bne L0CB9 - puls pc,y -L0D00 pshs y - ldd <$006A - subd <$0047 - addd <$00B3 - std <$009B - ldb <$006D - subb <$004A - bra L0D27 -L0D10 pshs y - lda <$0060 - lsra - ldd #$027F - bcs L0D1D - ldd #$013F -L0D1D subd <$003D - addd <$00B3 - std <$009B - ldb #$BF - subb <$0040 -L0D27 incb - stb <$00A0 - lbsr L1E9C - lbsr L0C9D - ldd $0C,y - std <$0006 - lbsr L06A4 + lda ,x+ Get active bits mask (0001, 0011 or 1111) + stx <$0002 Save base of color mask table + ldx #GrfStrt+L0E7C-1 Point to index for pixel tables + ldb Grf.STY,y Get GP buffers original screen type + ldb b,x Calc ptr to proper pixel table abx - lda ,x+ - stx <$0002 - leax <L0D6D-1,pcr - ldb $0E,y - ldb b,x - abx - ldb ,x - leay b,x - sty <$00A3 - anda $01,x - sta <$0008 - ldb $02,x - stb <$0005 - ldb <$0006 - addb #$02 - ldb b,x - leay b,x + ldb ,x Get offset for default shift? + leay b,x Get vector for 4, 2 or 1 shift + sty <$00A3 Save it + anda 1,x And bit mask from scrn with bit mask from GP bfr + sta <$0008 Save it + ldb 2,x Get # pixels/byte for GP buffer type + stb <$0005 Save it + ldb <$0006 Get # pixels used in 1st byte of GP buffer line + addb #$02 Adjust up to skip bit mask & # pixels/byte + ldb b,x Get offset + leay b,x Save vectors for bit shifts sty <$00A1 sty <$00A5 - puls pc,y -L0D63 inc <$007D - ldb <$007D - jsr <$00BC - ldy <$00B7 -L0D6C rts + puls pc,y Restore GP buffer ptr & return? + +* Get next 8K block of get/put buffers +* Exit: Y=Ptr to start of block ($2000) +L0E70 inc <$007D Increment buffer block # + ldb <$007D Get it + lbsr L017C Go map in next block in get/put buffer + ldy #$2000 Y=Ptr to start of GP buffer block + rts * Index to proper tables for GP buffer's original screen types -L0D6D fcb L0D71-(L0D6D-1) Type 5 (2 color) - fcb L0D7C-(L0D6D-1) Type 6 (4 color) - fcb L0D7C-(L0D6D-1) Type 7 (4 color) - fcb L0D83-(L0D6D-1) Type 8 (16 color) +L0E7C fcb L0E80-(L0E7C-1) Type 5 (2 color) + fcb L0E8B-(L0E7C-1) Type 6 (4 color) + fcb L0E8B-(L0E7C-1) Type 7 (4 color) + fcb L0E92-(L0E7C-1) Type 8 (16 color) * All of following tables' references to pixel # are based on 1 being the * far left pixel in the byte * Vector table for GP buffer's taken from 2 color screens -L0D71 fcb L0DD3-L0D71 <$00A3 vector +L0E80 fcb L0EE0-L0E80 <$00A3 vector fcb %00000001 Bit mask for 1 pixel fcb 8 # pixels /byte - fcb L0DD4-L0D71 Shift for 1st pixel - fcb L0DCD-L0D71 Shift for 2nd pixel - fcb L0DCE-L0D71 Shift for 3rd pixel - fcb L0DCF-L0D71 Shift for 4th pixel - fcb L0DD0-L0D71 Shift for 5th pixel - fcb L0DD1-L0D71 Shift for 6th pixel - fcb L0DD2-L0D71 Shift for 7th pixel - fcb L0DD3-L0D71 Shift for 8th pixel + fcb L0EE1-L0E80 Shift for 1st pixel + fcb L0EDA-L0E80 Shift for 2nd pixel + fcb L0EDB-L0E80 Shift for 3rd pixel + fcb L0EDC-L0E80 Shift for 4th pixel + fcb L0EDD-L0E80 Shift for 5th pixel + fcb L0EDE-L0E80 Shift for 6th pixel + fcb L0EDF-L0E80 Shift for 7th pixel + fcb L0EE0-L0E80 Shift for 8th pixel * Vector table for GP buffer's taken from 4 color screens -L0D7C fcb L0DD2-L0D7C <$00A3 vector +L0E8B fcb L0EDF-L0E8B <$00A3 vector fcb %00000011 Bit mask for 1 pixel fcb 4 # pixels/byte - fcb L0DD4-L0D7C Shift for 1st pixel - fcb L0DCE-L0D7C Shift for 2nd pixel - fcb L0DD0-L0D7C Shift for 3rd pixel - fcb L0DD2-L0D7C Shift for 4th pixel + fcb L0EE1-L0E8B Shift for 1st pixel + fcb L0EDB-L0E8B Shift for 2nd pixel + fcb L0EDD-L0E8B Shift for 3rd pixel + fcb L0EDF-L0E8B Shift for 4th pixel * Vector table for GP buffer's taken from 16 color screens -L0D83 fcb L0DD0-L0D83 <$00A3 vector +L0E92 fcb L0EDD-L0E92 <$00A3 vector fcb %00001111 Bit mask for 1 pixel fcb 2 # pixels/byte - fcb L0DD4-L0D83 Shift for 1st pixel - fcb L0DD0-L0D83 Shift for 2nd pixel - -L0D88 lbsr L0CA4 - pshs y -L0D8D stx <$0072 - ldd <$00AB - std <$0047 - ldd <$009B - std <$009D - lda <$0050 - sta <$0004 - ldb <$0006 - stb <$0097 - ldd <$00A5 - std <$00A1 - ldb <$0074 -L0DA5 ldy ,s - cmpy #$4000 - bcs L0DB4 - stb <$0099 - bsr L0D63 - ldb <$0099 -L0DB4 lda ,y+ - sty ,s - ldy <$0002 - pshs y - leay <L0DD4,pcr - cmpy <$00A1 - puls y - beq L0DD4 - lsla - jmp [>$00A1,u] -L0DCD rola EDA -L0DCE rola EDB -L0DCF rola EDC -L0DD0 rola EDD -L0DD1 rola EDE -L0DD2 rola EDF -L0DD3 rola EE0 -L0DD4 pshs b,a,cc - ldd <$009D - beq L0DEC - subd <$00B3 - std <$009D - ldd $01,s - anda <$0008 - lda a,y - lbsr L1F06 - lbsr L1EB3 - stb $02,s -L0DEC dec <$0097 - beq L0DF6 - puls b,a,cc - jmp [>$00A3,u] -L0DF6 leas $03,s - dec <$0004 - beq L0E12 - lda <$0004 - cmpa #$01 - beq L0E06 - lda <$0005 - bra L0E08 -L0E06 lda <$0007 -L0E08 sta <$0097 - ldy <$00A3 - sty <$00A1 - bra L0DA5 -L0E12 ldx <$0072 - ldb <$0063 - abx - dec <$00A0 - beq L0E23 - inc <$004A - dec <$0052 - lbne L0D8D -L0E23 puls pc,y -L0E25 lbsr L0851 - bcs L0E9F - stb <$0097 - ldb $0F,x - stb <$0099 - ldd $05,x - std <$009B - leax <$20,x - tfr x,d - anda #$1F - std <$009D - bra L0E9E -L0E3F ldb <$0060 - leax >L15C3,pcr - lda b,x - tfr a,b - cmpd $0C,y - bne L0E63 - leax >L1F83,pcr - cmpx <$0064 - bne L0E63 - leax >L1F9A,pcr - cmpx <$0068 - bne L0E63 - leas $02,s - lbra L0B8C -L0E63 sta <$0005 - rts -L0E66 ldb <$2A,y - rorb - bcc L0E6E - clrb - rts -L0E6E lbsr L0107 - tsta - bpl L0E8E - cmpa #$BF - bhi L0E84 - anda #$EF + fcb L0EE1-L0E92 Shift for 1st pixel + fcb L0EDD-L0E92 Shift for 2nd pixel + +L0E97 leay Grf.Siz,y Skip GP buffer header + pshs y Save ptr to raw GP buffer data + ldx <$0072 Get ptr to start of buffer placement on screen + ldu <$64 Get PSET vector for main loop @ L0EE1 + fcb $8C skip 2 bytes: same cycle time, 1 byte shorter + +L0E9E stx <$0072 Save get/put screen start address +L0EA0 ldd <$009B ??? x-count to do + std <$009D ??? + lda <$0050 Get LSB of X size (in bytes) + sta <$0004 Save # bytes left in width (including partials) + ldb <$0006 Get # of pixels used in 1st byte of GP line + stb <$0097 Save as # pixels left to do in current byte + ldd <$00A5 Get A5 vector + std <$00A1 Save as A1 vector + ldb <$0074 Get pixel mask for 1st byte of GP buffer on scrn + IFNE H6309 + ldw <$68 Get LSET vector + ELSE + ldy <$68 + sty <$B5 + ENDC + +L0EB2 ldy ,s Get buffer data ptr + cmpy #$4000 At end of 8K block yet? + blo L0EC1 No, continue + stb <$0099 Save B + bsr L0E70 Go map in next 8K block + ldb <$0099 Restore B +L0EC1 lda ,y+ Get byte of data from GP buffer + sty ,s Save updated buffer ptr + ldy #GrfStrt+L0EE1 Check if <$A1 vector points here + cmpy <$00A1 no shifting of bits? + beq L0ED6 It does, call vector + lsla Doesn't, shift buffer data left 1 first +L0ED6 ldy <$0002 Get ptr to table of bit masks for colors + jmp [>GrfMem+gr00A1] Place byte from GP buffer on screen + +* Bit shifter for adjusting pixel placements in non-aligned, possible differ- +* ent screen type, Get/put buffers +* Entry: W=LSET vector (for use with <$64,u vector) +L0EDA rola Adjust pixel to proper place in byte +L0EDB rola +L0EDC rola +L0EDD rola +L0EDE rola +L0EDF rola +L0EE0 rola +L0EE1 pshs cc,d Save carry & pixel/color masks + ldd <$009D ??? Get some sort of counter (X width?) + beq L0EFA If 0, skip ahead + IFNE H6309 + decd Drop it down + ELSE + subd #1 + ENDC + std <$009D Save it + ldd 1,s Get pixel/color masks back + anda <$0008 Mask out all but common bits of screen/buffer types + lda a,y Get proper color bit mask + jsr ,u Put pixel on screen + ldb 2,s Restore original pixel bit mask + lbsr L1F0E B=New pixel mask, X=new scrn addr. (if chng) + stb 2,s Save pixel mask for next pixel +L0EFA dec <$0097 Dec # pixels left in current byte + beq L0F04 Done byte, skip ahead + puls d,cc Restore pixel/color masks & carry + jmp [>GrfMem+gr00A3] Call vector + +* Current byte's worth of pixels done: set up next byte +L0F04 leas 3,s Eat stack + lda <$0004 Get # bytes wide GP buffer is + deca Decrement it + beq L0F20 If totally done buffer width, go to next line + sta <$0004 Save new total + deca If only 1, set up for partially used last byte + beq L0F14 + lda <$0005 Get # pixels/byte in GP buffer for full byte + fcb $8C skip 2 bytes: same cycle time, 1 byte shorter + +L0F14 lda <$0007 Get # pixels to do in last (partial) byte of bfr +L0F16 sta <$0097 Save # pixels to do in next byte + ldy <$00A3 Move last byte partial vector to normal + sty <$00A1 so we can use same routines + bra L0EB2 Go finish off the last byte + +* Done current line of GP buffer, set up for next line +L0F20 ldx <$0072 Get screen addr of current line in GP buffer + ldb <$0063 Get # bytes/row on screen + abx Point to start of next line on screen + dec <$0052 Dec # lines left on window / GP buffer + lbne L0E9E If not bottom, continue PUTting + puls pc,y As far as we can go, restore Y & return + +* Map GP buffer entry point +L0F31 lbsr L0930 find the buffer + lbcs L0118 If error, exit back to system with it + stb <$0097 save starting block number + ldb Grf.NBlk,x number of blocks in the buffer + stb <$0099 save count + ldd Grf.BSz,x size of data inside the buffer + std <$009B save size of the buffer + leax Grf.Siz,x point to the start of the buffer data itself + tfr x,d move into math register + anda #$1F keep offset within the block + std <$009D save offset + lbra L0F78 exit with no error + +* ATD: this special-purpose text routine results in gfx screens being +* marginally slower, but it saves ~170 clock cycles per character put +* on a gfx screen. + +fast.set dec <$0083 account for the first character we printed out +* reset the various parameters after falling off the rhs of the screen +fast.txt puls u restore pointer to our fast text + IFNE H6309 + ldw Wt.CurX,y move current X position into W + ELSE + ldx Wt.CurX,y + stx <$B5 + ENDC + ldx Wt.Cur,y get current cursor address on the screen + ldb Wt.Attr,y grab current attributes +ftxt.lp lda ,u+ get a character + lbsr txt.fixa fix A so it's printable + lbsr L0F7C.0 do more text screen fixes, and STD ,X++ + IFNE H6309 + incw right one character BEFORE counting down + ELSE + pshs x + ldx <$B5 + leax 1,x + stx <$B5 + puls x + ENDC + dec <$83 count down + beq ftxt.ex exit if it's zero: we're done here + IFNE H6309 + cmpw Wt.MaxX,y are we at the rhs of the screen? + ELSE + pshs x + ldx <$B5 + cmpx Wt.MaxX,y + puls x + ENDC + bls ftxt.lp no, continue doing fast text put + pshs u save text pointer + lbsr L1238 zero out X coord, do scroll, etc + bra fast.txt and go reset out parameters + +ftxt.ex equ * + IFNE H6309 + cmpw Wt.MaxX,y Are we at the right hand side of the screen? + ELSE + pshs x + ldx <$B5 + cmpx Wt.MaxX,y + puls x + ENDC + bls NoScroll No, exit normally + lbsr L1238 Do scroll stuff + IFNE H6309 + clrw Zero out current X coord + ELSE + clr <$B5 + clr <$B6 + ENDC +NoScroll equ * + IFNE H6309 + stw Wt.CurX,y save current X coordinate + ELSE + pshs x + ldx <$B5 + stx Wt.CurX,y + puls x + ENDC + lbsr L11D1 set up for the next call + lbra L0F78 exit without error + +* entry: A = number of characters at $0180 to write +* Y = window table pointer +fast.chr ldx #$0180 where the data is located +* ATD: $83 is unused by anything as far as I can tell. + sta <$83 save count of characters to do for later + lda ,x+ get the first character + pshs x save address of character + lbsr L0F4B.1 ensure window is set up properly during 1st chr. +* perhaps the DEC <$83 could be here... remove FAST.SET, and fix f1.do + + lda <$60 is it a text screen? + bmi fast.set yes, make it _really_ fast + + ldb <$006F get X size of font + cmpb #$08 Even byte wide size font? + IFNE H6309 + bne f1.do no, go setup for multi-color/shiftable screen + ELSE + lbne f1.do + ENDC + ldx <$B0 get cached font pointer + IFNE H6309 + beq f1.do didn't find a font: skip ahead + tim #Prop,<$E Proportional? + ELSE + lbeq f1.do + pshs a + lda <$E + bita #Prop + puls a + ENDC + bne f1.do yes, use slow method + +* OK. Now we have GFX screens only here, at least one character printed +* to ensure that the buffers etc. are set up and mapped in. We can now go to +* special-purpose routine for fixed-width 8x8 fonts: ~15% speedup! + ldd Grf.BSz,x + leax Grf.Siz,x point X to the first character in the font + leau d,x point U to the absolute end-address of the font +* Moved the DP saves from $B2 to $B9; RG + stu <$B9 save the pointer for later + clra + ldb Wt.CWTmp,y get bytes per font character + std <$BB + ldd Wt.MaxX,y get maximum X position (e.g. 319, 639) + IFNE H6309 + incd count up one + ELSE + addd #1 + ENDC + subd #$0008 point D to the last X position possible for + std <$BD a character, and save it + +* Note: W *SHOULD* be set up properly from the previous call to print one +* character, but that character might have caused the text to wrap, and thus +* destroy W + ldu #GrfStrt+Fast.pt-2 point to fast font put table + ldb <$0060 get screen type + aslb 2 bytes per entry + IFNE H6309 + ldw b,u grab pointer to routine to use + ELSE + pshs x + ldx b,u + stx <$B5 + puls x + ENDC + puls u restore character pointer + bra f2.do jump to the middle of the loop + +* U = pointer to characters to print +* Y = window table pointer +* X = font GP buffer pointer +f2.next lda ,u+ grab a character + pshs x,y,u save all sorts of registers + bsr txt.fixa fix the character in A so it's printable + tfr a,b move character to B + clra make 16-bit offset + IFNE H6309 + lsld ALL fonts are 8 pixels high + lsld + lsld + addr d,x point to the font data + ELSE + lslb + rola + lslb + rola + lslb + rola + leax d,x + ENDC + cmpx <$B9 are we within the font's memory buffer? + blo f2.fnt yes, we're OK + ldx #GrfStrt+L0FFA otherwise point to default font character '.' + +f2.fnt lbsr L102F.1 go print the character on the screen + ldy 2,s get window pointer again + ldd Wt.Cur,y get current cursor address + addd <$BB add in bytes per character + std Wt.Cur,y + ldd Wt.CurX,y Get X coordinate + addd #$0008 Add to X pixel count (1, 6 or 8?) + std Wt.CurX,y Update value + cmpd <$BD Compare with maximum X coordinate + bls f2.do1 If not past right hand side, leave + IFNE H6309 + pshsw save pointer to which font-put routine to use + ELSE + pshs x,y + ldx <$B5 + stx 2,s + puls x + ENDC + lbsr L1238 fix X,Y coordinate, scroll screen, set up bitmasks + IFNE H6309 + pulsw + ELSE + ldx ,s++ + stx <$B5 + ENDC +f2.do1 puls x,y,u restore registers +f2.do dec <$83 count down + bne f2.next continue + bra L0F78 and exit if we're all done + +f1.next lda ,x+ + pshs x + bsr L0F4B.2 put one character on the screen +f1.do puls x restore count, pointer + dec <$83 count down + bne f1.next continue + bra L0F78 and exit if we're all done + +* L0F4B.1 is now a subroutine to put one character on the screen... +* Alpha put entry point +* Entry: A = Character to write +* Y = window table ptr +* 07/19/93: LBSR L0177 to L0175 +L0F4B.1 lbsr L0175 Switch to the window we are writing to + lbsr L1002 set up character x,y sizes and font pointers + sty <$A9 Save window tbl ptr from this Alpha put + tsta Is the character ASCII 127 or less? +L0F4B.2 bsr txt.fixa fix A: adds 10 cycles for slow puts and gfx puts + + ldb <$0060 Get screen type + bpl L0F73 If gfx screen, go do it + bsr L0F7C go print it on-screen + fcb $8C skip the next 2 bytes +L0F73 bsr L0FAE go print graphic font +L0F75 lbra L121A check for screen scroll and/or next line + +* L.C.B - Add a flag that signifies that we are doing a GFX font, and that the +* font buffer size is $700 bytes. If this flag is set at entry to this +* routine (after bpl), return to print it. +txt.fixa bpl L0F6B Yes, go print it + tst <grBigFnt Gfx mode with a 224 char font? + beq Norm No, do normal remapping + cmpa #$e0 Last 31 chars? + blo BigOut No, exit + suba #$e0 Point to 1st 31 chars in font +BigOut rts + +Norm cmpa #$BF + bhi L0F61 Anything >=$C0 gets wrapped back + anda #$EF Mask out high bit suba #$90 cmpa #$1A - bcc L0E8E -L0E80 lda #$2E - bra L0E8E -L0E84 anda #$DF + bhs L0F6B yes, go print it +L0F5D lda #'. Change illegal character to a period + rts + +L0F61 anda #$DF suba #$C1 - bmi L0E80 + bmi L0F5D yes, change it to a period cmpa #$19 - bhi L0E80 -L0E8E ldb <$0060 - bpl L0E96 - bsr L0EA0 - bra L0E9B -L0E96 lbsr L13FB - bsr L0EDE -L0E9B lbsr L10D0 -L0E9E clrb -L0E9F rts -L0EA0 cmpa #$60 - bne L0EA6 - lda #$27 -L0EA6 cmpa #$5F - bne L0EAC - lda #$7F -L0EAC cmpa #$5E - bne L0EB2 - lda #$60 -L0EB2 ldx -$05,y - tst $09,y - bmi L0EC6 - ldb $01,x - andb #$07 - stb $01,x - ldb $08,y - andb #$F8 - orb $01,x - bra L0EC8 -L0EC6 ldb $08,y -L0EC8 std ,x - ldd <$00B3 - std <$006E - std <$0070 - cmpy <$002E - bne L0EDD - sta <$0039 - ldb >$1000 - stb >$1001 -L0EDD rts -L0EDE pshs y,a - ldb $09,y - stb <$000E - bitb #$04 - beq L0EEE - ldd <$0061 - exg a,b - std <$0061 -L0EEE bsr L0F31 - bcs L0EFC - lda ,s - ldb $0B,x - mul - cmpd $05,x - bcs L0F01 -L0EFC leax <L0F29,pcr - bra L0F05 -L0F01 addd <$00B5 + bhi L0F5D yes, change it to a period +L0F6B rts + +* this adds 10 cycles to any normal alpha put, but it should +* save us lots of cycles later! +L0F4B bsr L0F4B.1 do internal alpha-put routine + +* Return to the system without any errors +L0F78 clrb No errors + +* Return to system (Jumps to [D.Flip0] with X=system stack ptr & A=CC status) +L0118 tfr cc,a save IRQ status for os9p1 + orcc #IntMasks Shut off interrupts + ldx >WGlobal+G.GrfStk Get system stack ptr + clr >WGlobal+G.GfBusy Flag that Grfdrv will no longer be task 1 + IFNE H6309 + tfr 0,dp Restore system DP register for os9p1 + ELSE + pshs a + clra + tfr a,dp + puls a + ENDC + jmp [>D.Flip0] Return to system + +* Print text to hardware text - optimized for lowercase, then upper +* Can be switched around by swapping blo/bhi sections +L0F7C ldb Wt.Attr,y + ldx Wt.Cur,y +L0F7C.0 cmpa #$60 Convert ASCII reverse apostrophe to apostrophe + bhi L0F8E Above is safe, go straight to print + bne L0F88 No, try next + lda #$27 GIME apostrophe + bra L0F8E Skip rest +L0F88 cmpa #$5E Convert ASCII carat to GIME carat + blo L0F8E Below is safe, go straight to print + bne L0F82 No, has to be Underscore + lda #$60 GIME carat + fcb $8C skip 2 bytes: same cycle time, 1 byte shorter + +L0F82 lda #$7F Convert ASCII underscore to GIME underscore +* ATD: the back of the window OS-9 manual says that the transparent character +* switch is supported only on gfx screens, so we don't support it here! +*L0F8E ldx Wt.Cur,y get cursor address on screen +* ldb Wt.Attr,y get attributes from the window table +* tst Wt.BSW,y transparent characters? +* bmi L0FA4 no, go on +* IFNE H6309 +* aim #$07,1,x mask off everything but background attributes +* ELSE +* pshs a +* lda 1,x +* anda #7 +* sta 1,x +* puls a +* ENDC +* andb #$F8 get rid of background color +* orb 1,x merge in background color +L0F8E std ,x++ save character & attribute to screen + rts Check for screen scroll/new line + +* Print text to graphics window +* Note: $61 & $62 contain the bit masks for the foreground & background colors +* for the whole width of the byte (ex. a 2 color would be a $00 or $ff) +L0FAE pshs a,y Preserve character to print & Window table ptr + ldb Wt.BSW,y get current attributes + stb <$000E save 'em for quicker access + bitb #Invers inverse on? + beq L0FBE no, go on +* 07/20/93 mod: Get colors from window table instead of GRFDRV mem for speedup + ldd Wt.Fore,y Get fore/back colors + exg a,b exchange 'em + std <$0061 save 'em back +L0FBE ldx <$00B0 get cached font pointer + beq L0FCC if none, point to '.' font character + ldb Grf.XSz+1,x get x-size of the font + stb <$006F save here again: proportional fonts destroy it + lda ,s grab again the character to print +* ATD: is this next line really necessary? The code at L064A ENSURES that +* Grf.XBSz = Grf.YSz = $08, so this next line could be replaced by a LDB #8 + ldb Grf.XBSz,x get size of each buffer entry in bytes + mul Calculate offset into buffer for character + cmpd Grf.BSz,x Still in our buffer? (Not illegal character?) + blo L0FD1 yes, go on +L0FCC ldx #GrfStrt+L0FFA Point to default font char ('.') + bra L0FD6 + +L0FD1 addd #Grf.Siz Add 32 (past header in Gfx buffer table?) + IFNE H6309 + addr d,x Point to the character within buffer we need + ELSE leax d,x -L0F05 ldb <$0060 - cmpb #$01 - bne L0F1B - ldb <$006F - cmpb #$08 - bne L0F1B - ldb <$000E - bitb #$10 - bne L0F1B - bsr L0F5C - bra L0F27 -L0F1B leay >L100B,pcr - sty <$00A9 - ldy $01,s - bsr L0F9A -L0F27 puls pc,y,a -L0F29 fdb 0 - fdb 0 - fdb 0 - fdb $1000 -L0F31 pshs a - ldb <$60 - bpl L0F3F - ldd <$00B3 - std <$006E - std <$0070 - bra L0F5A -L0F3F ldb $0B,y - bne L0F4D - ldd #$0008 + ENDC +L0FD6 ldb <$006F get X size of font + cmpb #$08 Even byte wide size font? + bne L0FEC no, go setup for multi-color/shiftable screen + IFNE H6309 + tim #Prop,<$E Proportional? + ELSE + pshs a + lda <$E + bita #Prop + puls a + ENDC + beq L102F no, use fast method +* Setup for multi-color/shiftable gfx text +L0FEC ldu #GrfStrt+L10DF Normal gfx text vector + ldy 1,s get window table pointer back + lbsr L106D go print it +L0FF8 puls a,y,pc return + +* Default font character if no font buffer defined ('.') +L0FFA fcb %00000000 + fcb %00000000 + fcb %00000000 + fcb %00000000 + fcb %00000000 + fcb %00000000 + fcb %00010000 + fcb %00000000 + +* Check if font buffers defined? +L0FFF lbsr L0177 +L1002 pshs a save character + ldb <$0060 get STY marker + bpl L1011 graphics, go on +* Set text font H/W + ldd #$0001 get text font size std <$006E std <$0070 - comb - bra L0F5A -L0F4D jsr <$00BC - ldx $0C,y - ldd $07,x - std <$006E - ldd $09,x - std <$0070 - clrb -L0F5A puls pc,a -L0F5C ldy -$05,y - exg x,y - lda <$0071 - deca - sta <$0097 -L0F66 lda ,y+ - ldb <$000E - bitb #$20 - beq L0F71 - lsra - ora -$01,y -L0F71 tfr a,b - coma - tst <$000E - bmi L0F7C +* Added LCB 97/05/26 for 224 char font support + sta <grBigFnt Flag that this is not a 224 char font + puls a,pc larger, but faster than LDQ/bra L1022 + +* Set undefined graphics font H/W +* L100F is ONLY called from alpha put routine, above. +L100F pshs a Preserve A (so PULS PC,A works) +L1011 ldb Wt.FBlk,y any font defined? + bne L101F yes, go map it in & get X/Y sizes + comb set carry + IFNE H6309 + ldq #$00080008 get default width & height + tfr 0,x make garbage font ptr + ELSE + ldd #8 + std <$B5 + ldx #0 + ENDC + bra L1020 + +* Setup defined graphics font H/W +L101F lbsr L017C map in font block + ldx Wt.FOff,y get offset of font in mem block + clrb clear carry + IFNE H6309 + ldq Grf.XSz,x Get width & height from window table + ELSE + ldd Grf.XSz+2,x + std <$B5 + ldd Grf.XSz,x + ENDC +L1020 stx <$B0 cache font pointer for later +L1022 equ * + IFNE H6309 + stq <$6e Set working copies + ELSE + std <$6e + ldd <$B5 + std <$70 + ENDC +* LCB 05/25/97 - Added flag for 224 char fonts + ldd #$700 Size of font we are checking for + cmpd Grf.BSz,x Is this a big font? + bne NotBig + incb Flag it is a big font +NotBig stb <grBigFnt Set flag for 224 char font + puls a,pc return + +L102F bsr L102F.2 + bra L0FF8 + +* fast draw a graphic font character to a graphics window +* If inverse was selected, they have already been swapped +* Note: <$61 contains the foreground color mask, <$62 contains the background +* color mask. +* Entry: Y=window table pointer +* X=Ptr to char in font we are printing +L102F.2 ldu #GrfStrt+Fast.pt-2 point to fast font put table + ldb <$0060 get screen type + aslb 2 bytes per entry + IFNE H6309 + ldw b,u grab pointer to routine to use + ELSE + pshs x + ldx b,u + stx <$B5 + puls x + ENDC + +L102F.1 ldy Wt.Cur,y get cursor address on screen + exg x,y Swap Cursor address & font address + + ldu #GrfStrt+fast.tbl point to table of expanded pixels + + lda <$71 get font height + deca adjust it for double branch compare + sta <$20 save in temp buffer for later + +L1039 lda ,y+ get a line of character (8 pixels) + IFNE H6309 + tim #Bold,<$0E Bold attribute on? + ELSE + pshs a + lda <$0E + bita #Bold + puls a + ENDC + beq L1044 no, skip bold mask + lsra shift pixel pattern + ora -1,y merge it with original to double up pixels +L1044 equ * + IFNE H6309 + jsr ,w do a full 8-pixel width of bytes + ELSE + jsr [>GrfMem+$B5] + ENDC + ldb <$0063 get bytes per line + abx move screen address to next line + dec <$20 done 7 or 8 lines? + bgt L1039 No, go do next line + bmi L1052 yes, return + IFNE H6309 + tim #Under,<$0E Underline attribute on? + ELSE + lda <$0E + bita #Under + ENDC + beq L1039 No, go do last byte of font + lda #$ff Underline byte + bra L1044 Go put it in instead + +fast.pt fdb GrfStrt+font.2 2 color font + fdb GrfStrt+Font.4 4 color + fdb GrfStrt+Font.4 4 color + fdb GrfStrt+Font.16 16 color + +* smaller than old method. Perhaps slower, but it should get the right +* foreground/background colors +font.2 tfr a,b move font character into mask + comb invert it +ChkTChr tst <$0E Transparent attribute on? + bpl L1051 if transparent, do only foreground colors + andb <$0062 AND in background color: 0 or 1 + fcb $8C skip 2 bytes + +L1051 andb ,x AND in background + anda <$0061 AND in foreground color + IFNE H6309 + orr b,a OR in the background that's already there + ELSE + pshs b + ora ,s+ + ENDC + sta ,x save font to screen +L1052 rts and return + +font.16 bsr get.font expand it once + pshs a,x save low byte, and current X coordinate + tfr b,a move right hand mask into A + leax 2,x do the right side of the font first + bsr font.4 expand it again, and do another 2 bytes + puls a,x restore left hand byte and screen position + +font.4 bsr get.font get the font data into 2 bytes + pshs d save mask + IFNE H6309 + comd invert it for background check + ELSE + coma + comb + ENDC + tst <$0E check transparent flag + bpl fast.for if transparent, only do foreground colors + anda <$62 AND in background color + andb <$62 into both A and B + bra fast.st + +fast.for equ * + ifne H6309 + andd ,x AND in background of screen if transparent + ELSE anda ,x - bra L0F7E -L0F7C anda <$0062 -L0F7E sta ,x - andb <$0061 - orb ,x - stb ,x - ldb <$0063 - abx - dec <$0097 - bmi L0F99 - bne L0F66 - ldb <$000E - bitb #$40 - beq L0F66 - lda #$FF - bra L0F71 -L0F99 rts -L0F9A pshs x - leax <L0FFB,pcr - stx <$0010 - ldx ,s - ldb <$000E - bitb #$10 - beq L0FD0 - ldb <$0071 - decb - clra -L0FAD ora b,x - decb - bpl L0FAD - tsta - bne L0FB9 - lsr <$006F - bra L0FD0 -L0FB9 ldb #$FF -L0FBB incb - lsla - bcc L0FBB - ldx #$504C - ldb b,x - leax b,x - stx <$0010 - ldb #$01 -L0FCA incb - lsla - bcs L0FCA - stb <$006F -L0FD0 puls x - ldb -$03,y - stb <$000F - ldy -$05,y - exg x,y - lda <$0071 - deca - sta <$0099 - stx <$000C - lbsr L1E9C - ldx <$000C -L0FE7 lda ,y+ - ldb <$000E - bitb #$20 - beq L0FF2 - lsra - ora -$01,y -L0FF2 jmp [<$10,u] - lsla - lsla - lsla - lsla - lsla - lsla -L0FFB sta <$000B -L0FFD lda <$006F - sta <$0097 - ldb <$000F - stx <$000C -L1005 pshs b - jmp [>$00A9,u] -L100B lsl <$000B - bcs L1017 - lda <$000E - bpl L102A - lda <$0062 - bra L1019 -L1017 lda <$0061 -L1019 comb - andb ,x - stb ,x - anda ,s + andb 1,x + ENDC +fast.st std ,x save new background of the screen + puls d restore the old pixel mask + anda <$61 AND in foreground color + andb <$61 B, too + IFNE H6309 + ord ,x OR in background that's already there + ELSE ora ,x - sta ,x - bra L102A - eorb ,x - stb ,x -L102A dec <$0097 - beq L1035 - puls b - lbsr L1EB9 - bra L1005 -L1035 puls b - ldx <$000C - ldb <$0063 - abx - dec <$0099 - bmi L104C - bne L0FE7 - lda <$000E - bita #$40 - beq L0FE7 - lda #$FF - bra L0FFB -L104C rts -L104D fcb $AF,$AE,$AD,$AC,$AB,$AA,$A9,$AB -L1055 bsr L1063 - lbsr L10FF - bra L10A5 -L105C bsr L1063 - lbsr L1485 - bra L10A5 -L1063 jsr <$00B9 - lbra L0F31 -L1068 bsr L1063 - clra - ldb <$0047 - subd <$00B5 - tfr d,x - ldb <$006F - lbsr L1E21 - std <$0047 - addd <$006E - subd <$00B3 - cmpd <$1B,y - bhi L10A5 - clra - ldb <$0049 - subd <$00B5 - tfr d,x - ldb <$0071 - lbsr L1E21 - std <$0049 - addd <$0070 - subd <$00B3 - cmpd <$1D,y - bhi L10A5 - ldd <$0047 -L109C std -$02,y - ldd <$0049 - std ,y - lbsr L1131 -L10A5 clrb - rts -L10A7 clra - clrb - std ,y - lbra L112D -L10AE ldd -$02,y - subd <$006E - std -$02,y - lbpl L1139 - ldd <$1B,y - subd <$006E - addd <$00B3 - std -$02,y - ldd ,y - subd <$0070 - std ,y - bpl L1139 - clra - clrb - std -$02,y - std ,y + orb 1,x + ENDC + std ,x save it on-screen + rts + +* convert a byte of font data into pixel data +* This table turns a 2-color nibble (4 pixels) into a 4-color byte (4 pixels) +* The llokup is done twice for 16-color screens +fast.tbl fcb $00,$03,$0C,$0F + fcb $30,$33,$3C,$3F + fcb $C0,$C3,$CC,$CF + fcb $F0,$F3,$FC,$FF + +* A = font byte data +* U = pointer to fast.tbl, above +* returns D = pixel mask for this byte for a 4-color screen +get.font pshs a + anda #$0F + ldb a,u get rightmost byte + puls a + lsra + lsra + lsra + lsra move high nibble into low nibble + lda a,u get leftmost byte + rts +* ATD: end of new font routines + +* Draw a graphic font to multi color windows +* May want to change so E/F contains the byte from the font/screen mem to use +* register to register AND/OR, etc. +L106D pshs x save font address + ldd #GrfStrt+L10CF Point to default graphic plot routine + std <$0010 Save vector + IFNE H6309 + tim #Prop,<$E Proportional spacing? + ELSE + lda <$E no need to preserve regA + bita #Prop + ENDC + beq L10A4 no, skip finding font size +* Calc positioning for proportional spacing + ldb <$0071 Get Y pixel count + decb dec by 1 (0-7?) + clra Clear out byte for mask checking +* This goes through all 8 bytes of a font character, ORing them into A +* The resultant byte on completion of the loop has all bits set that will be +L1080 ora b,x Mask in byte from font + decb Dec counter (& position in font) + bpl L1080 Still more to check, continue + tsta Check byte still clear? + bne L108E No, skip ahead (B=$ff at this point) + lsr <$006F Divide X pixel count by 2 if it is + bra L10A4 Start printing with normal vector + +* Non-blank char +L108E decb dec B (# active pixels counter) + lsla Shift merged pixel mask byte left 1 bit + bcc L108E Pixel is unused in font char, keep looking +* Found pixel that will be needed, set up vector to shift char to be flush +* left +* Should move this table so that ABX can be used instead (move table to before +* shift routines + ldx #GrfStrt+L10CF+2 Point to shifting gfx text plot routine + leax b,x + stx <$0010 Save the vector +* Count # pixels that will be active + ldb #$01 Set up counter for #pixels to print (min.=2) +L109E incb Inc counter + lsla Shift out merged pixel mask byte + bcs L109E Until we either hit blank or run out + stb <$006F Save # pixels to print in X pixel count + +* Main printing starts here - sets up for outside loop (at L10BB) +L10A4 ldb Wt.FMsk,y Get start pixel mask (may be into byte for prop.) + stb <$000F Save in GrfDrv mem + ldx Wt.Cur,y get address of cursor in screen mem + puls y Get font address + lda <$0071 Get # bytes high char is + deca bump down by 1 (base 0) + sta <$0099 Save in temp (as counter) + stx <$000C Save cursor address + lbsr L1EF1 Set up mask & vector to bit shift routine + ldx <$000C Get cursor address +* Outside loop for Gfx font - A is byte of 2 color font data we are currently +* doing +L10BB lda ,y+ Get line of font data + IFNE H6309 + tim #$20,<$E Bold text? + ELSE + pshs a + lda <$E + bita #$20 + puls a + ENDC + beq L10C6 No, skip doubling up pixels + lsra shift it right 1 + ora -1,y merge with original to double up pixels +L10C6 jmp [>GrfMem+gr0010] Flush left the font data in byte + +* Bit shift offsets for proportional fonts +* Outside loop: A=byte from font data in 2 color format +* Will take byte of font data in A and make it flush left +L10C9 lsla +L10CA lsla +L10CB lsla +L10CC lsla +L10CD lsla +L10CE lsla +* Entry point for non-proportional fonts - byte already flush left (6 or 8) +L10CF sta <$000B Save flush left font byte, 1 bit/pixel + IFNE H6309 + lde <$006F get X width of font char in pixels + ELSE + ldb <$6F + stb <$B5 + ENDC + ldb <$000F Get bit mask for start pixel on screen +* NOTE: SHOULD TRY TO BUILD A WHOLE BYTE'S WORTH OF PIXELS INTO B TO PUT AS +* MANY PIXELS ONTO SCREEN AT ONCE - NEED TO KNOW HOW MANY PIXELS LEFT IN BYTE +* FROM START THOUGH (COULD USE F AS COUNTER) + pshs b Save pixel mask on stack + stx <$000C save screen address + jmp ,u Put it on screen (calls 10DF or 10FA only) + +* Print line of font char onto screen +* Inside loop: does 1 pixel at a time from font byte (stored in $000B) +L10DF lsl <$000B Shift pixel into carry from font byte + bcs L10EB Pixel is set, put it on screen in foregrnd color + lda <$000E Pixel is not used, transparent characters? + bpl L10FE No, skip this pixel entirely + lda <$0062 Transparent, get bckgrnd color full byte bit mast + bra L10ED Go put it on screen + +* Used by Update Window Cursor updates (Inverse for cursor) +L10FA eorb ,x Invert data on screen with bit data + stb ,x Save it on screen (Invert for cursor) + bra L10FE Check if we have more to do + +L10EB lda <$0061 get foreground color full byte bit mask +* Entry: B=Current pixel mask +* A=Color mask (can be fore or background) +L10ED equ * + IFNE H6309 + andr b,a Keep only color data we can use + ELSE + pshs b + anda ,s+ + ENDC + comb Make 'hole' with font data + andb ,x & screen data + IFNE H6309 + orr b,a Merge font color onto existing screen byte + ELSE + pshs b + ora ,s+ + ENDC + sta ,x Save result onto screen + +L10FE equ * + IFNE H6309 + dece Dec # pixels left on current font line + ELSE + dec <$B5 + ENDC + puls b Get current pixel mask again + beq L1109 Done current line, skip ahead + lbsr L1F0E Move to next pixel position + pshs b Save new pixel mask on stack + jmp ,u Put it on screen (calls 10DF or 10FA only) +* End of inside loop (each pixel within font byte) + +L1109 ldx <$000C get start of char. screen address again + ldb <$0063 Get # bytes per row on screen + abx Point to next line on screen + dec <$0099 Are we done whole char (or on last line)? + bgt L10BB No, continue drawing char + bmi L1120 Totally done, exit +* on last line ($99=0) + IFNE H6309 + tim #Under,<$0E Underline requested? + ELSE + lda <$0E + bita #Under + ENDC + beq L10BB No, go draw last line + lda #$FF Underline code + bra L10CF Go draw it +* End of outside loop (for each line with font) + +L1120 rts Return + +* 2 color mode pixel mask table +L1EE0 fcb $07 Mask for pixel #'s we care about + fcb $80,$40,$20,$10,$08,$04,$02,$01 + +* 4 color mode pixel mask table +L1EE9 fcb $03 Mask for pixel #'s we care about + fcb $c0,$30,$0c,$03 + +* 16 color mode pixel mask table +L1EEE fcb $01 Mask for pixel #'s we care about + fcb $f0,$0f + +* Goto X/Y entry point +L1186 lbsr L0FFF Set up font sizes (and font if on gfx screen) + ldb <$0047 Get X coord + subb #$20 Kill off ASCII part of it + lda <$006F Get # pixels wide each text char is + mul Calculate # pixels into screen to start at + std <$0047 Preserve Start pixel # as 'working' X coord + addd <$006E Add width in pixels again (calculate end X coord) + IFNE H6309 + decd Adjust + ELSE + subd #1 + ENDC + cmpd Wt.MaxX,y Would we be past end of window? + bhi L11CA Yes, exit out of grfdrv + ldb <$0049 Get Y coord + subb #$20 Kill off ASCII part of it + lda <$0071 Get Y size of font in bytes + mul Calculate # bytes from top of screen to start at + std <$0049 Save it + addd <$0070 Bump down by 1 more text char Y size + IFNE H6309 + decd Adjust + ELSE + subd #1 + ENDC + cmpd Wt.MaxY,y Would end of char go past bottom of window? + bhi L11CA Yes, exit out of grfdrv + IFNE H6309 + ldq <$0047 Get x & y coords + stq Wt.CurX,y Move into window table (-2 to +1) + ELSE + ldd <$49 + std Wt.CurX+2,y + std <$B5 + ldd <$47 + std Wt.CurX,y + ENDC + bsr NewEnt Originally bsr L11D1 (redundant) +L11CA jmp >GrfStrt+L0F78 + +* Control code processer +* ATD: 69 bytes old method, 47 new method +L1129 lbsr L0FFF Set up font sizes (and font if on gfx screen) + deca make 1-D = 0-C + bmi L1130 if 0 or smaller, exit + cmpa #$0D too high? (now 0-C instead of 1-D) + bhs L1130 yes, exit + + ldx #GrfStrt+T.1133 point to offset table to use + asla 2 bytes per entry + ldd a,x get pointer to routine + jsr d,x call it +L1130 jmp >GrfStrt+L0F78 return to WindInt: No errors + +T.1133 fdb L11E1-T.1133 1 home cursor + fdb L1130-T.1133 2 GOTO X,Y: handled elsewhere + fdb L1352-T.1133 3 erase current line + fdb L135F-T.1133 4 erase to end of line + fdb L1130-T.1133 5 cursor on/off: handled elsewhere + fdb L121A-T.1133 6 cursor right + fdb L1130-T.1133 7 BELL: handled elsewhere + fdb L11F9-T.1133 8 cursor left + fdb L122F-T.1133 9 cursor up + fdb L123A-T.1133 A cursor down (LF) + fdb L138D-T.1133 B erase to end of screen + fdb L1377-T.1133 C clear screen + fdb L11CD-T.1133 D cursor to LHS of the screen (CR) + +* Calculate screen logical address based on X/Y text coordinates +* Exit: X=Screen logical address pointing to X,Y text coordinate location +* If graphics screen, B=Mask for specific pixel +L1E9D ldx Wt.LStrt,y get screen logical start +* Calculate offset for Y location +L1E9F lda <$004A get Y coordinate (0-199) + ldb <$0063 get bytes/row + mul Calculate # bytes into screen to go + IFNE H6309 + addr d,x Add to screen start + ELSE + leax d,x + ENDC + ldb <$0060 get screen type + bpl L1EB5 graphics screen, go adjust X coordinate +* Calculate offset for X location (text only) + ldb <$0048 Get X coordinate + lslb account for attribute byte + abx point X to screen location & return + rts + +* Calculate offset for X location (gfx only) +* Fast horizontal and vertical lines call this after doing a LDW <$68 (LSET) +L1EB5 pshs u Preserve U + cmpb #$04 + bne L1EC0 +* 16 color screens (2 pixels/byte) + ldd <$0047 get requested X coordinate + ldu #GrfStrt+L1EEE Point to 2 pixel/byte tables + bra L1ED4 Adjust screen address accordingly + +L1EC0 cmpb #$01 640 2 color screen? + beq L1ECB Yes, go process it +* 4 color screens go here (4 pixels/byte) + ldd <$0047 Get requested X coordinate + ldu #GrfStrt+L1EE9 Point to 4 pixel/byte tables + bra L1ED2 Adjust Screen address accordingly +* 2 color screens go here (8 pixels/byte) +L1ECB ldd <$0047 Get requested X coordinate + ldu #GrfStrt+L1EE0 Point to 8 pixel/byte tables + IFNE H6309 + lsrd Divide by 8 for byte address +L1ED2 lsrd divide by 4 +L1ED4 lsrd divide coordinate by 2 (to get Byte offest) + addr d,x Point X to byte offset for pixel + ELSE + lsra + rorb +L1ED2 lsra + rorb +L1ED4 lsra + rorb + leax d,x + ENDC + ldb <$0048 Get LSB of X coordinate requested + andb ,u+ Mask out all but pixels we need to address + ldb b,u Get mask for specific pixel we need + puls pc,u Restore Y & exit + +* Cursor to left margin (CR) +L11CD equ * + IFNE H6309 + clrd Set X coordinate to 0 + ELSE + clra + clrb + ENDC + std Wt.CurX,y +L11D1 equ * + IFNE H6309 + ldq Wt.CurX,y Copy window table x,y coord to grfdrv x,y + stq <$0047 + ELSE + ldd Wt.CurX+2,y + std <$49 + ldd Wt.CurX,y + std <$47 + ENDC +NewEnt bsr L1E9D Go calculate screen logical address + stx Wt.Cur,y Preserve screen location + stb Wt.FMsk,y Preserve x coord (adjusted by x2 for text attr + rts if needed) + +* Home cursor +L11E1 ldd Wt.LStrt,y Make cursor address same as upper left of screen + std Wt.Cur,y + ldx #GrfStrt+L1F00-2 Point to bit mask/vector table + ldb <$0060 Get screen type + bmi L11F8 If text, exit + lslb Multiply x2 to get table entry + ldb b,x Get bit mask + stb Wt.FMsk,y Preserve it +L11F8 equ * + IFNE H6309 + clrd Clear out x & y coord's in window table + clrw + stq Wt.CurX,y + ELSE + clra + clrb + std <$B5 + std Wt.CurX,y + std Wt.CurX+2,y + ENDC rts -L10D0 ldd -$02,y - tfr d,x - addd <$006E - std -$02,y - addd <$006E - subd <$00B3 - cmpd <$1B,y - bls L1139 - lda <$2A,y - bpl L10F0 - stx -$02,y - ora #$01 - sta <$2A,y - bra L1139 -L10F0 bsr L112D - bra L1119 -L10F4 ldd ,y - subd <$0070 - bmi L10FE - std ,y - bsr L1139 -L10FE rts -L10FF cmpa #$0D - beq L112D - cmpa #$01 - beq L10A7 - cmpa #$08 - beq L10AE - cmpa #$06 - beq L10D0 - cmpa #$09 - beq L10F4 - cmpa #$0A - lbne L1267 -L1119 ldd ,y - addd <$0070 - tfr d,x - addd <$0070 - subd <$00B3 - cmpd <$1D,y - bhi L1149 - stx ,y - bra L1139 -L112D clra - clrb - std -$02,y -L1131 lda <$2A,y - anda #$FE - sta <$2A,y -L1139 ldd -$02,y - std <$0047 - ldd ,y - std <$0049 - lbsr L1E48 - stx -$05,y - stb -$03,y + +* Cursor left +L11F9 ldd Wt.CurX,y + subd <$006E Subtract X pixel count + std Wt.CurX,y + bpl L11D1 Didn't wrap into negative, leave + ldd Wt.MaxX,y Get Max X coordinate + subd <$006E subtract X pixel count + IFNE H6309 + incd Bump up by 1 + ELSE + addd #1 + ENDC + std Wt.CurX,y Save new X coordinate + ldd ,y Get Y coordinate + subd <$0070 Subtract Y pixel count + std Wt.CurY,y Save updated Y coordinate + bpl L11D1 Didn't wrap into negative, leave + IFNE H6309 + clrd Set coordinates to 0,0 + ELSE + clra + clrb + ENDC + std Wt.CurX,y Save X coordinate + std Wt.CurY,y Save Y coordinate rts -L1149 pshs y - ldb $02,y - lbsr L1252 - std <$0097 - clra - ldb <$0063 - std <$0099 - ldd ,y - std <$009D - lda -$08,y - deca - sta <$009B - beq L1184 - ldx -$0D,y - ldd $04,y - tfr x,y + +* Cursor Up +L122F ldd Wt.CurY,y Get Y coordinate + subd <$0070 Subtract Y pixel size + bpl GoodUp If not at top, save coordinate + rts Otherwise, exit +GoodUp std Wt.CurY,y Save new Y coordinate + bra L11D1 Leave + +* Cursor right +L121A ldd Wt.CurX,y Get X coordinate + addd <$006E Add to X pixel count (1, 6 or 8?) + std Wt.CurX,y Update value + addd <$006E Add to X pixel count again + IFNE H6309 + decd Dec by 1 + ELSE + subd #1 + ENDC + cmpd Wt.MaxX,y Compare with maximum X coordinate + bls L11D1 If not past right hand side, leave +L1238 bsr L11CD Zero out X coordinate + +* Cursor Down (LF) +* Called by font change. Entry= Y=window table ptr, X=Screen addr, B=X coord +* on current line on physical screen +L123A ldd Wt.CurY,y Get current Y coord + addd <$0070 Add to Y pixel count + tfr d,x Move result to X + addd <$0070 Add Y pixel count again + IFNE H6309 + decd decrement by 1 + ELSE + subd #1 + ENDC + cmpd Wt.MaxY,y compare with Maximum Y coordinate + bhi L124F If higher (scroll needed), skip ahead + stx Wt.CurY,y Store +1 Y coordinate + bra L11D1 Update grfdrv's X&Y ptrs & leave + +* new Y coord+1 is >bottom of window goes here +L124F pshs y Preserve window table ptr + ldb Wt.XBCnt,y Get width of window in bytes + stb <$0097 Save since Y will disappear + clra Clear MSB of D + ldb <$0063 Get # bytes per row of screen + std <$0099 preserve value (16 bit for proper ADDR) + ldd Wt.CurY,y Get current Y coord + std <$009D Preserve + lda Wt.SZY,y Get current Y size + deca 0 base + sta <$009B Preserve + beq L128A If window only 1 line high, then no scroll needed + ldx Wt.LStrt,y Get screen logical start addr. (top of screen) + ldd Wt.BRow,y Get # bytes/text row (8 pixel lines if gfx) + tfr x,y Move screen start addr. to Y + IFNE H6309 + addr d,x X=Screen addr+1 text line + ELSE leax d,x - tst <$0060 - bmi L1175 - lda <$009B - lsla - lsla - lsla - sta <$009B -L1175 ldd <$0097 - lbsr L121F - ldd <$0099 - leax d,x - leay d,y - dec <$009B - bne L1175 -L1184 puls y - ldd <$009D -L1188 lbra L127A -L118B lda #$80 - ora <$2A,y - bra L1197 -L1192 lda #$7E - anda <$2A,y -L1197 sta <$2A,y - clrb - rts -L119C cmpa #$26 - beq L118B - cmpa #$27 - beq L1192 - cmpa #$30 - beq L11AD - cmpa #$31 - beq L11E1 - rts -L11AD pshs y - ldd ,y - std <$009D - ldb $02,y - lbsr L1252 - std <$0097 - clra - ldb <$0063 - nega - negb - sbca #$00 - std <$0099 - ldb -$08,y - decb - lda <$0071 - mul - tfr b,a - deca - subb $01,y - cmpb <$0071 - bcs L1184 - stb <$009B - ldb <$0063 - mul - addd -$0D,y - tfr d,x - addd $04,y - tfr d,y - bra L1175 -L11E1 pshs y - ldb $02,y - bsr L1252 - std <$0097 - clra - ldb <$0063 - std <$0099 - lda -$08,y - deca - tst <$0060 - bmi L11F8 - lsla + ENDC + lda <$009B Get Y size (0 base) + ldb <$0060 Check screen type + bmi L1267 If text, skip ahead + lsla Multiply by 8 (# pixel lines/text line) lsla lsla -L11F8 suba $01,y - bhi L1202 - puls y - ldd ,y - bra L1188 -L1202 sta <$009B - ldd <$1D,y - subd <$0070 - addd <$00B3 - std <$009D - lda <$0063 - ldb $01,y - mul - addd -$0D,y + sta <$009B Y size into # pixel lines, not text lines +* Special check for full width windows +L1267 ldb <$97 Get width of window in bytes + cmpb <$63 Same as screen width? + bne L127B No, do normal scroll + mul Calculate size of entire window to move +* Scroll entire window in one shot since full width of screen + IFNE H6309 + tfr d,w Move to TFM size reg. + tfm x+,y+ Move screen + ELSE + pshs d,x,u + tfr x,u tfr d,x - ldd $04,y - tfr x,y - leax d,x - lbra L1175 -L121F pshs u,y,x,dp,cc - pshs a - tstb - beq L122D -L1226 lda ,x+ +L1267b lda ,u+ sta ,y+ - decb - bne L1226 -L122D puls b - tstb - beq L1250 - orcc #$50 - stb >$1006 - sts >$1003 + leax -1,x + bne L1267b + stx <$B5 + stu 2,s + puls d,x,u + ENDC + bra L128A Exit scroll routine + +* Scroll window that is not full width of screen +L127B ldd <$0099 Get # bytes/row for screen + IFNE H6309 + ldf <$0097 Get # bytes wide window is + clre + subr w,d Calc # bytes to next line + ELSE + pshs d + clra + ldb <$97 + std <$B5 regW loaded + puls d + subd <$B5 subr w,d + ENDC + IFNE H6309 +L127E tfm x+,y+ Block move the line + ELSE +L127E pshs d,x,u + ldb <$B6 get regW + clra tfr x,u - tfr y,s - leas $07,s -L1241 pulu y,x,dp,b,a - pshs y,x,dp,b,a - leas $0E,s - dec >$1006 - bne L1241 - lds >$1003 -L1250 puls pc,u,y,x,dp,cc -L1252 tfr b,a - lsra - lsra - lsra - andb #$07 - pshs a - addb ,s+ -L125D cmpb #$07 - blt L1266 - subb #$07 - inca - bra L125D -L1266 rts -L1267 cmpa #$03 - beq L1278 - cmpa #$04 - beq L1285 - cmpa #$0B - beq L12B4 - cmpa #$0C - beq L129C - rts -L1278 ldd ,y -L127A std <$0049 - clra - clrb - std <$0047 - ldd <$1B,y - bra L1292 -L1285 ldd -$02,y - std <$0047 - ldd ,y - std <$0049 - ldd <$1B,y - subd -$02,y -L1292 addd <$00B3 - std <$004F - ldd <$0070 - std <$0051 - bra L12C8 -L129C lbsr L10A7 - clra - clrb + tfr d,x +L127Eb lda ,u+ + sta ,y+ + leax -1,x + bne L127Eb + stx <$B5 + stu 2,s + puls d,x,u + ENDC + dec <$009B Dec # lines to still copy + beq L128A If done, exit + IFNE H6309 + addr d,x Bump start ptr by 1 line + addr d,y Bump end ptr by 1 line + ldf <$0097 Get width of window in bytes + ELSE + leax d,x + leay d,y + pshs b + ldb <$97 + stb <$B6 + puls b + ENDC + bra L127E Do until we have moved all the lines + +L128A puls y Get back window table ptr +L128C ldd <$009D Get back current Y coord +L128E bra L1354 Go clear new line & exit + +* Insert line +L1291 pshs y Save window table ptr + ldd Wt.CurY,y Get current Y coord + std <$009D Preserve it + ldb Wt.XBCnt,y Get width of window in bytes + stb <$0097 Save in fast mem + clra Get # bytes/row into D + ldb <$0063 (16 bit for ADDR) + IFNE H6309 + negd Make negative (since scrolling down?) + ELSE + coma + comb + addd #1 + ENDC + std <$0099 Preserve it + ldb Wt.SZY,y Get current Y size + decb 0 base + lda <$0071 Get Y pixel count + mul Multiply by current Y size + tfr b,a Dupe result + deca Don't include line we are on + subb Wt.CurY+1,y Subtract Y coord of cursor + cmpb <$0071 Compare with Y pixel count + blo L128A If on bottom line, don't bother + stb <$009B Save # lines to leave alone + ldb <$0063 Get #bytes/row + mul Calculate # bytes to skip scrolling + addd Wt.LStrt,y Add to screen start address + tfr d,x Move to top of scroll area reg. for TFM + addd Wt.BRow,y Add # bytes/text row + tfr d,y Move to bottom of scroll area reg. for TFM + bra L127B Do insert scroll + +* Delete line +L12C5 pshs y Save window table ptr + ldb Wt.XBCnt,y Get width of window in bytes + stb <$0097 Save it + clra Get # bytes/row on screen into D + ldb <$0063 + std <$0099 Save for ADDR loop + lda Wt.SZY,y Get current Y size + deca 0 base + ldb <$0060 Check screen type + bmi L12DC If text, skip ahead + lsla Multiply x8 (height of font) + lsla + lsla +L12DC suba Wt.CurY+1,y Subtract current Y location + bhi L12E6 Not on bottom of screen, continue + puls y On bottom, get back window table ptr + ldd Wt.CurY,y Get Y coord back + bra L1354 Just clear the line & exit + +L12E6 sta <$009B Save # lines to scroll + ldd Wt.MaxY,y Get Maximum Y coordinate + subd <$0070 Subtract Y pixel count + IFNE H6309 + incd Base 1 + ELSE + addd #1 + ENDC + std <$009D Save size of area to scroll for delete + lda <$0063 Get # bytes/row + ldb Wt.CurY+1,y Get Y coord of cursor + mul Calculate offset to top of area to scroll + addd Wt.LStrt,y Add to Screen logical start address + tfr d,x Move to top of window reg. for TFM + ldd Wt.BRow,y Get # bytes/text row + tfr x,y Swap top of window to bottom since reverse scroll + IFNE H6309 + addr d,x Calculate top of window reg. for backwards TFM + ELSE + leax d,x + ENDC + jmp >GrfStrt+L127B Go delete the line + +* Erase current line +L1352 ldd Wt.CurY,y Get Y coordinate +L1354 std <$0049 Preserve 'working' Y coordinate + IFNE H6309 + clrd + ELSE + clra + clrb + ENDC + std <$0047 'Working' X coordinate to 0 + ldd Wt.MaxX,y Get maximum X coordinate + bra L136C + +* Erase to end of line +L135F equ * + IFNE H6309 + ldq Wt.CurX,y Get X & Y coordinates + stq <$0047 Save as 'working' copies + ELSE + ldd Wt.CurX+2,y + std <$49 + ldd Wt.CurX,y + std <$47 + ENDC + ldd Wt.MaxX,y Get maximum X coordinate + subd Wt.CurX,y Subtract X coordinate +L136C equ * + IFNE H6309 + incd Add 1 to X size + ELSE + addd #1 + ENDC + std <$004F New X size (in bytes) + ldd <$0070 Get Y pixel count + std <$0051 New Y size (in bytes) + bra L13AD + +* CLS (Chr$(12)) +L1377 lbsr L11E1 Home cursor (D&W are 0 on exit) + IFNE H6309 + stq <$0047 + ELSE +* pshs d not needed because D=W=0 +* ldd <$B5 + std <$49 +* puls d + std <$47 + ENDC + ldd Wt.MaxX,y Get maximum X coordinate + IFNE H6309 + incd Bump up by 1 + ELSE + addd #1 + ENDC + std <$004F New X size + ldd Wt.MaxY,y Get maximum Y coordinate + bra L13A8 + +* Erase to end of screen +L138D bsr L135F Erase to end of current line first + IFNE H6309 + clrd 'working' X coordinate to 0 + ELSE + clra + clrb + ENDC std <$0047 - bsr L12A7 - bra L12C4 -L12A7 std <$0049 - ldd <$1B,y - addd <$00B3 - std <$004F - ldd <$1D,y - rts -L12B4 bsr L1285 - clra - clrb - std <$0047 - ldd ,y - addd <$0070 - bsr L12A7 - subd <$0049 - bmi L12CE -L12C4 addd <$00B3 - std <$0051 -L12C8 ldb <$0060 - bmi L12CF - bsr L12FA -L12CE rts -L12CF pshs y - lbsr L1E48 - lda #$20 - ldb $08,y - andb #$38 - orb <$0062 - std <$0097 - ldb <$0063 - subb <$0050 - subb <$0050 - stb <$0099 -L12E6 ldy <$004F - ldd <$0097 -L12EB std ,x++ - leay -$01,y - bne L12EB - ldb <$0099 - abx - dec <$0052 - bne L12E6 - puls pc,y -L12FA ldb <$0060 - ldx #$4C78 - lda <$0048 - coma - anda b,x - inca - sta <$0097 - ldx #$4C7C - ldb b,x - abx - lsla - lda a,x - sta <$0012 - clra - ldb <$0060 - tfr d,x - ldd <$004F - subb <$0097 - sbca #$00 - lsra - rorb - cmpx #$0004 - beq L132C - lsra - rorb - cmpx <$00B3 - bne L132C - lsra - rorb -L132C stb <$0097 - ldb <$0063 - subb <$0097 - subb #$01 - stb <$0099 - lbsr L1E48 - lda <$0012 - inca - beq L1360 -L133E lda <$0012 - tfr a,b - coma - anda ,x - sta ,x - andb <$0062 - orb ,x - stb ,x+ - lda <$0097 - beq L1358 - ldb <$0062 -L1353 stb ,x+ - deca - bne L1353 -L1358 ldb <$0099 - abx - dec <$0052 - bne L133E + ldd Wt.CurY,y + addd <$0070 Add Y pixel count + std <$0049 New Y coordinate + ldd Wt.MaxX,y Get maximum X coordinate + IFNE H6309 + incd bump up by 1 + ELSE + addd #1 + ENDC + std <$004F New X size + ldd Wt.MaxY,y Get maximum Y coordinate + subd <$0049 Subtract Y coordinate + bmi L13B7 If negative, skip +L13A8 equ * + IFNE H6309 + incd Bump up by 1 + ELSE + addd #1 + ENDC + std <$0051 Save Y size +* Erase to end of screen/line comes here too +L13AD lbsr L1E9D get screen logical start address into X +* and also the starting pixel mask into B. + lda <$0060 Get screen type + bpl L13E3 Do CLS on gfx screen & return +* Do the CLS on text screen + lda #$20 Space character + ldb Wt.Attr,y Get default attributes + andb #$38 Mask out Flash/Underline & bckgrnd color + orb <$0062 Mask in background color + IFNE H6309 + tfr x,w move pointer to faster index register + ELSE + stx <$B5 + ENDC + tfr d,x Move into proper register for clear loop + ldb <$0063 Get #bytes/row + subb <$0050 Subtract width twice for char. & attribute + subb <$0050 B=# bytes to skip to go to next line + beq ClsFTxt If full width screen, use optomized routine + +L13CF lda <$0050 Get width of line in chars? + IFEQ H6309 + pshs u + ldu <$B5 + ENDC +L13D4 equ * * Only called as loop + IFNE H6309 + stx ,w++ Put attr/char on screen + ELSE + stx ,u++ + ENDC + deca Dec counter of how many bytes this line + bne L13D4 Do until line is done + IFNE H6309 + addr d,w after all, A=0 + ELSE + leau d,u + stu <$B5 + puls u + ENDC + dec <$0052 Dec line count + bne L13CF Do until rest of screeen done +L13B7 rts Restore window table ptr & return + +* Optomized routine for full width text screens +* Entry: W=attribute/char to fill with +ClsFTxt ldb <$0050 Get # chars per line + lda <$0052 Get # of rows (lines) + mul # chars till end of screen + IFEQ H6309 + pshs u + ldu <$B5 + ENDC +FstClrT equ * + IFNE H6309 + stx ,w++ Put attr/char on screen + decd Dec counter + ELSE + stx ,u++ + subd #1 + ENDC + bne FstClrT Do until done + IFNE H6309 + rts Restore window table ptr & return + ELSE + stu <$B5 + puls u,pc + ENDC + +* Part of CLS/Erase to end of screen/line - Gfx only +* all coords & sizes should be pixel based +* the cmpx's at the bottom should be F or E (screen type) +* NOTE: <$48 contains a 0 when coming in here for CLS +* If this is the only way to get here, may change lda/coma to lda #$ff +* <$4F=X size in pixels (1-640) to clear +* <$51=Y size in pixels (1-200) to clear +* This routine calculates the pixel mask if you are clearing from the middle +* of a byte to properly handle proportional chars or 6 pixel fonts +* ATD: OK, MOST clears are on 8x8 pixel boundaries, but for proportional, etc. +* fonts and clear to EOL, we may be in the middle of a byte. In that case, +* do a BAR. It's slower, but a lot smaller code. +* Entry: A=Screen type +* B= starting pixel mask for this byte: important for pixel boundaries! +* X=absolute address of the start of the screen +L13E3 ldu #GrfStrt+L0D70-1 mask for pixels + lda a,u grab mask (7,3,1) + tstb is the high bit of the pixel mask set? + bmi L13F0 yes, we're starting on a byte boundary + pshs a,x save X-coord mask, and screen ptr for later + tfr b,a get another copy of the pixel mask + +L13E5 lsrb move the mask one bit to the right + IFNE H6309 + orr b,a make A the right-most mask + ELSE + pshs b + ora ,s+ + ENDC + bcc L13E5 the low bits of A will be the pixel mask + tfr a,b copy A to B again + coma + andb <$62 AND with full-byte background color mask + std <$97 save screen mask, background color + IFNE H6309 + lde <$52 get the lines to clear + ELSE + ldb <$52 + stb <$B5 + ENDC + ldb <$63 get the size of the screen + +L13E8 lda ,x grab a byte off of the screen + anda <$97 AND in only the screen pixels we want + ora <$98 OR in the background color + sta ,x save the updated byte + abx go to the next screen line + IFNE H6309 + dece count down + ELSE + dec <$B5 + ENDC + bne L13E8 continue until done + + puls a,x restore X coord mask and screen ptr + leax 1,x we've done these bytes already + +L13F0 inca now B=number of pixels per byte (8,4,2);A not B; RG + ldb <$62 Get backgrnd full-byte pixel mask + pshs d save pixels/byte, color mask + ldd <$004F Get X size (in pixels) + IFNE H6309 + divd ,s+ divide by pixels/byte: B=bytes wide the window is +* PANIC if A<>0!!! leave mask on stack for later use + ELSE + clr ,-s +L13F0b inc ,s + subb 1,s + sbca #0 + bcc L13F0b +* addb 1,s +* tfr b,a don't care about remainder + puls b + decb + leas 1,s + ENDC + cmpb <$0063 Get # bytes/row on screen + beq ClsFGfx full width of screen: do complete TFM + + stb <$97 save width of window for later + subb <$0063 subtract width of window from width of screen + negb now B=offset from X-end,Y to X-start,Y+1 + + lda <$52 Get # lines to clear + IFNE H6309 + clre W for TFM size +L1450 ldf <$97 Get width of window in bytes + tfm s,x+ Clear out line + ELSE +L1450 pshs d,y + clra + ldb <$97 + tfr d,y + lda 4,s +L1450b sta ,x+ + leay -1,y + bne L1450b + sty <$B5 + puls d,y + ENDC + deca Dec line counter + beq L146F done, exit + abx Bump to start of next line + bra L1450 Keep clearing until done + +* Clearing Gfx screen/even byte start/full width window +* Entry: B=width of screen/window in bytes +ClsFGfx lda <$52 Get # lines to clear + mul Calculate # bytes for remainder of screen + IFNE H6309 + tfr d,w Move to TFM size register + tfm s,x+ Clear out remainder of screen + ELSE + cmpd #0 + beq L146F + pshs d,y + tfr d,y tfr d,w + lda 4,s get ,s +L146Fb sta ,x+ + leay -1,y + bne L146Fb + sty <$B5 + puls d,y + ENDC +L146F puls pc,a Eat a & return + +* $1f code processor +*L1478 lbsr L0177 Map in window/setup GRFDRV mem/update cursors +L1478 lbsr L0FFF Set up font info + bsr L1483 Perform $1F function + jmp >GrfStrt+L0F78 Return to Grf/Wind Int: no errors + +L1483 suba #$20 Inverse on? (A=$20) + beq L14A8 yes, go do it + deca A=$21 Inverse off? + beq L14C4 + deca A=$22 Underline on? + beq L14D0 + deca A=$23 Underline off? + beq L14D9 + deca A=$24 Blink on? + beq L14E2 + deca A=$25 blink off? + beq L14E9 + suba #$30-$25 A=$30 Insert line? + lbeq L1291 + deca A=$31 Delete line? + lbeq L12C5 rts -L1360 pshs u - lda <$0062 - tfr a,b - tfr d,u - ldb <$0097 - incb - clr <$0097 - lsrb - stb <$0012 - bcc L1374 - inc <$0097 -L1374 ldb <$0097 - beq L137A - sta ,x+ -L137A ldb <$0012 - beq L1383 -L137E stu ,x++ - decb - bne L137E -L1383 ldb <$0099 - abx - dec <$0052 - bne L1374 - puls pc,u -L138C lbsr L1063 - bsr L1393 - clrb - rts -L1393 cmpa #$21 - beq L13C9 - cmpa #$22 - beq L13D3 - cmpa #$23 - beq L13DB - cmpa #$24 - beq L13E4 - cmpa #$25 - beq L13EA - cmpa #$20 - lbne L119C - ldb $09,y - bitb #$04 - bne L13C8 - orb #$04 -L13B5 stb $09,y - lda $08,y - lbsr L14B4 - pshs b,a - ldb $08,y - andb #$C0 - orb ,s+ + +* Inverse ON +L14A8 ldb Wt.BSW,y Get window bit flags + bitb #Invers Inverse on? + bne L14C3 Already on, leave it alone + orb #Invers Set inverse on flag + stb Wt.BSW,y Save new bit flags + +L14B2 lda Wt.Attr,y Get default attributes + lbsr L15B2 Go swap Fore/Background colors into A + ldb Wt.Attr,y Get default attributes again + andb #$c0 Mask out all but Blink & underline + IFNE H6309 + orr a,b Mask in swapped colors + ELSE + pshs a orb ,s+ - stb $08,y -L13C8 rts -L13C9 ldb $09,y - bitb #$04 - beq L13C8 - andb #$FB - bra L13B5 -L13D3 ldd $08,y - ora #$40 - orb #$40 - bra L13E1 -L13DB ldd $08,y - anda #$BF - andb #$BF -L13E1 std $08,y - rts -L13E4 ldb $08,y - orb #$80 - bra L13EE -L13EA ldb $08,y - andb #$7F -L13EE stb $08,y + ENDC + stb Wt.Attr,y Save new default attribute byte & return +L14C3 rts + +* Inverse OFF +L14C4 ldb Wt.BSW,y Get window bit flags + bitb #Invers Inverse off? + beq L14C3 Already off, leave + andb #^Invers Shut inverse bit flag off + stb Wt.BSW,y Save updated bit flags + bra L14B2 Go swap colors in attribute byte + +L14D0 equ * + IFNE H6309 + oim #Under,Wt.Attr,y + oim #Under,Wt.BSW,y + ELSE + pshs a + lda Wt.Attr,y + ora #Under + sta Wt.Attr,y + lda Wt.BSW,y + ora #Under + sta Wt.BSW,y + puls a + ENDC + rts + +L14D9 equ * + IFNE H6309 + aim #^Under,Wt.Attr,y + aim #^Under,Wt.BSW,y + ELSE + pshs a + lda Wt.Attr,y + anda #^Under + sta Wt.Attr,y + lda Wt.BSW,y + anda #^Under + sta Wt.BSW,y + puls a + ENDC + rts + +* Blink on +L14E2 equ * + IFNE H6309 + oim #TChr,Wt.Attr,y + ELSE + pshs a + lda Wt.Attr,y + ora #TChr + sta Wt.Attr,y + puls a + ENDC rts -L13F1 lbsr L0107 - bsr L1454 - lbsr L14C1 -L13F9 clrb + +* Blink off +L14E9 equ * + IFNE H6309 + aim #^TChr,Wt.Attr,y + ELSE + pshs a + lda Wt.Attr,y + anda #^TChr + sta Wt.Attr,y + puls a + ENDC rts -L13FB pshs y,x,b,a - bsr L146D - lbsr L14E3 - ldb >$1000 - stb >$1001 - puls pc,y,x,b,a -L140A lbsr L0107 - cmpy <$002E - bne L1428 - ldd <$005B - cmpd <$003D - bne L1420 - ldd <$005D - cmpd <$003F - beq L1428 -L1420 lbsr L14E3 - bsr L142A - lbsr L14C1 -L1428 bra L13F9 -L142A ldd <$0047 - pshs b,a - ldd <$0049 - pshs b,a - ldd <$005B + +* Cursor On/Off entry point +L116E lbsr L0FFF Set up font sizes (and font if on gfx screen) + bsr L1179 Do appropriate action + bra L1508 + +L1179 suba #$20 A=$20 Cursor Off? + beq L14F8 Yes, go do it + deca A=$21 Cursor on? + beq L14F0 Yes, go do it + rts Neither, return + +* Update Window entrypoint - Put txt & Gfx cursors back on scrn +L1500 lbsr L0129 Map the window in & setup Grfdrv mem + bsr L1563 Put text cursor back on window +L1505 lbsr L15BF Put gfx cursor back on window +L1508 jmp >GrfStrt+L0F78 no error & exit + +* This takes the gfx/txt cursors off the screen before returning to original +* Grfdrv call +L150C pshs y,x,d Preserve regs + bsr L157A Take text cursor off (restore original char) + lbsr L15E2 Take Gfx cursor off (restore original screen) + ldb >WGlobal+G.CurTik Get restart counter for # clock interrupts per + stb >WGlobal+G.CntTik cursor update & make it current counter + puls pc,y,x,d Restore regs & return + +* PutGC entry point (Took out mapping in window since the CMPY only lets us +* do anything if it IS mapped in currently +L151B lbsr L0129 Map in window & setup Grfdrv vars + cmpy <$002E Are we the current active window (window tbl)? + bne L1508 No, don't bother with PutGC + ldd <$005B Get Graphics cursor X coord + cmpd <$003D Same as last used graphics cursor coord? + bne L1531 No, go draw new graphics cursor + ldd <$005D Get Graphics cursor Y coord + cmpd <$003F Same as last used graphics cursor coord? + beq L1508 Yes, don't bother updating +L1531 lbsr L15E2 Put original data under cursor back to normal + bsr L153B Update 'last gfx cursor' on position to new one + bra L1505 put gfx cursor back on screen, and exit: +3C:-3B + +L153B ldd <$0047 Get current 'working' X & Y coords + ldx <$0049 + pshs d,x Save them on stack + IFNE H6309 + ldq <$005b Get new graphics cursor X & Y coords + stq <$0047 Save as working copies for Put routines + stq <$003d Also, make them the new 'last position' coords + ELSE + ldd <$5d + std <$B5 + std <$49 + std <$3f + ldd <$5b + std <$47 + std <$3d + ENDC + ldx Wt.STbl,y Get screen table ptr + ldx St.LStrt,x Get screen start address + lbsr L1E9F Screen address to put=X, start pixel mask=B + stx <$0041 Save screen ptr + stb <$0043 Save start pixel mask + puls d,x Get back original 'working' coords std <$0047 - std <$003D - ldd <$005D - std <$0049 - std <$003F - ldx -$10,y - ldd $02,x - lbsr L1E4A - stx <$0041 - stb <$0043 - puls b,a - std <$0049 - puls b,a - std <$0047 - rts -L1452 bsr L147E -L1454 lbsr L0F31 - cmpy <$002E - bne L146A - ldb $09,y - bitb #$02 - bne L146A - ldb <$0039 - bne L146A - bsr L148E - inc <$0039 -L146A rts -L146B bsr L147E -L146D lbsr L0F31 - cmpy <$002E - bne L147D - ldb <$0039 - beq L147D - bsr L148E - clr <$0039 -L147D rts -L147E eora #$21 - ldb #$02 - lbra L034E -L1485 cmpa #$20 - beq L146B - cmpa #$21 - beq L1452 - rts -L148E pshs y - ldx -$05,y - ldb <$0060 - bpl L14A8 - lda $01,x - bsr L14B4 - pshs b,a - ldb $01,x - andb #$C0 - orb ,s+ + stx <$0049 Put them back for original GrfDrv function +L1579 rts + +* Cursor on +L14F0 equ * + IFNE H6309 + aim #^NoCurs,Wt.BSW,y Set cursor flag to on + ELSE + lda Wt.BSW,y + anda #^NoCurs + sta Wt.BSW,y + ENDC +* Update txt cursor (on gfx or txt screens) from UPDATE Window 'hidden' call +L1563 lda #$01 put the cursor on the screen + bra L157B + +* Cursor off +L14F8 equ * + IFNE H6309 + oim #NoCurs,Wt.BSW,y Set cursor flag to off + ELSE + lda Wt.BSW,y + ora #NoCurs + sta Wt.BSW,y + ENDC +* Update text cursor (on gfx or text screens) from within Grfdrv +L157A clra take the cursor off of the screen + +L157B cmpy <$002E We on current window? + bne L1579 No, exit + IFNE H6309 + tim #NoCurs,Wt.BSW,y Cursor enabled? + ELSE + pshs a + lda Wt.BSW,y + bita #NoCurs + puls a + ENDC + bne L1579 No, exit + cmpa <$0039 get cursor on screen flag + beq L1579 same state as last time, exit + sta <$0039 cursor is ON the screen + lbsr L1002 Set up fonts, character sizes + bra L158B go put the cursor on-screen + +* Cursor on +*L14F0 aim #^NoCurs,Wt.BSW,y Set cursor flag to on +* Update txt cursor (on gfx or txt screens) from UPDATE Window 'hidden' call +*L1563 cmpy <$002E We on current window? +* bne L1579 No, exit +* tim #NoCurs,Wt.BSW,y Cursor on? +* bne L1579 No, exit +* ldb <$0039 get GP buffer block number +* bne L1579 none, exit +* lbsr L1002 Set up font counts +* bsr L158B +* inc <$0039 cursor is ON the screen +*L1579 rts + +* Cursor off +*L14F8 oim #NoCurs,Wt.BSW,y Set cursor flag to off +* Update text cursor (on gfx or text screens) from within Grfdrv +*L157A cmpy <$002E We on current window? +* bne L158A No, exit +* ldb <$0039 +* beq L158A +* lbsr L1002 setup font counts +* bsr L158B +* clr <$0039 cursor is OFF of the screen +*L158A rts + +* Handle char. under cursor on Hware Text screen +* Entry: Y=window table ptr +* Exit: Attribute byte on screen has fore/bckground colors reversed +L158B ldx Wt.Cur,y get cursor physical address + ldb <$0060 get screen type + bpl L15A5 Skip ahead if gfx screen + lda 1,x Get attribute byte of char. under cursor + bsr L15B2 Get inversed fore/bck ground colors mask into A + ldb 1,x Get original attribute byte back + andb #%11000000 Mask out all but blink & underline + IFNE H6309 + orr a,b Merge in swapped colors mask + ELSE + pshs a orb ,s+ - stb $01,x - bra L14B2 -L14A8 ldx #$5026 - stx <$00A9 - clr <$000E - lbsr L0F9A -L14B2 puls pc,y -L14B4 tfr a,b - anda #$38 - lsra - lsra - lsra - andb #$07 - lslb - lslb - lslb + ENDC + stb 1,x Set new attributes for this char + rts + +* Set attributes on Gfx screen +L15A5 pshs y Save window table ptr + ldu #GrfStrt+L10FA Setup vector for cursor on Gfx screen + clr <$000E Shut off all attributes + lbsr L106D Go put inversed char (under cursor) on screen + puls pc,y Restore window tbl ptr & return + +* Flip fore/background color masks for hardware text attribute byte +* Entry:A=attribute byte for h/ware text screen +* Exit: A=Reversed color masks +L15B2 clrb no attributes here yet + anda #%00111111 Mask out blinking, underline bits + IFNE H6309 + lsrd one byte smaller than old method + lsrd move foreground in A to background in A, + lsrd background in A to 3 high bits of B + ELSE + lsra + rorb + lsra + rorb + lsra + rorb + ENDC + lsrb shift background in B 2 bits: blink & underline + lsrb now background in A is in foreground in B + IFNE H6309 + orr b,a Merge two masks together in A + ELSE + pshs b + ora ,s+ + ENDC rts -L14C1 pshs y,x - ldx -$10,y + +* Update Gfx Cursor - UPDATE Window 'hidden' call version - Put it on scrn +L15BF pshs y,x Preserve window & screen tbl ptrs + ldx Wt.STbl,y Get scrn tbl ptr from window tbl + cmpx <$0030 Same as current screen? + bne L15E0 No, leave + ldb <$003A Get Gfx cursor XOR'd on/off flag + bne L15E0 It's already on screen, exit + ldb Wt.GBlk,y Get memory block # of gfx cursor + stb <$0044 Save in Grfdrv mem + beq L15E0 If there is no Gfx cursor defined, exit + bsr L017C Map in Gfx cursor GP buffer block + ldy Wt.GOff,y Get ptr to actual shape in block + sty <$0045 Save it in Grfdrv mem + bsr L15FE XOR mouse cursor onto screen (put it on) + inc <$003A Set Gfx cursor XOR flag to 'ON' +L15E0 puls pc,y,x Restore regs & return + +* Update Gfx cursor - from within GRFDRV - Take old one off scrn +L15E2 pshs y,x + ldx Wt.STbl,y cmpx <$0030 - bne L14E1 - ldb <$003A - bne L14E1 - ldb <$18,y - stb <$0044 - beq L14E1 - jsr <$00BC - ldy <$19,y - sty <$0045 - bsr L14FE - inc <$003A -L14E1 puls pc,y,x -L14E3 pshs y,x - ldx -$10,y - cmpx <$0030 - bne L14FC - ldb <$003A - beq L14FC - ldb <$0044 - beq L14E1 - jsr <$00BC - ldy <$0045 - bsr L14FE - clr <$003A -L14FC puls pc,y,x -L14FE ldb <$0060 - bmi L1535 - lda <$004A - ldx <$0047 - pshs x,a - ldd <$004F + bne L15FC + ldb <$003A is the Gfx cursor on the screen? + beq L15FC no, exit. + ldb <$0044 grab gfx cursor GP buffer number + beq L15E0 if none, exit + bsr L017C map in get/put buffer + ldy <$0045 grab pointer to cursor in block + bsr L15FE XOR mouse cursor onto screen (take off old one) + clr <$003A Set Gfx cursor XOR flag to 'OFF' +L15FC puls pc,y,x + +* XOR mouse cursor onto screen +L15FE ldb <$0060 Get screen type + bmi L1634 Text; exit + ldd <$004F Get original X & Y sizes ldx <$0051 - pshs x,b,a - ldd <$0064 - pshs b,a - ldd <$0041 - std <$0072 - ldb <$0043 - stb <$0074 - ldx #$5FA5 + pshs x,d Save them + ldd <$0064 Get original Pset & Lset vectors + ldx <$0068 + pshs x,d Save them + ldd <$0041 Get screen address of Gfx cursor + std <$0072 Save as GP buffer start position + ldb <$0043 Get pixel mask for start of Gfx cursor + stb <$0074 Save as GP buffer pixel mask start + ldx #GrfStrt+L1F9E Force PSET to 'off' stx <$0064 - lbsr L0D10 - lbsr L0D88 - puls b,a + ldx #GrfStrt+L1FA3 For LSET to XOR + stx <$0068 + lbsr L0E14 set up for different STY in buffer/screen + lbsr L0E97 go put the cursor on-screen + puls x,d Restore original vectors std <$0064 - puls x,b,a + stx <$0068 + puls x,d Restore original X/Y sizes std <$004F stx <$0051 - puls x,a - sta <$004A - stx <$0047 -L1535 rts -L1536 clr <$0047 - clr <$0049 - ldd -$05,y - subd -$0D,y -L153E cmpd $04,y - bcs L1549 - subd $04,y - inc <$0049 - bra L153E -L1549 lda [<-$10,y] - cmpa #$01 - beq L1556 - lsrb - cmpa #$04 - bne L1556 - lsrb -L1556 stb <$0048 - rts -L1559 tst ,y - bpl L1562 -L155D comb - ldb #$C0 - puls pc,x -L1562 lbsr L1DA2 - bcc L1569 - puls pc,x -L1569 jsr <$00B9 - lbra L1F65 - rts -L156F bsr L1559 - lbsr L1E48 - lda <$0061 - lbsr L1F06 - bra L159B -L157B bsr L1559 - lbsr L1DA9 - bcs L159C - ldd <$0049 - cmpd <$004D - bne L158D - bsr L159D - bra L159B -L158D ldd <$0047 - cmpd <$004B - bne L1598 - bsr L1607 - bra L159B -L1598 lbsr L1637 -L159B clrb -L159C rts -L159D bsr L15B6 -L159F ldd <$004B - subd <$0047 - addd <$00B3 - std <$0099 - bsr L15B0 - lda <$0061 - ldy <$0099 - bra L15C8 -L15B0 lbsr L1E9C - lbra L1E48 -L15B6 ldd <$004B - cmpd <$0047 - bge L15C3 -L15BD ldx <$0047 +L1634 rts return + +* Bring in Get/Put buffer memory bank - put into GRFDRV DAT Img @ <$87 +* Entry: B=MMU block # to get +L017C clr <$89 Make sure System Global is first + stb <$8A Save Block number of Get/Put buffer + stb >$FFA9 Save it to MMU as well + rts Return + +* LSet entry point +L06A4 ldx #GrfStrt+L06BC Point to LSET vector table + ldb Wt.LSet,y Get LSet type + cmpb #$03 If higher than 3, error + bhi L06B7 + ldb b,x Get vector offset + abx Calculate vector + stx Wt.LVec,y Save LSet table vector + jmp >GrfStrt+L0F78 Return to system without error + +L06B7 comb Return to system with Illegal argument error + ldb #E$IllArg + jmp >GrfStrt+L0118 + +* Retain "magic" spacing + IFEQ H6309 +L1FA3b equ * + pshs a + orb ,s+ + bra L1FA3c + ENDC + +* LSet vector table +L06BC fcb L1FA9-L06BC Normal vector + fcb L1FA7-L06BC AND logical vector + fcb L1FAE-L06BC OR logical vector + fcb L1FA3-L06BC XOR logical vector +* LSET routines here: affecting how pixels go on screen +* The proper vector is stored in the window table @ <$14,y +* Entry: X=address of pixel to change +* B=Bit mask of specific pixel to change (1, 2 or 4 bits) +* A=Bits to actually set (color palette #) +* A&B are also both preserved on the stack by the calling routine +* XOR +L1FA3 eora ,x EOR new bits onto what is on screen + sta ,x and save onto screen + rts 5 bytes +* AND +L1FA7 anda ,x AND new color onto what is on screen +* Normal +L1FA9 comb Make 'hole' for transparent putting + andb ,x Create mask of bits already on screen + IFNE H6309 + orr a,b Merge color & bit mask + ELSE + nop keep byte count the same + bra L1FA3b + ENDC +L1FA3c stb ,x Save new byte + rts +* OR +L1FAE ora ,x Merge new color onto screen + sta ,x and store them +L1FB2 rts return + +* do a word of pixels at one time +* This is an ALAN DEKOK MAGIC ROUTINE! Do NOT CHANGE ANYTHING +* Likewise, do NOT change any offsets at the normal pixel routines at +* L1FA3 and following! +Pix.XOR equ * + IFNE H6309 + eord ,x offset 0 + ELSE + nop + bra PEOR keep byte count same + ENDC +PXOR2 std ,x++ + rts + +Pix.AND equ * + IFNE H6309 + andd ,x offset 6 + ELSE + nop + bra PAND + ENDC +PAND2 std ,x++ + rts + + fcc /ALAND/ space fillers + +Pix.OR equ * + IFNE H6309 + ord ,x offset 17 + ELSE + ora ,x + orb 1,x + ENDC + std ,x++ + rts +* End of ATD's magic routine! + IFEQ H6309 +PEOR eora ,x + eorb 1,x + bra PXOR2 +PAND anda ,x + andb 1,x + bra PAND2 + ENDC + +* Point entry point +L1635 bsr I.point map screen and PSET block in, scale coordinates + bcs L1688 Error scaling, exit with it + lbsr L1E9D Get:X=ptr to byte on screen,B=bit mask for pixel + lda <$0061 Get foreground color + IFNE H6309 + ldw <$68 Get LSET vector + ELSE + pshs x + ldx <$68 + stx <$B5 + puls x + ENDC + jsr ,u Put pixel on screen + bra L1687 Exit without error + +* Line entry point +* ATD: Line/bar/box set up screen: saves ~40 bytes, adds 6 clock cycles +I.line lbsr L1DFD scale 2nd set of coordinates + bcs L16B0 error: exit to a convenient RTS +I.point lbsr L1884 map in window, and verify it's graphics + ldu <$64 get PSET vector for line/bar/box routines + lbra L1DF6 Scale 1st set of coords + +* Line entry point +L1654 bsr I.line internal line set up routine + bcs L1688 Error; exit + IFNE H6309 + ldw <$68 Get LSET vector + ELSE + ldd <$68 + std <$B5 + ENDC + ldd <$0049 Get 'working' Y coordinate + cmpd <$004D Same as current Y coordinate? + bne L1679 No, check X + bsr L168B Do 'fast' horizontal line + bra L1687 Return to system without error + +L1679 ldd <$0047 Get 'working' X coordinate + cmpd <$004B Same as current X coordinate? + bne L1684 No, use 'normal' line routine + lbsr L16F4 Do 'fast' vertical line + bra L1687 Return to system without error + +L1684 lbsr L1724 Do 'normal' line routine +L1687 clrb No error +L1688 jmp >GrfStrt+L0118 Return to system + +* Swap start & end X coords if backwards ($47=Start, $4B=End) +L16A3 ldd <$004B Get end X coord + cmpd <$0047 Compare with start X coord + bge L16B0 Proper order, leave +L16AA ldx <$0047 Swap the 2 X coord's around std <$0047 stx <$004B -L15C3 rts - lsl <$0004 - lsr <$0002 -L15C8 pshs u,y,x,b,a - sta $06,s - leax <L15C3,pcr - ldb <$0060 - clra - ldb b,x - std $04,s - puls x,b,a - bra L15DC -L15DA ldb <$0079 -L15DC lbsr L1F06 - leay -$01,y - beq L1605 - lbsr L1EB3 - bpl L15DC -L15E8 cmpy ,s - bcs L15DA - ldb #$FF - lbsr L1F06 - ldb $01,s - negb - leay b,y - beq L1605 - leax $01,x - ldd ,s - addd <$0047 - std <$0047 - lda $02,s - bra L15E8 -L1605 puls pc,x,b,a -L1607 bsr L1629 -L1609 ldd <$004D +L16B0 rts + +* # of pixels/byte table +L16B1 fcb $08 640x200x2 color + fcb $04 320x200x4 color + fcb $04 640x200x4 color + fcb $02 320x200x16 color + +* Fast horizontal line routine +L168B bsr L16A3 Make sure X coords in right order +L168D lbsr L1EF1 <$79=Start of byte pixel mask, <$77=Shift vector +* Entry point from FFILL +L1690 ldd <$004B Get end X coord of line + subd <$0047 # pixels wide line is + IFNE H6309 + incd +1 (base 1) + ELSE + addd #1 + ENDC + std <$0099 Save # of pixels left + lbsr L1E9D X=Mem ptr to 1st pixel, B=Mask for start pixel + lda <$0061 Get foreground color mask (full byte) + ldy <$0099 Get # pixels to do + +* "Fast" horizontal line draw +* Entry: Y = # pixels left +* A = Color bit mask +* X = Screen address +* B = mask for first pixel +* W = address of LSET routine +* U = address of PSET routine +L16B5 pshs u,y,x,d Preserve X & D, and reserve 4 bytes on stack + sta 6,s Save Full byte color mask + ldx #GrfStrt+L16B1-1 Point to # pixels/byte table + ldb <$0060 Get screen type + clra Clear high byte + ldb b,x Get # pixels/byte for screen type + std 4,s Save overtop original Y on stack + puls x,d Restore Screen ptr & Color/pixel masks + tstb is the pixel mask at the high bit of the byte? + bmi L16D5 yes, start off with a check for TFM +* bra L16C9 Start drawing + fcb $8C skip 2 bytes: same cycle time, 1 byte shorter + +* Stack now has: 0,s = # pixels per byte (2,4 or 8, 16 bit # for Y compare) +* 2,s = Color mask +* 3,s = Garbage? (LSB of U) +* Y = # pixels left in line +* Put single pixels on the screen +L16C7 ldb <$0079 Get bit mask for 1st pixel in byte +L16C9 std <$97 Save current color & bit masks + jsr ,u put pixel on the screen + leay -1,y Bump line pixel count down by 1 + lbeq L16F2 Done line, exit + ldd <$97 Get color & bit masks back +* Set up bit pattern for next pixel, including changing byte position + jsr >GrfStrt+L1F08 Set up for next pixel (scrn address & bit mask) + bpl L16C9 (1st bit would be set if next byte, keep going) +* If on last byte, Y<#pixels per byte, so will use above loop +* If not on last byte, Y>#pixels per byte, so can 'cheat' & do 1 byte at a +* time below +L16D5 cmpy ,s Done pixel count for current byte (or last byte) + blo L16C7 No, keep going +* Draw remainder of line 1 full byte (2,4 or 8 pixels) at a time +* ATD: GrfStrt+L1FA9 is the normal PUT (no fancy stuff) routine +L16D7 tfr y,d get number of pixels left into D + IFNE H6309 + divd 1,s divide it by the number of pixels in 1 byte + ELSE + clr ,-s +L16D7b inc ,s + subb 2,s + sbca #0 + bcc L16d7b + addb 2,s + tfr b,a + puls b + decb + ENDC + pshs a save remainder for later + clr ,-s and make remainder on-stack 16-bit + pshs b save number of bytes to do + +* now we have: +* B = number of bytes to do a full byte at a time +* 0,S = number of bytes to do a full byte at a time +* 1,s = remainder of pixels in last byte to do +* 3,s = pixels per byte +* 5,s = color mask + + lda #(GrfStrt+L1F9E)&$00FF point to NO pset vector + cmpa <$64+1 is it just a normal color routine? + bne L16E2 no, it's a PSET, so go do it especially + + IFNE H6309 + cmpw #GrfStrt+L1FA9 is it the normal PUT routine? + ELSE + pshs x + ldx <$B5 + cmpx #GrfStrt+L1FA9 + puls x + ENDC + bne L16E0 no, go use old method + + clra + IFNE H6309 + tfr d,w into TFM counter register + ENDC + leay 5,s point to full byte color mask + IFNE H6309 + tfm y,x+ move everything else a byte at a time +* LDW MUST go before the call to L16F2! + ldw #GrfSTrt+L1FA9 and restore vector to normal PUT routine + ELSE + pshs x,u + tfr x,u + tfr d,x + lda ,y +L16DEb sta ,u+ + leax -1,x + bne L16DEb + ldd #GrfSTrt+L1FA9 + std <$B5 + stu ,s + puls x,u + ENDC +L16DE puls b restore number of full bytes to do + lda 3,s get number of pixels per byte + mul get number of pixels done + addd <$47 add to current X coordinate + std <$47 and save as current X coordinate +L16DF ldy ,s++ restore 16-bit remainder of pixels: GET CC.Z bit + beq L16F2 exit quickly if done all of the bytes + lda 2,s get pixel mask + bra L16C7 and do the last few pixels of the line + +L16E0 lsrb divide by 2 + beq L16E2 only 1 pixel to do, go do it. + +* here we have 2 or more pixels to do full-byte, so we go to a method +* using D: much magic here! +* W = pointer to LSET routine +* U = pointer to routine that does ANDR B,A JMP ,W + IFNE H6309 + subw #GrfStrt+L1FA3 point to start of LSET routines + ELSE + pshs d + ldd <$B5 + subd #GrfSTrt+L1FA3 + std <$B5 + puls d + ENDC + beq pix.do skip fancy stuff for XOR + IFNE H6309 + incf go up by one byte + ELSE + inc <$B6 + ENDC +pix.do ldu #GrfStrt+Pix.XOR point to double-byte pixel routines + IFNE H6309 + leau f,u point U to the appropriate routine + tfr b,f move counter to a register + ELSE + pshs a + lda <$B6 + leau a,u + stb <$B6 + puls a + ENDC +pix.next lda 5,s grab full-byte color mask + tfr a,b make D=color mask + jsr ,u call 2-byte routine + IFNE H6309 + decf + ELSE + dec <$B6 + ENDC + bne pix.next + IFNE H6309 + ldw <$68 get LSET vector + ELSE + ldu <$68 + stu <$B5 + ENDC + ldu <$64 and PSET vector again + ldb ,s get number of bytes left to do: do NOT do PULS! + andb #1 check for odd-numbered bytes + beq L16DE if done all the bytes, exit: does a PULS B + stb ,s save the count of bytes to do: =1, and do one byte + +* PSET+LSET full byte line draws come here +L16E2 ldb #$FF Full byte bit mask + lda 5,s Get color mask + jsr ,u put the pixel on the screen + leax 1,x Bump screen ptr up by 1 + ldd 3,s get number of pixels per byte + addd <$0047 Update 'working' X-cord to reflect pixels we did + std <$0047 Save result + dec ,s decrement counter + bne L16E2 continue until done + leas 1,s kill the counter off of the stack + bra L16DF restore 16-bit pixel remainder, and do last byte + +L16F2 puls pc,x,d Restore regs & return when done + +* Fast vertical line routine +L16F4 bsr L1716 Make sure Y coords in right order +L16F6 ldd <$004D Calculate height of line in pixels subb <$004A - incb - std <$0099 - lbsr L1E48 - stb <$0097 - lda <$0061 - ldy <$0099 -L161A ldb <$0097 - lbsr L1F06 - ldb <$0063 - abx - inc <$004A - leay -$01,y - bne L161A + incb Base 1 + std <$0099 Save height + lbsr L1E9D Calculate screen address & pixel mask + lda <$0061 Get color mask + std <$0097 Save color & pixel masks + ldy <$0099 Get Y pixel counter +L1707 ldd <$0097 Get color & pixel mask + jsr ,u Put pixel on screen + ldb <$0063 Get # bytes to next line on screen + abx Point to it + inc <$004A Bump up working Y coord + leay -1,y Dec. Y counter + bne L1707 Do until done rts -L1629 ldd <$004D - cmpd <$0049 - bge L1636 -L1630 ldx <$0049 + +* Swap Y coords so lower is first +L1716 ldd <$004D Get current Y coord + cmpd <$0049 Compare with destination Y coord + bge L1723 If higher or same, done +L171D ldx <$0049 std <$0049 stx <$004D -L1636 rts -L1637 ldd <$004B - cmpd <$0047 - bge L1647 - lbsr L15BD - ldd <$004D - bsr L1630 - ldd <$004B -L1647 subd <$0047 - std <$0013 - ldb <$0063 - clra - std <$0017 - ldd <$004D - subd <$0049 - std <$0015 - bpl L1666 - nega - negb - sbca #$00 - std <$0015 - ldd <$0017 - nega - negb - sbca #$00 - std <$0017 -L1666 clra - clrb - std <$0075 - lbsr L15B0 - stb <$0074 -L166F ldb <$0074 - lda <$0061 - lbsr L1F06 - ldd <$0075 - bpl L168C - addd <$0013 - std <$0075 - ldd <$0017 - leax d,x - bmi L1688 - inc <$004A - bra L1697 -L1688 dec <$004A - bra L1697 -L168C subd <$0015 - std <$0075 - ldb <$0074 - lbsr L1EB3 - stb <$0074 -L1697 ldd <$0047 - cmpd <$004B - ble L166F - rts -L169F clra - clrb - std <$0053 - std <$0055 -L16A5 lbsr L1559 -L16A8 lbsr L1DA9 - bcc L16AE +L1723 rts + +* Next pixel calcs - See if <$47 could not be done outside the loop by a +* simple ADDD (if needed at all) +* If it is needed in loop for some, simply have the ones that don't need to +* come in at L1F0E instead +* Called from Fast Horizontal Line L16C9, Normal Line L177D, Flood Fill L1CD4 +* Entry: <$0047 = Working X coord +* B=Bit mask for current pixel +* X=Screen address +* Exit: +* B=Bit mask for new pixel (high bit set if starting new byte) +* X=New screen address (may not have changed) +* ATD: Could replace calls to L1F08 with jsr [>GrfMem+gr0077], and move 'lsrb's +* from L1F14 here, to the TOP of the routine. That would convert a +* JSR >foo, JMP[>GrfMem+gr0077] to a jsr [>], saving 4 cycles, adding 2 bytes per call +* Also, the 'inc' does NOT affect the carry. +L1F08 inc <$0048 Inc LSB of working X coord + bne L1F0E Didn't wrap, skip ahead + inc <$0047 Inc MSB of working X coord +L1F0E lsrb Shift to next bit mask + bcs L1F18 Finished byte, reload for next + jmp [>GrfMem+gr0077] Shift B more (if needed) depending on scrn type + +L1F18 ldb #1 Bump screen address by 1 + abx + ldb <$0079 Get start single pixel mask (1,2 or 4 bits set) rts -L16AE lbsr L15B6 -L16B1 lbsr L1629 -L16B4 lbsr L1DD4 - leas <-$1A,s - sty ,s - ldd <$0053 - std $0A,s - ldd <$0055 - std $0C,s - ldd <$0047 - std $02,s - addd <$0053 - std $0E,s - std <$0047 - ldd <$0049 - std $04,s - addd <$0055 - std <$12,s - ldd <$004B - std $06,s - subd <$0053 - std <$10,s - std <$004B - ldd <$004D - std $08,s - subd <$0055 - std <$14,s - lbsr L159F - ldd $0E,s - std <$0047 - ldd $08,s - std <$0049 - ldy ,s - lbsr L159F - ldd $02,s - std <$0047 - ldd <$12,s - std <$0049 - ldd <$14,s - std <$004D - ldy ,s - lbsr L1609 - ldd <$12,s - std <$0049 - ldd $06,s - std <$0047 - ldy ,s - lbsr L1609 - ldb <$0054 - beq L1786 - lda #$FF - sta <$00AD - negb - std <$16,s - ldb <$0056 - negb - std <$18,s - bsr L1791 - ldd $0E,s - std <$0047 - ldd <$12,s - std <$0049 - ldd <$16,s - std <$0020 - ldd <$18,s - std <$0026 - bsr L178C - ldd <$10,s - std <$0047 - ldd <$12,s - std <$0049 - ldd <$18,s - std <$0022 - ldd <$0053 - std <$0024 - bsr L178C - ldd $0E,s - std <$0047 - ldd <$14,s - std <$0049 - ldd <$0055 - std <$0022 - ldd <$16,s - std <$0024 - bsr L178C - ldd <$10,s - std <$0047 - ldd <$14,s - std <$0049 - ldd <$0053 - std <$0020 - ldd <$0055 - std <$0026 - bsr L178C -L1786 leas <$1A,s - clr <$00AD + +* Normal line routine +L1724 ldd <$004B current X + cmpd <$0047 HBX, LBX + bge L1734 + lbsr L16AA swap x-coordinates around + ldd <$004D current Y + bsr L171D swap Y coordinates around + ldd <$004B get high X +L1734 subd <$0047 subtract out low X + std <$0013 save x-count to do + ldb <$0063 BPL + clra + std <$0017 save 16-bit bytes per line + ldd <$004D high Y + subd <$0049 subtract out low Y + std <$0015 save y-count to do + bpl L1753 if positive + IFNE H6309 + negd + ELSE + coma + comb + addd #1 + ENDC + std <$0015 invert y-count if negative (make it positive) + ldd <$0017 invert BPL, too. Why? + IFNE H6309 + negd + ELSE + coma + comb + addd #1 + ENDC + std <$0017 +* ATD: If we get _really_ fancy, have this do a DIVD for X and Y, and +* figure out how many sub-lines to do, and call the main line to do each. +* that way any horizontal/vertical sections will use optimized routines +* above +* vertical sections can call L16F4 directly, I think... +* +L1753 equ * + IFNE H6309 + clrd + ELSE + clra + clrb + ENDC + std <$0075 counter + lbsr L1EF1 Set up <$77 bit shift vector & <$79 pixel mask + lbsr L1E9D Calculate screen addr into X & pixel mask into B + stb <$0074 Save pixel mask +L1760 ldb <$0074 Get pixel mask + lda <$0061 Get color mask + jsr ,u + ldd <$0075 grab counter + bpl L177D if positive + addd <$0013 add in number of X-pixels to do + std <$0075 save it + ldd <$0017 get BPL + IFNE H6309 + addr d,x go up/down + ELSE + leax d,x + ENDC + bmi L1779 + inc <$004A go down one y-line + bra L1788 + +L1779 dec <$004A decrement y-count + bra L1788 + +L177D subd <$0015 take out one BPL + std <$0075 save new count + ldb <$0074 grab pixel mask + bsr L1F08 go right one pixel + stb <$0074 save new pixel mask +L1788 ldd <$0047 grab X-start + cmpd <$004B at X-end yet? + ble L1760 no, continue rts -L178C ldy $02,s - bsr L1807 -L1791 clra - clrb - std <$0020 - std <$0022 - std <$0024 - std <$0026 - ldd $0C,s - std <$0053 - ldd $0E,s - std <$0055 - rts -L17A4 lbsr L1559 - lbsr L1DA9 - bcs L17E6 - lbsr L15B6 - lbsr L1629 - ldd <$0047 - std <$0099 - ldd <$004B - subd <$0047 - addd <$00B3 - std <$009B - lbsr L15B0 - lda <$0061 - std <$009D + +* Box entry point +* The optimizations here work because the special-purpose horizintal and +* vertical line routines only check start X,Y and end X OR Y, not BOTH of +* the end X,Y. We can use this behaviour to leave in end X or Y coordinates +* that we want to use later. +* Possible problem: If the normal line routine is fixed to work properly, +* there won't be much need for the fast vertical line routine, and we'll have +* to fix up the X coordinates here. +L1790 lbsr I.Line internal line/bar/box setup + bcs L17F9 Error; exit + lbsr L16A3 Make sure X coords in right order + lbsr L1716 Make sure Y coords in right order + leas -4,s Make 4 byte buffer on stack + IFNE H6309 + ldq <$47 Copy upper left coords: SX,SY + stq ,s save on the stack + ELSE + ldd <$49 + std 2,s + ldd <$47 + std ,s + ENDC + pshs y Save window table ptr + IFNE H6309 + ldw <$68 Get LSET vector + ELSE + pshs x + ldx <$68 + stx <$B5 + puls x + ENDC +* enters with SX,SY ; EX,EY + lbsr L168D Do fast horizontal line: 0,0 -> X,0 +* leaves with $47-$4D = EX+1,SY ; EX,EY + ldd <$4B grab EX+1 (incremented after line) + std <$47 save proper EX + ldy ,s grab window table pointer again: for L1E9D call + lbsr L16F6 Do fast vertical line: X,0 -> X,Y +* leaves with $47-$4D = EX,EY+1 ; EX,EY + ldd 4,s get SY + std <$49 save SY again + ldd 2,s get SX + std <$47 save SX again + ldy ,s get window table ptr +* enters with SX,SY ; EX,EY + lbsr L16F6 Do other fast vertical line 0,0 -> 0,Y +* leaves with $47-$4D = SX,EY ; EX,EY + ldy ,s restore window table pointer + ldd <$4D grab EY+1 (incremented after line) + std <$49 save EY + lbsr L168D Do final fast horizontal line: 0,Y -> X,Y + leas 6,s Eat stack buffer + clrb No error & return +L17F9 jmp >GrfStrt+L0118 + +* Bar entry point +L17FB lbsr I.Line internal line/bar/box routine + bcs L1853 + lbsr L16A3 Make sure X coords in right order + lbsr L1716 Make sure Y coords in right order + IFNE H6309 + ldw <$68 Get LSET vector + ELSE + ldd <$68 + std <$B5 + ENDC + +* internal BAR routine called from CLS for non-byte boundary clear to EOL +i.bar ldd <$0047 grab start X coordinate + std <$0099 save it for later + subd <$4B take out end X coordinate + IFNE H6309 + negd negate it + incd add one + ELSE + coma + comb + addd #2 + ENDC + std <$9B save for later + lbsr L1EF1 Set up <$79 bit mask & <$77 bit shft vector + lbsr L1E9D Calculate scrn ptr & 1st bit mask + lda <$0061 Get color mask + std <$009D Save color mask & pixel mask ldd <$004D subb <$004A incb - tfr d,y -L17CC pshs y,x + tfr d,y Move # horizontal lines to draw to Y +L1839 pshs y,x Preserve # lines left & screen ptr ldy <$009B - ldd <$009D - lbsr L15C8 - puls y,x - ldb <$0063 + ldd <$009D Get color & pixel masks + lbsr L16B5 Do fast horizontal line + puls y,x Get # lines left & screen ptr + ldb <$0063 Bump ptr to start of next line in bar abx - inc <$004A - ldd <$0099 - std <$0047 - leay -$01,y - bne L17CC - clrb -L17E6 rts -L17E7 ldx #$5BDB - bra L17EF -L17EC ldx #$5A13 -L17EF stx <$002C - bsr L1822 - ldd <$0053 - lsra - rorb - std <$0055 - bra L1863 -L17FB bsr L1822 - lbsr L1DB1 - bcs L17E6 - lbsr L1DD0 - bcs L17E6 -L1807 ldx #$5A13 - stx <$002C - ldd <$0020 - cmpd <$0024 - bne L182B - ldx #$5A34 - ldd <$0022 - cmpd <$0026 - blt L184D - ldx #$5A39 - bra L184D -L1822 jsr <$00B9 - ldb <$0060 - lbmi L155D -L182A rts -L182B ldx <$0022 - cmpx <$0026 - bne L183E - ldx #$5A3E - cmpd <$0024 - blt L184D - ldx #$5A44 - bra L184D -L183E ldx #$5A4A - ldd <$0020 - subd <$0024 - std <$0097 - ldd <$0022 - subd <$0026 - std <$0099 -L184D stx <$00A1 - bra L1868 -L1851 lbsr L1ACE - lbra L1B69 -L1857 ldx #$5BDB - bra L185F -L185C ldx #$5A13 -L185F stx <$002C - bsr L1822 -L1863 ldx #$5A4E - stx <$00A1 -L1868 lbsr L1F65 - tst <$00AD - bne L1879 - lbsr L1DA2 - bcs L182A - lbsr L1DD4 - bcs L182A -L1879 ldd <$0047 - std <$0018 - ldd <$0049 - std <$001A - clra - clrb - std <$001C - ldd <$0055 - std <$001E - leas <-$3E,s - sty <$3C,s - leax $05,s - ldd <$0053 - lbsr L1AC5 - lbsr L1B2E + inc <$004A Bump up Y coord + ldd <$0099 get saved starting X coordinate + std <$0047 save as current X coordinate + leay -1,y Bump line counter + bne L1839 Draw until done + clrb No error & return +L1853 jmp >GrfStrt+L0118 + +* Circle entry point +L1856 bsr L1884 Make sure window is graphics + ldd <$53 Get radius (horizontal) + IFNE H6309 + lsrd Calculate vertical radius for 'perfect circle' + ELSE + lsra + rorb + ENDC + std <$55 Vertical radius=Horizontal radius/2 + bra L18BF Go to appropriate place in ellipse routine + +* Arc entry point +L1860 bsr L1884 Make sure window is graphics + lbsr L1E05 Go scale start 'clip' coords, check if legal + bcs L1853 Illegal coordinate, exit with error + lbsr L1E24 Go scale end 'clip' coords, check if legal + bcs L1853 Illegal coordinate, exit with error + ldd <$0020 Get start clip X coord + cmpd <$0024 Same as end clip X coord? + bne L188E No, skip ahead + ldx #GrfStrt+L1A9D Point to vertical line clip vector + ldd <$0022 Get start clip Y coord + cmpd <$0026 Same as end clip Y coord? + blt L18B3 If lower, skip ahead + ldx #GrfStrt+L1AA4 End X clip is to right of Start vector + bra L18B3 Go save vector & continue + +L1884 lbsr L0177 Map in window + ldb <$60 Get screen type + lbmi L0569 If text, return with Error 192 + ldb Wt.PBlk,y Get Pattern memory block + beq L18BC None, exit to a convenient RTS + lbra L017C Map that block in + +* Different X coord clip coords +L188E ldx <$0022 Get start Y coord + cmpx <$0026 Same as end Y coord? + bne L18A3 No, skip ahead + ldx #GrfStrt+L1AAB Point to horizontal line clip vector + cmpd <$0024 Is start X coord left of end X coord? + blt L18B3 Yes, use this vector + ldx #GrfStrt+L1AB1 Point to horizontal line/to right vector + bra L18B3 Go save the vector & continue + +* Different X & Y clip coords +L18A3 ldx #GrfStrt+L1AB7 Point to 'normal' Arc Clip line vector + ldd <$0020 Get start X coord + subd <$0024 Calculate X clip line width + std <$0097 Save it + ldd <$0022 Get start Y coord + subd <$0026 Calculate Y clip line height + std <$0099 Save it + bra L18B3 Go save vector & continue + +L18B7 lbsr L1B3B Copy 5 byte integer from ,Y to ,X +* Shift 5 byte number pointed to by X to the left 1 bit +L1BDD lsl 4,x (four 7 cycles & one 6 cycle) + IFNE H6309 + ldq ,x Get rest of 5 byte # + rolw Shift it all left + rold + stq ,x Store result + ELSE + ldd 2,x + rolb + rola + std 2,x + std <$B5 + ldd ,x + rolb + rola + std ,x + ENDC +L18BC rts Exit + +* Ellipse entry point +L18BD bsr L1884 Make sure we are on graphics screen +L18BF ldx #GrfStrt+L1ABB Point to 'no clipping' routine +L18B3 stx <$A1 Preserve clipping vector +* Clipping vector setup, start processing ARC +L18C5 lbsr L1DF6 Make sure coord's & scaling will work + bcs L18D4 Error, return to system with error # + lbsr L1E28 Go make sure X & Y Radius values are legit +L18D4 lbcs L1A75 Nope, exit with error + IFNE H6309 + ldq <$47 Get Draw pointer's X & Y Coordinates + stq <$18 Make working copies + clrd Set some variable to 0 + ELSE + ldd <$47 + std <$18 + ldd <$49 + std <$1A + clra + clrb + ENDC + std <$1C Store it + ldd <$55 Get Y radius value + std <$1E Move to working area + leas <-$3E,s Make a 62 byte working stack area + sty <$3C,s Preserve Y in last 2 bytes of stack area + leax $05,s Point X into stack working area + ldd <$0053 Get horizontal radius + lbsr L1BA1.0 ATD: lbsr L1B32 moved for size tfr x,y leax <$14,s ldd <$0055 - lbsr L1B3E + lbsr L1BB1 leax $0A,s - bsr L1851 + bsr L18B7 tfr x,y leax $0F,s - bsr L1851 + bsr L18B7 leax <$19,s ldd <$0055 - lbsr L1AC5 - lbsr L1B2E + lbsr L1BA1.0 ATD: lbsr L1B32 moved for size tfr x,y leax <$1E,s - bsr L1851 + bsr L18B7 tfr x,y leax <$23,s - bsr L1851 + bsr L18B7 leax <$28,s - clra - clrb - lbsr L1AC5 + lbsr L1B32.0 ATD: CLRD moved for size leax <$2D,s ldd <$001E - lbsr L1AC5 - subd <$00B3 - lbsr L1B2E + lbsr L1B32 + IFNE H6309 + decd Doesn't affect circle + ELSE + subd #1 + ENDC + lbsr L1BA1 leay $0A,s - lbsr L1B40 + lbsr L1BB4 leay $05,s - bsr L1960 + bsr L19C3 leax ,s - bsr L1963 - ldd <$00B3 - lbsr L1AF0 + bsr L19C6 + lbsr L1B63 ATD: LDD moved for size leay <$1E,s - lbsr L1B40 + lbsr L1BB4 tfr x,y - leax <$2D,s - bsr L1960 + bsr L19C3.0 ATD: LEAX moved for size + leax <$32,s + bsr L19C6.0 ATD: LEAY moved for size + bsr L19C0.0 ATD: LDD moved for size + leax <$37,s + leay <$1E,s + lbsr L1B3B +L1970 leax <$14,s + leay <$28,s + lbsr L1C2E + ble L19CC + lbsr L1A78 + tst <$2D,s + bmi L19A0 leax <$32,s leay $0F,s - bsr L1963 - ldd <$001E - bsr L195D - leax <$37,s - leay <$1E,s - lbsr L1ACE -L190F leax <$14,s - leay <$28,s - lbsr L1BBA - ble L1969 - lbsr L1A0C - tst <$2D,s - bmi L193E - leax <$32,s - leay $0F,s - bsr L1960 + bsr L19C3 tfr x,y - leax <$2D,s - bsr L1960 + bsr L19C3.0 ATD: LEAX moved for size leax <$14,s leay $05,s - lbsr L1B1F + +* [X] = [X] - [Y] : leave [Y] alone +* ONLY called once. Moving it would save 1 byte (rts) (save LBSR, convert +* 3 BSRs to LBSRs), and save +* one LBSR/rts (11 cycles), and convert 3 BSR to LBSR (+3) +* can also get rid of superfluous exg x,y at the end of the routine +* used to be a stand-alone routine +L1B92 lbsr L1C11.0 negate 5 byte [Y]: ATD: EXG X,Y moved for size + exg x,y + lbsr L1B7A 40 bit add: [X] = [X] + [Y] + lbsr L1C11.0 negate 5 byte int: ATD: EXG X,Y moved for size ldd <$001E - subd <$00B3 + IFNE H6309 + decd Doesn't affect circle + ELSE + subd #1 + ENDC std <$001E -L193E leax <$37,s +L19A0 leax <$37,s leay <$23,s - bsr L1960 + bsr L19C3 tfr x,y - leax <$2D,s - bsr L1960 + bsr L19C3.0 ATD: LEAX moved for size leax <$28,s leay <$19,s - bsr L1960 + bsr L19C3 ldd <$001C - addd <$00B3 + IFNE H6309 + incd Doesn't affect circle + ELSE + addd #1 + ENDC std <$001C - bra L190F -L195D lbra L1B2E -L1960 lbra L1B07 -L1963 lbsr L1ACE - lbra L1B9D -L1969 leax <$2D,s + bra L1970 + +L19C0.0 ldd <$001E ATD: moved here for size +L19C0 jmp >GrfStrt+L1BA1 + +L19C3.0 leax <$2D+2,s ATD: moved here for size +L19C3 jmp >GrfStrt+L1B7A add 40 bit [X] = [X] + [Y] + +L19C6.0 leay <$0F+2,s ATD: moved here for size +L19C6 lbsr L1B3B + jmp >GrfStrt+L1C11 negate 5-byte integer + +L19CC leax <$2D,s ldd <$001C - lbsr L1AC5 - addd <$00B3 - bsr L195D + lbsr L1B32 + IFNE H6309 + incd Doesn't affect circle + ELSE + addd #1 + ENDC + bsr L19C0 leay <$1E,s - lbsr L1B40 + lbsr L1BB4 leax ,s ldd <$001E - lbsr L1AC5 + lbsr L1B32 subd #$0002 - bsr L195D - ldd <$00B3 - lbsr L1AF0 + bsr L19C0 + lbsr L1B63 ATD: LDD moved for size leay $0A,s - lbsr L1B40 + lbsr L1BB4 tfr x,y - leax <$2D,s - bsr L1960 + bsr L19C3.0 ATD: LEAX moved for size leax ,s leay $0A,s - bsr L1963 - ldd <$00B3 - lbsr L1AF0 + bsr L19C6 + lbsr L1B63 ATD: LDD moved for size leay <$19,s - lbsr L1B40 + lbsr L1BB4 tfr x,y - leax <$2D,s - bsr L1960 + bsr L19C3.0 ATD: LEAX moved for size leax <$32,s leay <$23,s - lbsr L1ACE + lbsr L1B3B ldd <$001C - bsr L195D + bsr L19C0 leax <$37,s - leay $0F,s - bsr L1963 - ldd <$001E - bsr L195D + bsr L19C6.0 ATD: LEAY moved for size + bsr L19C0.0 ATD: LDD moved for size leay $0A,s - bsr L1960 -L19CC ldd <$001E - addd <$00B3 - beq L1A07 - bsr L1A0C + bsr L19C3 +L1A32 ldd <$001E + cmpd #$FFFF change to INCD? + beq L1A71 won't be affected by INCD: exit routine + bsr L1A78 draw pixel: shouldn't be affected by INCD tst <$2D,s - bpl L19EE + bpl L1A57 leax <$32,s leay <$23,s - bsr L1A04 - tfr x,y - leax <$2D,s - bsr L1A04 - ldd <$001C - addd <$00B3 - std <$001C -L19EE leax <$37,s - leay $0F,s - bsr L1A04 + bsr L1A6E tfr x,y - leax <$2D,s - bsr L1A04 - ldd <$001E - subd <$00B3 - std <$001E - bra L19CC -L1A04 lbra L1B07 -L1A07 leas <$3E,s - clrb - rts -L1A0C ldy <$3E,s - jmp [<$2C,u] + bsr L1A6E.0 ATD: LEAX moved for size ldd <$001C - ldx <$001E - bsr L1A2E - nega - negb - sbca #$00 - bsr L1A2E - exg d,x - nega - negb - sbca #$00 + IFNE H6309 + incd Doesn't affect Circle + ELSE + addd #1 + ENDC + std <$001C +L1A57 leax <$37,s + leay $0F,s + bsr L1A6E + tfr x,y + bsr L1A6E.0 ATD: LEAX moved for size + ldd <$001E + IFNE H6309 + decd Doesn't affect circle + ELSE + subd #1 + ENDC + std <$001E + bra L1A32 + +L1A6E.0 leax <$2D+2,s ATD: moved here for size +L1A6E jmp >GrfStrt+L1B7A + +L1A71 leas <$3E,s + clrb +L1A75 jmp >GrfStrt+L0118 + +* Draw all 4 points that one calculation covers (opposite corners) +* (Ellipse & Circle) +L1A78 ldy <$3E,s Get window table ptr back (for [>GrfMem+gr00A1]) + ldd <$001C grab current X offset from center + ldx <$001E grab current Y offset from center +* At this point, add check for filled flag. If set, put x,y pairs in +* for line command call (with bounds checking) & call line routine 2 times +* (once for top line, once for bottom line) + tst <$b2 We doing a Filled Ellipse/Circle? + beq NotFill No, do normal + bsr SetX Do any adjustments to start X needed + std <$47 Save as start X + std <$AD Save copy + ldd <$1C Get current X offset again + IFNE H6309 + negd Negate for coord on other side of radius + ELSE + coma + comb + addd #1 + ENDC + bsr SetX Do any adjustments + std <$4b Save end X coord + std <$AF Save Copy + tfr x,d Copy current Y offset into D + pshs x,y,u Preserve regs for HLine call + bsr DoHLine Do line (if necessary) + ldy 2,s Get window table ptr back for checks + IFNE H6309 + ldq <$AD Get original X coords back + std <$47 Save Start X + stw <$4b Save End X + ELSE + ldd <$AF + std <$B5 + std <$4b + ldd <$AD + std <$47 + ENDC + ldd ,s Get Y coord back + IFNE H6309 + negd Negate for coord on other side of radius + ELSE + coma + comb + addd #1 + ENDC + bsr DoHLine Do line (if necessary) + puls x,y,u,pc Restore regs & return + +* NOTE: THIS WILL MODIFY <$47 AS IT GOES THROUGH THE LINE! +DoHLine bsr SetY Do Y adjustments + cmpa #$FF Off window? + beq SaveStrX Yes, return without drawing + std <$49 Save Y coord for fast horizontal line + IFNE H6309 + ldw <$68 Get LSET vector + ELSE + ldu <$68 + stu <$B5 + ENDC + ldu <$64 Get PSET vector + jmp >GrfStrt+L168B Call fast horizontal line & return from there + +* Calc X coord & make sure in range +SetX addd <$18 Add X center point + bmi OffLeft Off left hand side, use 0 + cmpd Wt.MaxX,y Past right hand side? + bls SaveStrX No, save start X + ldd Wt.MaxX,y Get right side of window +SaveStrX rts + +OffLeft equ * + IFNE H6309 + clrd 0 X Coord start + ELSE + clra + clrb + ENDC + rts + +* Calc Y coord & make sure in range +SetY addd <$1a Add Y center point + bmi OffTop Off top, not drawable + cmpd Wt.MaxY,y Past bottom? + bhi OffTop Yes, not drawable +SaveStrY rts + +OffTop lda #$FF Flag that it is off the window + rts + +* Not filled circle or ellipse +NotFill bsr L1A97 Draw X,Y + IFNE H6309 + negd invert X + ELSE + coma + comb + addd #1 + ENDC + bsr L1A97 Draw -X,Y + exg d,x Invert Y + IFNE H6309 + negd invert X + ELSE + coma + comb + addd #1 + ENDC exg d,x - bsr L1A2E - ldd <$001C - bsr L1A2E - rts -L1A2E pshs x,b,a - jmp [>$00A1,u] - cmpd <$0020 - bra L1A46 - cmpd <$0020 - bra L1A40 - cmpx <$0022 -L1A40 ble L1A4E - bra L1A70 - cmpx <$0022 -L1A46 bge L1A4E - bra L1A70 - bsr L1A72 - bgt L1A70 -L1A4E addd <$0018 - bmi L1A70 - cmpd <$1B,y - bhi L1A70 - std <$0047 + bsr L1A97 Draw inverted X, inverted Y pixel + ldd <$001C Last, draw X,-Y +L1A97 pshs x,d Preserve x,y coords + jmp [>GrfMem+gr00A1] Draw point (L1ABB if circle/ellipse) + +* NOTE: THE FOLLOWING 6 LABELS (L1A9D, L1AA4, L1AAB, L1AB1, L1AB7 & L1ABB) +* ARE POINTED TO BY >GrfMem+gr00A1, DEPENDING ON WHETHER ARC IS ON OR NOT, AND THE +* COORDINATES ARE WITHIN CERTAIN BOUNDARIES. THE ENTRY CONDITIONS FOR ALL +* 6 OF THESE ARE: +* D=X coord offset from center point +* X=Y coord offset from center point +* (ARC) Vertical clip line, start Y > end Y coord vector +L1A9D cmpd <$0020 >= start clip X coord? + bge L1ABB Yes, go draw point + puls pc,x,d No, return + +* (ARC) Vertical clip line, start Y < end Y coord vector +L1AA4 cmpd <$0020 <= start clip X coord? + ble L1ABB Yes, go draw point + puls pc,x,d No, return + +* (ARC) Horizontal clip line, start X < end X coord vector +L1AAB cmpx <$0022 <= start clip Y coord? + ble L1ABB Yes, go draw point + puls pc,x,d No, return + +* (ARC) Horizontal clip line, start X > end X coord vector +L1AB1 cmpx <$0022 >= start clip Y coord? + bge L1ABB Yes, go draw point + puls pc,x,d No, return + +* (ARC) Clip line is diagonal in some way +L1AB7 bsr L1ADF Check if within range of diagonal clip line + bgt L1ADD If out of range, don't put pixel on screen +* Entry point for 'No clipping' routine pixel put +* Entry: D=X offset from center point +* X=Y offset from center point +L1ABB addd <$0018 Add X offset to center point X + bmi L1ADD Off of left side of window, don't bother + cmpd Wt.MaxX,y Past right side of window? + bhi L1ADD Yes, don't bother + std <$0047 Save X for Point routine + tfr x,d Move Y offset to D + addd <$001A Add Y offset to center point Y + bmi L1ADD Off of top of window, don't bother + cmpd Wt.MaxY,y Past bottom of window? + bhi L1ADD Yes, don't bother + std <$0049 Save Y coord for Point routine + lbsr L1E9D Calculate scrn addr:X, bit mask into B + lda <$0061 Get color mask + IFNE H6309 + ldw <$68 Get LSET vector + ELSE + pshs x + ldx <$68 + stx <$B5 + puls x + ENDC + jsr [>GrfMem+gr0064] Put pixel on screen +L1ADD puls pc,x,d Restore regs & return + +* Uses signed 16x16 bit multiply +* Called by Arc (probably in clipping coordinates) +L1ADF pshs x,d + leas -4,s tfr x,d - addd <$001A - bmi L1A70 - cmpd <$1D,y - bhi L1A70 - std <$0049 - lbsr L1E48 - lda <$0061 - lbsr L1F06 -L1A70 puls pc,x,b,a -L1A72 pshs x,b,a - tfr x,d - subd <$0026 - ldx <$0097 - bsr L1A90 - pshs x,b - ldd $03,s - subd <$0024 - ldx <$0099 - bsr L1A90 - cmpb ,s - bne L1A8C - cmpx $01,s -L1A8C leas $03,s - puls pc,x,b,a -L1A90 pshs x,b,a - lda $03,s - mul - pshs b,a - lda $05,s - ldb $02,s - mul - addb ,s+ - adca #$00 - pshs b,a - ldd $04,s - mul - addd ,s - std ,s - lda $05,s - ldb $03,s - mul - addb ,s - ldx $01,s - tst $03,s - bpl L1ABA - neg $06,s - addb $06,s -L1ABA tst $05,s - bpl L1AC2 - neg $04,s - addb $04,s -L1AC2 leas $07,s + subd <$26 + IFNE H6309 + muld <$97 Calculate 1st result + stq ,s Save 24 bit result + ELSE + pshs x,y,u + ldx <$97 + bsr MUL16 + sty 6,s + stu 8,s + stu <$B5 + puls x,y,u + ENDC + ldd 4,s + subd <$24 + IFNE H6309 + muld <$99 Calculate 2nd result + ELSE + pshs x,y,u + ldx <$99 + bsr MUL16 + stu <$B5 + tfr y,d + puls x,y,u + ENDC + cmpb 1,s Compare high byte with original multiply + bne L1AF9 Not equal, exit with CC indicating that + IFNE H6309 + cmpw 2,s Check rest of 24 bit # + ELSE + ldd <$B5 + cmpd 2,s + ENDC +L1AF9 leas 4,s Eat our buffer + puls pc,x,d Restore regs & return + + IFEQ H6309 +MUL16 pshs d,x,y,u XmulD returns Y&U + clr 4,s + lda 3,s + mul + std 6,s + ldd 1,s + mul + addb 6,s + adca #0 + std 5,s + ldb ,s + lda 3,s + mul + addd 5,s + std 5,s + bcc MUL16b + inc 4,s +MUL16b lda ,s + ldb 2,s + mul + addd 4,s + clra + std 4,s + puls d,x,y,u,pc + ENDC + +L1B32.0 equ * + IFNE H6309 + clrd ATD: moved here for size +L1B32 clrw + stw ,x + ste 2,x + ELSE + clra + clrb +L1B32 pshs d + clra + clrb + std <$B5 + std ,x + sta 2,x + puls d + ENDC + std 3,x rts -L1AC5 clr ,x - clr $01,x - clr $02,x - std $03,x - rts -L1ACE pshs b,a + +L1B3B pshs d + IFNE H6309 + ldq ,y + stq ,x + ELSE + ldd 2,y + std <$B5 + std 2,x ldd ,y std ,x - ldd $02,y - std $02,x - ldb $04,y - stb $04,x - puls pc,b,a -L1ADE exg y,u + ENDC + ldb 4,y + stb 4,x + puls pc,d + +L1B52 exg y,u exg x,y - bsr L1ACE + bsr L1B3B exg x,y exg y,u - rts -L1AE9 exg x,u - bsr L1ACE - exg x,u - rts -L1AF0 pshs b,a - addd $03,x - std $03,x - ldd #$0000 - adcb $02,x - adca $01,x - std $01,x - ldb #$00 + rts + +* Called by ellipse +* Add 16 bit to 40 bit number @ X (but don't carry in 5th byte) +L1B63 ldd #$0001 for circle, etc. above +L1B64 pshs d + addd 3,x + std 3,x + ldd #$0000 For using carry + IFNE H6309 + adcd 1,x + ELSE + adcb 2,x + adca 1,x + ENDC + std 1,x + ldb #$00 *CHANGE: WAS CLRB, BUT THAT WOULD SCREW CARRY UP adcb ,x stb ,x - puls pc,b,a -L1B07 pshs b,a - ldd $03,x - addd $03,y - std $03,x - ldd $01,x - adcb $02,y - adca $01,y - std $01,x + puls pc,d + +* Add 40 bit # @ X to 40 bit # @ Y; result into X +L1B7A pshs d + ldd 3,x + addd 3,y + std 3,x + ldd 1,x + IFNE H6309 + adcd 1,y + ELSE + adcb 2,y + adca 1,y + ENDC + std 1,x ldb ,x adcb ,y stb ,x - puls pc,b,a -L1B1F exg x,y - bsr L1B9D - exg x,y - bsr L1B07 - exg x,y - bsr L1B9D - exg x,y - rts -L1B2E pshs y,b,a - clra - clrb - pshs b,a + puls pc,d + +L1BA1.0 bsr L1B32 +L1BA1 pshs y,d + IFNE H6309 + clrd + ELSE + clra + clrb + ENDC + pshs d Put 3 0's on stack pshs b tfr s,y - bsr L1B40 - leas $03,s - puls pc,y,b,a -L1B3E bsr L1AC5 -L1B40 pshs u,y,b,a - leas -$0A,s - tfr s,u - bsr L1AE9 - tfr u,y - leau $05,u - bsr L1ADE - clra - clrb - lbsr L1AC5 - bra L1B57 -L1B55 bsr L1B74 -L1B57 bsr L1B7F - beq L1B61 - bcc L1B55 - bsr L1B07 - bra L1B55 -L1B61 bcc L1B65 - bsr L1B07 -L1B65 leas $0A,s - puls pc,u,y,b,a -L1B69 lsl $04,x - rol $03,x - rol $02,x - rol $01,x - rol ,x - rts -L1B74 lsl $04,y - rol $03,y - rol $02,y - rol $01,y - rol ,y - rts -L1B7F lsr ,u - bne L1B92 - ror $01,u - bne L1B94 - ror $02,u - bne L1B96 - ror $03,u - bne L1B98 - ror $04,u - rts -L1B92 ror $01,u -L1B94 ror $02,u -L1B96 ror $03,u -L1B98 ror $04,u - andcc #$FB - rts -L1B9D com ,x - com $01,x - com $02,x - com $03,x - com $04,x - inc $04,x - bne L1BB9 - inc $03,x - bne L1BB9 - inc $02,x - bne L1BB9 - inc $01,x - bne L1BB9 + bsr L1BB4 + leas 3,s + puls pc,y,d + +L1BB1 bsr L1B32 Make 5 byte integer of D @ X +L1BB4 pshs u,y,d Preserve regs on stack + leas -10,s Make buffer for two 5 byte integers + tfr s,u Point U to first buffer +* Was subroutine 1B5D + exg x,u Swap temp ptr with X ptr + bsr L1B3B Copy 5 byte # from Y to X (into 1st temp buffer) + exg x,u Swap ptrs back + + tfr u,y Move stack ptr to Y + leau 5,u Point U to 2nd 5 byte buffer + bsr L1B52 + IFNE H6309 + bsr L1B32.0 ATD: CLRD moved for size + ELSE + lbsr L1B32.0 + ENDC + bra L1BCB + +L1BC9 lsl 4,y Multiply 5 byte integer by 2 + IFNE H6309 + ldq ,y + rolw + rold + stq ,y + ELSE + ldd 2,y + rolb + rola + std 2,y + ldd ,y + rolb + rola + std ,y + ENDC + +* Loop-Divide U by 2 until U=0 or uneven divide +* (each time, multiply Y by 2) +* When U=0 & no remainder, exits +* When U=0 & remainder, 5 byte # @ X = that # + 5 byte # @ Y +* NOTE: If it works, change below & L1C06 to use LDQ/RORD/RORW/STQ +L1BCB lsr ,u Divide 5 byte integer by 2 + bne L1C06 If any non-zero bytes, make sure to clear 0 flag + ror 1,u + bne L1C08 + ror 2,u + bne L1C0A + ror 3,u + bne L1C0C + ror 4,u +* If it gets this far, the resulting 5 byte # is zero + beq L1BD5 If result=0, skip ahead +NewLbl bcc L1BC9 If no remainder, multiply Y by 2 again + bsr L1B7A X=X+Y (5 byte #'s @ register names) + bra L1BC9 Continue (multiply Y by 2 & divide U by 2 again) + +L1BD5 bcc L1BD9 If result=0 & no remainder, done & return + bsr L1B7A X=X+Y (5 byte #'s @ register names) +L1BD9 leas 10,s Eat 2 5 byte integers off of stack + puls pc,u,y,d Restore regs & return + +L1C06 ror 1,u Finishes divide by 2 with non-zero result +L1C08 ror 2,u +L1C0A ror 3,u +L1C0C ror 4,u + bra NewLbl Continue + +* Negate 5 byte integer +L1C11.0 exg x,y ATD: moved here for size +L1C11 com ,x Invert # @ X + com 1,x + com 2,x + com 3,x + com 4,x + + inc 4,x + bne L1C2D + inc 3,x + bne L1C2D + inc 2,x + bne L1C2D + inc 1,x + bne L1C2D inc ,x -L1BB9 rts -L1BBA pshs b,a +L1C2D rts + +L1C2E pshs d ldd ,x cmpd ,y - bne L1BD9 + bne L1C4D ldd $02,x cmpd $02,y - bne L1BD0 + bne L1C44 ldb $04,x cmpb $04,y - beq L1BD9 -L1BD0 bhi L1BD6 + beq L1C4D +L1C44 bhi L1C4A lda #$08 - bra L1BD7 -L1BD6 clra -L1BD7 tfr a,cc -L1BD9 puls pc,b,a - ldd <$0018 - addd <$001C - cmpd <$1B,y - bls L1BE8 - ldd <$1B,y -L1BE8 pshs y,b,a - std <$004B - ldd <$0018 - subd <$001C - bpl L1BF4 - clra - clrb -L1BF4 pshs b,a - std <$0047 - ldd <$001A - subd <$001E - bpl L1C00 - clra - clrb -L1C00 bsr L1C15 - puls y,x,b,a - std <$0047 - stx <$004B - ldd <$001A - addd <$001E - cmpd <$1D,y - bls L1C15 - ldd <$1D,y -L1C15 std <$0049 - std <$004D - lbra L159F -L1C1C lbsr L1559 - ldb #$01 + fcb $21 skip one byte: same cycle time, 1 byte smaller +L1C4A clra +L1C4B tfr a,cc +L1C4D puls pc,d + + +* FFill entry point +L1C4F lbsr L1884 ATD: +11C:-6B exit if screen is text + ldb #$01 Set flag that no error has occurred + stb <$b1 LCB:Set flag that this is the 1st time through stb <$002A - lbsr L1E48 - stx <$0072 - stb <$0074 - lbsr L1EF6 - sta <$0028 - lbsr L06AC - cmpb $06,y - beq L1C67 - clrb - pshs b - lbsr L1E9C - lbsr L1EC8 - ldx <$0072 - bra L1C76 -L1C43 tst >$101B - beq L1C6C - ldb ,s+ - beq L1C67 - stb <$002B - addb ,s+ - cmpb <$1E,y - bhi L1C72 - stb <$004A - puls b,a - std <$0047 - puls b,a - std <$004B - lbsr L1E48 - stb <$0074 - lbra L1CEE -L1C67 clrb - ldb <$002A - bne L1C6F -L1C6C ldb #$BA - coma -L1C6F lbra L00F4 -L1C72 leas $04,s - bra L1C43 -L1C76 ldb <$0074 -L1C78 lbsr L1EDF - bsr L1CC4 - beq L1C84 - lbsr L1EF6 - beq L1C78 -L1C84 lbsr L1EB3 + lbsr L1DF6 Check/calculate scaling + lbcs L1CBF Illegal coordinate, exit + IFNE H6309 + ldq <$47 Get original X,Y start (now scaled) + stq <$AD Save them + ELSE + ldd <$49 + std <$B5 + std <$AF + ldd <$47 + std <$AD + ENDC + lbsr L1E9D Calculate screen address to start filling @ + stx <$0072 Save ptr to start pixel on physical screen + stb <$0074 Save bit mask for start pixel +* replaced the code above with this: slightly larger, but L1F4B is smaller, +* and this code is only executed once, while L1F4B is executed many times +* the additional benefit is that <$0028 is now the full-byte color mask +* instead of the single pixel mask, and we can do byte-by-byte checks! + andb ,x get first pixel: somewhere in the byte... + ldx #GrfStrt+L075F-1 point to table of pixel masks + lda <$0060 Get screen type + lda a,x Get subtable ptr + leax a,x Point to proper screen table + lda 2,x skip mask, color 0, get color 1 full-byte mask + mul multiple color by $FF, $55, or $11 (1,4,16-color) + IFNE H6309 + orr b,a bits are all mixed up: OR them together + ELSE pshs b - ldd <$0047 - std <$009B - puls b -L1C8F bsr L1CD6 - bsr L1CCC - bhi L1C9A - lbsr L1EF6 - beq L1C8F -L1C9A lbsr L1EDF - lbsr L1D9A - beq L1CA8 - bsr L1CB5 - lda #$FF - pshs b,a -L1CA8 lbsr L1D9A - beq L1C43 - bsr L1CB5 - lda #$01 - pshs b,a -L1CB3 bra L1C43 -L1CB5 puls b,a - pshs y,x,b,a - ldd <$0047 - std $04,s - ldd <$009B - std $02,s - ldb <$004A - rts -L1CC4 pshs b,a - ldd <$0047 - addd <$00B3 - puls pc,b,a -L1CCC pshs b,a - ldd <$0047 - cmpd <$1B,y - puls pc,b,a -L1CD6 lda ,x - sta ,-s - lda <$0061 - lbsr L1F06 - lda ,x - cmpa ,s+ - beq L1CEA - lda #$FF - sta >$101B -L1CEA lbsr L1EB3 - rts -L1CEE ldd <$0047 - subd #$0002 - std <$009B - ldb <$0074 -L1CF7 lbsr L1EF6 - bne L1D03 - lbsr L1EDF - bsr L1CC4 - bne L1CF7 -L1D03 lbsr L1EB3 - stb <$0074 - ldd <$0047 - cmpd <$004B - bhi L1CB3 - ldb <$0074 - lbsr L1EF6 - bne L1D03 - ldd <$0047 - cmpd <$009B - bgt L1D34 - bsr L1D9A - beq L1D34 - ldd <$009B - pshs b,a - ldd <$0047 - bpl L1D2B - clra - clrb -L1D2B pshs b,a - ldb <$004A - lda <$002B - nega - pshs b,a -L1D34 ldd <$0047 - std <$009B - ldb <$0074 -L1D3A lbsr L1EF6 - bne L1D45 - bsr L1CD6 - bsr L1CCC - bls L1D3A -L1D45 lbsr L1EDF - stb <$0074 - bsr L1D9A - beq L1D57 - lbsr L1CB5 - lda <$002B - pshs b,a - ldb <$0074 -L1D57 lbsr L1EB3 - stb <$0074 - lbsr L1CCC - bgt L1D71 - ldd <$0047 - cmpd <$004B - bgt L1D71 - ldb <$0074 - lbsr L1EF6 - bne L1D57 - bra L1D34 -L1D71 cmps <$003B - bhi L1D78 - clr <$002A -L1D78 ldd <$0047 - subd <$00B3 - std <$0047 - ldd <$004B - addd #$0002 - cmpd <$0047 - bhi L1D97 - leas -$02,s - pshs b,a - ldd <$0047 - std $02,s - ldb <$004A - lda <$002B - nega - pshs b,a -L1D97 lbra L1C43 -L1D9A cmps <$003B - bhi L1DA1 - clr <$002A -L1DA1 rts -L1DA2 ldb #$47 -L1DA4 bsr L1DD8 - lbra L1E31 -L1DA9 ldb #$4B - bra L1DA4 -L1DAD ldb #$4F - bra L1DA4 -L1DB1 ldb #$20 -L1DB3 bsr L1DD8 - ldd #$027F - bsr L1DBF - bcs L1DCF - ldd #$00BF -L1DBF pshs b,a - ldd ,x++ - bpl L1DC9 - nega - negb - sbca #$00 -L1DC9 cmpd ,s++ - bgt L1E44 - clrb -L1DCF rts -L1DD0 ldb #$24 - bra L1DB3 -L1DD4 ldb #$53 - bra L1DB3 -L1DD8 tfr u,x - abx - lda $09,y - bita #$08 - beq L1DE5 - ldd -$07,y - bne L1DE6 -L1DE5 rts -L1DE6 pshs y,x,b,a - tfr x,y - ldx ,y - ldb ,s - beq L1DF4 - bsr L1E00 - std ,y -L1DF4 ldx $02,y - ldb $01,s - beq L1DFE - bsr L1E00 - std $02,y -L1DFE puls pc,y,x,b,a -L1E00 pshs x,b - leas -$02,s - lda $04,s - mul - cmpb #$CD - pshs cc - exg a,b - clra - puls cc - bcs L1E14 - addd <$00B3 -L1E14 std ,s - lda $03,s - ldb $02,s - mul - addd ,s - leas $03,s - puls pc,x -L1E21 pshs x - lda ,s - stb ,s - mul - stb ,-s - ldd $01,s - mul - adda ,s+ - puls pc,x -L1E31 ldd ,x - cmpd <$1B,y - bhi L1E44 - ldd $02,x - cmpd <$1D,y - bhi L1E44 - andcc #$FE - rts -L1E44 comb - ldb #$BD - rts -L1E48 ldd -$0D,y -L1E4A pshs y,b,a - lda <$004A - ldb <$0063 - mul - addd ,s++ - tfr d,x - ldb <$0060 - bpl L1E60 - ldd <$0047 - lslb - leax d,x - puls pc,y -L1E60 cmpb #$04 - bne L1E6B - ldd <$0047 - leay <L1E99,pcr - bra L1E7F -L1E6B cmpb #$01 - beq L1E76 - ldd <$0047 - leay <L1E94,pcr - bra L1E7D -L1E76 ldd <$0047 - leay <L1E8B,pcr - lsra - rorb -L1E7D lsra - rorb -L1E7F lsra - rorb - leax d,x - ldb <$0048 - andb ,y+ - ldb b,y - puls pc,y - -* 2 color mode pixel mask table -L1E8B fcb $07 Mask for pixel #'s we care about - fcb $80,$40,$20,$10,$08,$04,$02,$01 - -* 4 color mode pixel mask table -L1E94 fcb $03 Mask for pixel #'s we care about - fcb $c0,$30,$0c,$03 - -* 16 color mode pixel mask table -L1E99 fcb $01 Mask for pixel #'s we care about - fcb $f0,$0f - -L1E9C lda <$0060 - leax <L1EAB-2,pcr - lsla - ldd a,x - sta <$0079 - leax b,x - stx <$0077 - rts -* Bit shift table to shift to the right 3,2,1 or 0 times -L1EAB fcb $80,L1EC2-(L1EAB-2) -L1EAD fcb $c0,L1EC1-(L1EAB-2) -L1EAF fcb $c0,L1EC1-(L1EAB-2) -L1EB1 fcb $f0,L1EBF-(L1EAB-2) -L1EB3 inc <$48 - bne L1EB9 - inc <$0047 -L1EB9 lsrb - bcs L1EC3 - jmp [<$77,u] -L1EBF lsrb -L1EC0 lsrb -L1EC1 lsrb -L1EC2 rts -L1EC3 ldb <$0079 - leax $01,x - rts -L1EC8 lda <$0060 - leax <L1ED7-2,pcr - lsla - ldd a,x - sta <$007C - leax b,x - stx <$007A - rts + ora ,s+ + ENDC +* now A = full-byte color mask for the color we want to FFILL on + ldx #GrfStrt+L16B1-1 point to pixels/byte table + ldb <$0060 get screen type again + ldb b,x get B=pixels per byte + std <$0028 save full-byte color mask, pixels per byte +* end of inserted code: a bit larger, but MUCH faster in the end + cmpa Wt.Fore,y background color as current foreground color? + beq L1CB7 Yes, exit if no stack overflow occurred + clr ,-s save y-direction=0: done FFILLing + lbsr L1EF1 Setup start pixel mask & vector for right dir. +* Setup up bit mask & branch table for flood filling in the left direction +L1F1D lda <$0060 Get screen type + ldx #GrfStrt+L1F2C-2 Point to table + lsla x2 for table offset + ldd a,x Get mask and branch offset + sta <$007C Preserve bit mask + abx Store vector to bit shift routine + stx <$007A save for later + ldx <$0072 Get phys screen address to pixel we are doing + lbra L1CC6 Skip ahead * Bit shift table to shift to the left 3,1 or 0 times * Used by FFill when filling to the left -L1ED7 fcb $01,L1EF0-(L1ED7-2) $1b 640 2-color - fcb $03,L1EEF-(L1ED7-2) $1a 320 4-color - fcb $03,L1EEF-(L1ED7-2) $1a 640 4-color - fcb $0f,L1EED-(L1ED7-2) $18 320 16-color - -L1EDF tst <$0048 - bne L1EE5 - dec <$0047 -L1EE5 dec <$0048 - lslb - bcs L1EF1 - jmp [<$7A,u] - -L1EED lslb - lslb -L1EEF lslb -L1EF0 rts -L1EF1 ldb <$007C - leax -$01,x +L1F2C fcb $01,L1F45-(L1F2C-2) $1b 640 2-color + fcb $03,L1F44-(L1F2C-2) $1a 320 4-color + fcb $03,L1F44-(L1F2C-2) $1a 640 4-color + fcb $0f,L1F42-(L1F2C-2) $18 320 16-color +* Bit shifts based on screen type +L1F42 lslb + lslb +L1F44 lslb +L1F45 rts + +X1F08 lda <$0028 get full-byte background color mask + cmpa ,x same as the byte we're on? + beq X1F16 yes, skip ahead + leau 1,u otherwise go to the right one pixel +X1F0E lsrb Shift to next bit mask + bcs X1F18 Finished byte, reload for next + jmp [>GrfMem+gr0077] Shift B more (if needed) depending on scrn type + +* background is a byte value, but we don't know what the X coord is +X1F16 clra + ldb <$29 pixels per byte + IFNE H6309 + addr d,u go to the right one byte + ELSE + leau d,u + ENDC + decb make 2,4,8 into 1,3,7 + IFNE H6309 + comd get mask + andr d,u force it to the left-most pixel of the byte + ELSE + coma + comb + pshs d + tfr u,d + anda ,s + andb 1,s + tfr d,u + puls d + ENDC +X1F18 ldb #1 Bump screen address by 1 + abx + ldb <$0079 Get start single pixel mask (1,2 or 4 bits set) + rts + +* Switch to next line for FFill +L1CC2 leas 4,s Eat last set of X start ($47), end ($9B) +* $101B is a counter counted down continuously by CC3IO. +* this is DEBUG code... check out 1D28: if no NEW PIXEL is put down for +* 255 ticks (~4 seconds), exit with error. +* May have to add it back in for SnakeByte Pattern paint bug? +L1C93 ldb ,s+ grab y-direction to travel + beq L1CB7 if zero, check if we're done + stb <$002B save direction to travel in + addb ,s+ add into saved Y-coordinate + cmpb <Wt.MaxY+1,y check against the maximum Y position + bhi L1CC2 too high, eat X start,end and go DOWN + stb <$004A save current Y-position + puls d,x restore X start, X end + std <$0047 save it for later + stx <$004B save that, too + lbsr L1E9D get X=logical screen coordinates, B=pixel mask + stb <$0074 save starting pixel mask + jmp >GrfStrt+L1D40 go do some painting + +* Check if done filling or if error occurred +L1CB7 clrb Clear carry as default (no error) + ldb <$002A Get done/error flag + bne L1CBF Done flag, exit without error +L1CBC ldb #E$StkOvf Stack overflow error + coma +L1CBF jmp >GrfStrt+L0118 + +* Move 1 pixel to left (for FFill) +* <$0028 = full-byte color mask to paint on +* <$0029 = pixels per byte +L1F34 lda ,x get current byte + cmpa <$0028 full-byte background color? + beq L1F3C yes, go do full-checks + leau -1,u drop down by 1 + lslb Move pixel mask to left by 1 + bcs L1F46 If finished byte, skip ahead + jmp [>GrfMem+gr007A] Adjust for proper screen type (further LSLB's) + +L1F3C clra make A=0 + ldb <$0029 get 16-bit value of pixels per byte + decb get 7,3,1 pixel mask + IFNE H6309 + comd get pixel mask, with low bits cleared out, + andr d,u i.e. ensure we're to the LEFT as far as possible + ELSE + coma + comb + pshs d + tfr u,d + anda ,s + andb 1,s + tfr d,u + puls d + ENDC + leau -1,u go to the left one pixel + +L1F46 ldb <$007C Get start pixel mask (on right side) + leax -1,x Bump screen's pixel ptr left & return rts -L1EF6 pshs b + +* search until we find the left-most pixel which is NOT the paint on pixel, +* or the edge of the screen +* Exits with B=pixel mask +* W = current X position +* U = W +FFILL.1 ldb <$0074 Get pixel mask for pixel we are doing + ldu <$0047 +L1CC8 lbsr L1F4B check pixel + bne L1CD4 backup if not the background color pixel + bsr L1F34 exits with U = x-coord + IFNE H6309 + cmpr 0,u has it filled to line position -1? + ELSE + cmpu #0 + ENDC + bpl L1CC8 we're still on the same color, continue +* we've found the left boundary, go to the right +L1CD4 equ * + IFNE H6309 + bra X1F08 go to the right one pixel: account for extra DECW + ELSE + lbra X1F08 + ENDC + +L1CC6 bsr FFILL.1 + stu <$0047 + stu <$009B save for later + bsr FFILL.2 paint to the right, a pixel at a time + lda #$FF get a flag: go UP one line + bsr L1D05 set up for another fill + lda #$01 get a flag: go DOWN one line + bsr L1D05 save more things on the stack + bra L1C93 go do another line + +* paint to the right, a pixel at a time. +* Exits with B=pixel mask +* W = current X position +* U = W +FFILL.2 ldu <$0047 + stu <$20 save X-start for this fill routine + clr <$2C clear flag: no pixels done yet +ffill.2a bsr L1F4B check if we hit color other than background + bne L1CEA yes, skip ahead + lbsr X1F08 go to the right one pixel + stb <$2C + cmpu Wt.MaxX,y Are we at right side of window? + bls FFILL.2a no, continue +* we've gone too far to the right +L1CEA bsr L1F34 back up one pixel +* ATD: New routine added. Do a horizontal line from left to right! +* This is not substantially faster, perhaps, but it does look better. + pshs d + lda <$2C check flag + beq L1D03 skip ahead: no pixels to draw +* LCB: New routine added to check if we are redoing the 1st pixel we started +* painting at. If we are exit (Helps fill certain PSET variations that allow +* infinite recursions (loops) that hang Grfdrv) + lda <$B1 Get flag that we are on 1st line of FFill + beq DoChecks Not 1st time, do checks + clr <$B1 Clear flag & do draw + bra Not1st + +DoChecks ldd <$AF Get Y value from 1st FFill line + cmpd <$49 Same as current? + bne Not1st No, go draw + cmpu <$AD right side X lower or same as original X? + bhi Not1st No, draw it + ldd <$20 Get left X coord + cmpd <$AD left side X higher or same as original X? + blo Not1st No, draw it + leas 4,s We already did this, eat stack & exit w/o error + clrb + jmp >GrfStrt+L0118 + +Not1st ldd <$4B get old coordinate: U=<$0047 already + pshs d,x,y,u + stu <$4B save as X-end + ldd <$20 get LHS X coordinate + std <$47 save for the line routine +* ATD: warning: This routine trashes W! + IFNE H6309 + ldw <$68 get LSET vector + ELSE + ldu <$68 + stu <$B5 + ENDC + ldu <$64 and PSET vector + jsr >GrfStrt+L1690 do fast horizontal line + puls d,x,y,u restore registers + std <$004B save +L1D03 stu <$0047 save + puls d,pc + +L1D05 puls u restore PC of calling routine + ldb <$004A get B=working Y coordinate + pshs y,x,d save PC, and 4 junk bytes; ???RG + IFNE H6309 + ldw <$0047 Get 'working' X coord + ELSE + ldd <$47 + std <$B5 + std 4,s see stq 2,s below + ENDC + ldd <$009B and left-most pixel we were at + IFNE H6309 + stq 2,s save X start, end positions on the stack + ELSE + std 2,s see std 4,s above + ENDC + jmp ,u return to calling routine + +* ATD: mod: <$0028 is full-byte color mask +* Entry: X=ptr to current byte on screen +* B=bit mask for current pixel +* Exit: B=bit mask for current pixel +* CC set to check if we hit border of FFill +L1F4B pshs b Preserve pixel mask + tfr b,a Duplicate it + anda ,x Get common bits between screen/mask + andb <$0028 and common bits between full-byte color and mask + IFNE H6309 + cmpr b,a are the 2 colors the same? + ELSE + pshs b + cmpa ,s+ + ENDC + puls pc,b Restore pixel mask & return + +* start painting at a new position. +* <$47=start X, <$49=current Y, <$4B=end X +* Check to the left for bounds +L1D40 ldu <$0047 get current X + leau -2,u go to the left 2 pixels? : wrap around stop pixel + stu <$009B save position + lbsr FFILL.1 search to the left + bra L1D58 skip ahead + +L1D55 lbsr X1F08 go to the right one pixel +L1D58 stu <$0047 save X coordinate + cmpu <$004B check against X-end from previous line + lbhi L1C93 too far to the right, skip this line + bsr L1F4B check the pixel + bne L1D55 not the same, go to the right + stb <$0074 save starting pixel mask + cmpu <$009B check current X against saved start (X-2) + bgt L1D87 higher, so we do a paint to the right + bsr L1DEE check stack + beq L1D87 if 0: stack is too low + ldu <$009B grab X + ldd <$0047 grab current X +* ATD: removed check for X coord <0, as the above call to X1F08 ensures it's +* at least 0. + pshs d,u Save X start, X end coordinates + ldb <$004A Get Y coord + lda <$002B Get save current Y-direction + nega Change direction + pshs d Save direction flag and Y coord +L1D87 ldd <$0047 Get current X coord + std <$009B Save duplicate (for direction change???) + ldb <$0074 Get current pixel mask + +* Paint towards right side +L1D98 lbsr FFILL.2 + stb <$0074 Save new start pixel mask + bsr L1DEE check stack + beq L1DAA if 0: stack is too low + lda <$002B grab direction flag + bsr L1D05 save current X start, end on-stack + ldb <$0074 grab starting pixel mask + ldu <$0047 restore current X-coord + +* Small loop +L1DAA lbsr X1F08 Adjust for next pixel on the right + stb <$0074 Save new pixel mask + stu <$0047 and new X-coord + cmpu Wt.MaxX,y Hit right side of window? + bgt L1DC4 Yes, skip ahead + cmpu <$004B Is current X coord going past Draw ptr X coord? + bgt L1DC4 Yes, skip ahead + bsr L1F4B Check if we are hitting a drawn border + bne L1DAA No, keep FFilling + bra L1D87 paint to RHS of the screen + +* could be subroutine call to L1DEE +* saves 6 bytes, adds 10 clock cycles +L1DC4 cmps <$003B Stack about to get too big? + bhi L1DCB No, continue + clr <$002A Yes, set flag to indicate stack overflow +L1DCB leau -1,u go to the left one pixel + stu <$0047 Save X coord + ldd <$004B Get draw ptr X coord + addd #2 Bump up by 2 + IFNE H6309 + cmpr u,d Past current X coord in FFill? + ELSE + pshs u + cmpd ,s++ + ENDC + lbhi L1C93 Yes, go change Y-direction + pshs d,u Save draw ptrs X+2, current X coord + ldb <$004A Get working Y coord + lda <$002B get y-direction flag + nega Change direction? + pshs d Save direction flag and Y coord +L1DEB jmp >GrfStrt+L1C93 go do another direction + +L1DEE cmps <$003B check against lowest possible stack + bhi L1DF5 Question: Why not just an in-line check? + clr <$002A clear flag: stack is too low +L1DF5 rts + +L1DF6 ldb #$47 get offset in grfdrv mem to working X coord +L1DF8 bsr L1E2C +* Check requested X/Y co-ordinates to window table to see if they are in range +L1E86 equ * + IFNE H6309 + ldq ,x Get requested X & Y coordinates + ELSE + ldd 2,x + std <$B5 + ldd ,x + ENDC + cmpd Wt.MaxX,y X within max. range of window? + bhi L1E99 No, return error + IFNE H6309 + cmpw Wt.MaxY,y Y within max. range of window? (keep it 16-bit) + ELSE + pshs x + ldx <$B5 + cmpx Wt.MaxY,y + puls x + ENDC + bhi L1E99 No, return error + andcc #^Carry They work, return without error + rts + +L1E99 comb set carry + ldb #E$ICoord get error code + rts return + +L1DFD ldb #$4B Get offset in grfdrv mem to current X coord + bra L1DF8 +L1E01 ldb #$4F Get offset in Grfdrv mem to X size + bra L1DF8 + +L1E05 ldb #$20 Point to Arc 'clip line' Start coordinate +* Check both X and Y coordinates and see if valid (negative #'s OK) +* Entry : B=Offset into GRFDRV mem to get X & Y (16 bit) coordinates +L1E07 bsr L1E2C Do offset of X into grfdrv space by B bytes + IFNE H6309 + ldw #639 Maximum value allowed + ELSE + pshs x + ldx #639 + stx <$B5 + puls x + ENDC + bsr L1E13 Check if requested coordinate is max. or less + bcs L1E23 Error, exit + IFNE H6309 + ldw #MaxLines*8-1 Maximum Y coord allowed; check it too + ELSE + pshs x + ldx #MaxLines*8-1 + stx <$B5 + puls x + ENDC +* Make sure 16 bit coordinate is in range +* Entry: W=Maximum value allowed +* X=Pointer to current 16 bit number to check +* Exit: B=Error code (carry set if error) + +L1E13 ldd ,x++ Get original value we are checking + bpl L1E1D Positive, do the compare + IFNE H6309 + negd Flip a negative # to a positive # +L1E1D cmpr w,d If beyond maximum, return with Illegal coord error + ELSE + coma + comb + addd #1 +L1E1D cmpd <$B5 + ENDC + bgt L1E99 + clrb In range, no error +L1E23 rts + +L1E24 ldb #$24 Point to Arc 'clip line' end coordinate + bra L1E07 + +L1E28 ldb #$53 Point to Horizontal Radius + bra L1E07 + +* Offset X into grfdrv mem by B bytes (to point to 2 byte coordinates) +L1E2C ldx #GrfMem Point to GRFDRV mem + abx Point X to X,y coord pair we are working with + IFNE H6309 + tim #Scale,Wt.BSW,y Scaling flag on? + ELSE + pshs a + lda Wt.BSW,y + bita #Scale + puls a + ENDC + beq L1E39 no, return + ldd Wt.SXFct,y Get X & Y scaling values + bne L1E3A If either <>0, scaling is required +L1E39 rts If both 0 (256), scaling not required + +* Scaling required - Scale both X & Y coords +* Change so ldb ,s/beq are both done before ldx ,y (will save time if that +* particular axis does not require scaling) +* Entry:X=Ptr to X,Y coordinate pair (2 bytes each) +* Y=Window tble ptr +* A=X scaling multiplier +* B=Y scaling multiplier +L1E3A pshs a Preserve X scaling value + tstb Y need scaling? + beq NoY No, skip scaling it +* ATD: 10 bytes smaller, 20 cycles longer +* leax 2,x +* bsr L1E4A +* leax -2,s + clra D=Y scaling value + IFNE H6309 + muld 2,x Multiply by Y coordinate + tfr b,a Move 16 bit result we want to D + tfr e,b + cmpf #$cd Round up if >=.8 leftover + ELSE + pshs x,y,u + ldx 2,x + lbsr MUL16 + tfr y,d + stu <$B5 + puls x,y,u tfr b,a - anda ,x -L1EFC lsrb - bcs L1F02 - lsra - bra L1EFC -L1F02 cmpa <$0028 - puls pc,b -L1F06 pshs b,a - jmp [<$64,u] -L1F0B FCB 5,$0F,$0F,$17 -L1F0F pshs b,x - bsr L1F55 - lsra - rorb - lsra - rorb - bra L1F25 - pshs x,b - bsr L1F55 - lsra - rorb - bra L1F25 - pshs x,b - bsr L1F55 -L1F25 andb <$00B0 - abx - lda <$008A - pshs a - lda <$00B1 -L1F2E cmpx #$4000 - bcs L1F3A - inca - leax >-$2000,x - bra L1F2E -L1F3A sta <$008A - sta >$FFA9 - ldb ,x - puls a - sta <$008A - sta >$FFA9 - andb ,s+ - ldx ,s++ - lda ,s + ldb <$B6 + cmpb #$cd cmpf #$cd + pshs cc save result + ldb <$B5 tfr e,b + puls cc + ENDC + blo L1E48 Fine, store value & do X coord + IFNE H6309 + incd Round up coordinate + ELSE + addd #1 + ENDC +L1E48 std 2,x Save scaled Y coordinate +NoY ldb ,s+ Get X scaling value + beq L1E52 None needed, exit +L1E4A clra D=X scaling value + IFNE H6309 + muld ,x Multiply by X coordinate + tfr b,a Move 16 bit result we want to D + tfr e,b + cmpf #$cd Round up if >=.8 leftover + ELSE + pshs x,y,u + ldx ,x + lbsr MUL16 + stu <$B5 + tfr y,d + puls x,y,u + tfr b,a + ldb <$B6 + cmpb #$cd cmpf #$cd + pshs cc save result + ldb <$B5 tfr e,b + puls cc + ENDC + blo L1E50 Fine, store value & return + IFNE H6309 + incd Round up coordinate + ELSE + addd #1 + ENDC +L1E50 std ,x Save new X coordinate +L1E52 rts Return + +L1EF1 lda <$0060 get screen type + ldx #GrfStrt+L1F00-2 Point to mask & offset table + lsla account for 2 bytes entry + ldd a,x get mask & offset + sta <$0079 Preserve mask + abx Point to bit shift routine + stx <$0077 Preserve vector to bit shift routine + rts + +* Bit shift table to shift to the right 3,2,1 or 0 times +L1F00 fcb $80,L1F17-(L1F00-2) $19 640 2 color + fcb $c0,L1F16-(L1F00-2) $18 320 4 color + fcb $c0,L1F16-(L1F00-2) $18 640 4 color + fcb $f0,L1F14-(L1F00-2) $16 320 16 color + +L1F14 lsrb + lsrb +L1F16 lsrb +L1F17 rts + +* PSET vector table - if PSET is on. Otherwise, it points to L1F9E, which +* does an AND to just keep the 1 pixel's worth of the color mask and calls +* the proper LSET routine +L1FB4 fcb L1F60-(L1FB4-1) 640x200x2 + fcb L1F6E-(L1FB4-1) 320x200x4 + fcb L1F6E-(L1FB4-1) 640x200x4 + fcb L1F7C-(L1FB4-1) 320x200x16 + +* PSET vector ($16,y) routine - 2 color screens +L1F60 pshs x,b Preserve scrn ptr & pixel mask + bsr L1F95 Calculate pixel offset into pattern buffer + abx Since 1 bit/pixel, that is address we need + ldb <$0048 Get LSB of X coord + lsrb Divide by 8 for byte offset into pattern buffer + lsrb + lsrb + andb #%00000011 MOD 4 since 2 color pattern buffer 4 bytes wide + bra L1F88 Go merge pattern buffer with pixel mask + +* PSET vector ($16,y) routine - 4 color screens +L1F6E pshs x,b Preserve scrn ptr & pixel mask + bsr L1F95 Calculate pixel offset into pattern buffer + lslb Since 2 bits/pixel, multiply vert. offset by 2 + abx + ldb <$0048 Get LSB of X coord + lsrb Divide by 4 for byte offset into pattern buffer + lsrb + andb #%00000111 MOD 8 since 4 color pattern buffer 8 bytes wide + bra L1F88 Go merge pattern buffer with pixel mask + +* PSET vector ($16,y) routine - 16 color screens +L1F7C pshs x,b Preserve scrn ptr & pixel mask + bsr L1F95 Calculate pixel offset into pattern buffer + lslb Since 4 bits/pixel, multiply vert. offset by 4 + lslb + abx + ldb <$0048 Get LSB of X coord + lsrb Divide by 2 for byte offset into pattern buffer + andb #%00001111 MOD 16 since 16 color pattern buffer 16 bytes wide +L1F88 ldb b,x Get proper byte from pattern buffer + andb ,s+ Only keep bits that are in pixel mask + puls x Restore screen ptr + +* DEFAULT PSET ROUTINE IF NO PATTERN BUFFER IS CURRENTLY ACTIVE. POINTED TO +* BY [$64,u], usually called from L1F5B +L1F9E equ * + IFNE H6309 + andr b,a Only keep proper color from patterned pixel mask + jmp ,w Call current LSET vector + ELSE pshs b anda ,s+ - jmp [<$68,u] -L1F55 ldx <$0066 - lda <$00AF - ldb <$00B2 - anda <$004A - mul - leax d,x - ldd <$0047 - lsra - rorb - rts -L1F65 ldb $0E,y - beq L1F82 - stb <$00B1 - jsr <$00BC - ldx $0F,y - stx <$0066 - ldd <-$16,x - deca - bpl L1F79 - lda #$FF -L1F79 stb <$00B2 - decb - bpl L1F80 - ldb #$FF -L1F80 std <$00AF -L1F82 rts -L1F83 anda $01,s - jmp [<$68,u] - ldb $01,s - bra L1F9A - anda <$0061 - ldb ,s - andb $01,s - bra L1F9A - eora ,x - bra L1FA1 - anda ,x -L1F9A comb - andb ,x - stb ,x - ora ,x -L1FA1 sta ,x - puls pc,b,a - anda $01,s - eora ,x - sta ,x - puls pc,b,a + jmp [>GrfMem+$B5] + ENDC +* Calculate pixel offset into pattern buffer (32x8 pixels only) from Y coord +* Exit: X=ptr to start of data in pattern buffer +* B=Pixel offset within buffer to go to +L1F95 ldx <$0066 Get current pattern's buffer ptr + ldb <$004A Calculate MOD 8 the line number we want + andb #%00000111 to get data from the Pattern buffer + lslb Multiply by 4 to calculate which line within + lslb Pattern buffer we want (since 32 pixels/line) + rts emod -eom equ * +eom equ * end -