Mercurial > hg > Members > kono > nitros9-code
view level2/cmds/grfdrv.asm @ 3295:6b7a7b233925 default tip
makefile: Allow PORTS with level1/2 mix
https://sourceforge.net/p/nitros9/feature-requests/10/
author | Tormod Volden <debian.tormod@gmail.com> |
---|---|
date | Tue, 19 Apr 2022 18:12:17 +0200 |
parents | 602657b50bd6 |
children |
line wrap: on
line source
******************************************************************** * 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 SysRet 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 SysRet ** - 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 CoWin/CoGrf ** 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 CoWin) ** 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 CoWin 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 ** 02/26/07 - Changed Line routine to improve symmetry. The changes will permit ** the removal of the FastH and FastV routines if desired. The new ** Normal Line will correctly draw horizontal or vertical lines. 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 NitrOS-9 Windowing Driver ifp1 use defsfile use cocovtio.d endc GrfStrt equ $4000 Position of GRFDRV in it's own task tylg set Systm+Objct atrv set ReEnt+rev rev set $01 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 fcs /GrfDrv/ fcb edition ****************************** * Main entry point * Entry: B=Internal function code (from CoGRF or CoWin) * 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 #GrfMem/256 Direct page for GrfDrv tfr e,dp ELSE pshs a lda #GrfMem/256 tfr a,dp puls a 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 CoWin fdb $0000 Palette ($16) NOW IN CoWin fdb L063C+GrfStrt Font ($18) fdb L068B+GrfStrt GCSet ($1A) fdb $0000 DefColor ($1C) NOW IN CoWin fdb L06A4+GrfStrt LSet ($1E) fdb L0707+GrfStrt FColor ($20) fdb L0726+GrfStrt BColor ($22) fdb $0000 TChrSW ($24) NOW IN CoWin fdb $0000 PropSW ($26) NOW IN CoWin fdb $0000 Scale ($28) NOW IN CoWin fdb $0000 Bold ($2A) NOW IN CoWin 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/CoGrf, 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+SysRet 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 FScrTbl 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+SysRet 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 L0264 comb Window won't fit with existing windows ldb #E$IWDef L0286 rts * Setup a new screen table *L0268 bsr FScrTbl 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 FScrTbl 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 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 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 L0643 Go set up for font clrb No error and return rts * 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 * 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? * Note: The following line was causing our screen to clear which wrote over * the $FF value we wrote at the beginning to flag the screen memory as free. * This caused a memory leak in certain situations, like: * iniz w1 w4;echo>/w1;echo>/w4;deiniz w4 w1 * bne L03F4 No, Clear our screen & exit bne L03F5 No, just 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+SysRet 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 L03F5 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 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 * 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 ldy #WinBase Point to start of window tables leay d,y Point to parent window entry rts * 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+SysRet 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+SysRet 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 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+SysRet 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 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 * 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 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 ora ,s+ ENDC sta Wt.Attr,y Store new default attribute L0748 clr <$A9 No error, clear flag & return to system jmp >GrfStrt+SysRet * 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 * 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 CoVDG 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 fcb $17,$08,$15,$06,$27,$16,$26,$36 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 * DefGPB entry point L08DC bsr L08E1 go do it jmp >GrfStrt+SysRet 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 * 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 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 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+SysRet 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 sta Grf.Bck,x sty Grf.Off,x L0A75 ldb ,s lda <$009F cmpa #$01 bgt L0A9E tfr b,a bsr L0AA8 bcc L0A94 ldx #GrfStrt+L0AF4 stx <$00A1 ldx 1,s bsr L0ACD lbsr L017C lbsr L0A0C puls pc,y,x,b L0A94 ldx #GrfStrt+L0B1E stx <$00A1 ldx 1,s bsr L0ACD L0A9E clra tfr d,x ldb <$009F os9 F$DelRAM Deallocate the memory L0AA6 puls pc,y,x,b L0AA8 pshs x,b ldb <$0032 beq L0AC7 cmpa <$0032 beq L0ACA ldx <$0033 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 * 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++ ENDC rts * 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 CoGRF or CoWin) * 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/CoWin 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 CoWin 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+SysRet * 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 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 * 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+SysRet * 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 L0D0F comb ldb #$BE get internal integrity check error puls pc,y * 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 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) L0D78 fcb %00000001,%10000000 fcb %00000011,%11000000 fcb %00000111,%11100000 fcb %00001111,%11110000 fcb %00011111,%11111000 fcb %00111111,%11111100 fcb %01111111,%11111110 fcb %11111111,%11111111 * 4 color masks L0D88 fcb %00000011,%11000000 fcb %00001111,%11110000 fcb %00111111,%11111100 fcb %11111111,%11111111 * 16 color masks L0D90 fcb %00001111,%11110000 fcb %11111111,%11111111 * 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 * 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+SysRet * 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 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 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 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 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 L0E80 fcb L0EE0-L0E80 <$00A3 vector fcb %00000001 Bit mask for 1 pixel fcb 8 # pixels /byte 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 L0E8B fcb L0EDF-L0E8B <$00A3 vector fcb %00000011 Bit mask for 1 pixel fcb 4 # pixels/byte 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 L0E92 fcb L0EDD-L0E92 <$00A3 vector fcb %00001111 Bit mask for 1 pixel fcb 2 # pixels/byte 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 SysRet 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 bhs L0F6B yes, go print it L0F5D lda #'. Change illegal character to a period rts L0F61 anda #$DF suba #$C1 bmi L0F5D yes, change it to a period cmpa #$19 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) SysRet 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 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 * 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 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 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 CoWin: 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 * 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 * 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 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 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 L1267a 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 * Note, the following code will work as long as D is an even number... * Which it should be since all screen widths are even numbers (80, 40, etc) pshs u tfr x,u L1267b pulu x stx ,y++ subd #$0002 bgt L1267b puls u ENDC bra L128A Exit scroll routine * Scroll window that is not full width of screen L127B equ * IFNE H6309 ldd <$0099 Get # bytes/row for screen ldf <$0097 Get # bytes wide window is clre subr w,d Calc # bytes to next line L127E tfm x+,y+ Block move the line ELSE ldd <$0099 Get # bytes/row for screen pshs d clra ldb <$97 std <$B5 regW loaded puls d subd <$B5 subr w,d L127E pshs d,x,u ldb <$B6 get regW clra tfr x,u 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 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 * 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+ 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 * 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 * 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 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+ 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 * 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 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,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 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 stx <$0068 puls x,d Restore original X/Y sizes std <$004F stx <$0051 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+SysRet * 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+SysRet 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 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 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 * 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 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 * Routine to move left for Normal Line L177D. Needed to get correct symmetry LeftMV pshs d ldd <$0047 subd #1 std <$0047 puls d Lmore lslb bcs Lmore2 jmp [>GrfMem+gr007A] Lmore2 leax -1,x ldb <$007C rts * A dX or dY of 1 will step the line in the middle. The ends of the line * are not swapped. The initial error is a function of dX or dY. * A flag for left/right movement <$12 is used. * Normal line routine L1724 clr <$0012 flag for X swap ldd <$004B current X subd <$0047 new X std <$0013 save dX bpl L1734 com <$0012 flag left movement IFNE H6309 negd make change positive ELSE nega negb sbca #0 ENDC std <$0013 force dX>0 L1734 ldb <$0063 BPL bytes/line clra std <$0017 save 16-bit bytes per line ldd <$004D current Y subd <$0049 subtract working Y std <$0015 save dY bpl L1753 if positive IFNE H6309 negd make change positive ELSE nega negb sbca #0 ENDC std <$0015 force dY>0 ldd <$0017 up/down movement; up=+ down=- IFNE H6309 negd ELSE nega negb sbca #0 ENDC std <$0017 now points the correct direction L1753 ldd <$0013 compare dX with dY to find larger cmpd <$0015 bcs Ylarge IFNE H6309 asrd error = dX/2 bra Lvector Ylarge ldd <$0015 negd asrd error = -dY/2 ELSE asra rorb bra Lvector Ylarge ldd <$0015 nega negb sbca #0 asra rorb ENDC Lvector std <$0075 error term lbsr L1EF1 Set up <$77 right bit shift vector & <$79 pixel mask * for symmetry lbsr L1F1D Set up <$7A left 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 L1788 ldd <$0047 finished with X movement? cmpd <$004B bne L1788b ldd <$0049 finished with Y movement? cmpd <$004D bne L1788b rts finished fo leave L1788b ldd <$0075 get error bpl L177D if >=0 addd <$0013 add in dX std <$0075 save new working error ldd <$0017 get BPL IFNE H6309 addr d,x bcs L1779 test direction not result ELSE leax d,x will not change regCC N bmi L1779 ENDC inc <$004A go down one Y-line bra L1760 L1779 dec <$004A decrement y-count bra L1760 L177D subd <$0015 take out one BPL std <$0075 save new count ldb <$0074 grab pixel mask tst <$12 flag for left/right movement bne L177D2 lbsr L1F08 go right one pixel L177D3 stb <$0074 save new pixel mask bra L1760 loop to draw it L177D2 lbsr LeftMV go left one pixel bra L177D3 * 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+SysRet * 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 Move # horizontal lines to draw to Y L1839 pshs y,x Preserve # lines left & screen ptr ldy <$009B 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 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+SysRet * 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 L1BB1 leax $0A,s bsr L18B7 tfr x,y leax $0F,s bsr L18B7 leax <$19,s ldd <$0055 lbsr L1BA1.0 ATD: lbsr L1B32 moved for size tfr x,y leax <$1E,s bsr L18B7 tfr x,y leax <$23,s bsr L18B7 leax <$28,s lbsr L1B32.0 ATD: CLRD moved for size leax <$2D,s ldd <$001E lbsr L1B32 IFNE H6309 decd Doesn't affect circle ELSE subd #1 ENDC lbsr L1BA1 leay $0A,s lbsr L1BB4 leay $05,s bsr L19C3 leax ,s bsr L19C6 lbsr L1B63 ATD: LDD moved for size leay <$1E,s lbsr L1BB4 tfr x,y 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 L19C3 tfr x,y bsr L19C3.0 ATD: LEAX moved for size leax <$14,s leay $05,s * [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 IFNE H6309 decd Doesn't affect circle ELSE subd #1 ENDC std <$001E L19A0 leax <$37,s leay <$23,s bsr L19C3 tfr x,y bsr L19C3.0 ATD: LEAX moved for size leax <$28,s leay <$19,s bsr L19C3 ldd <$001C IFNE H6309 incd Doesn't affect circle ELSE addd #1 ENDC std <$001C 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 L1B32 IFNE H6309 incd Doesn't affect circle ELSE addd #1 ENDC bsr L19C0 leay <$1E,s lbsr L1BB4 leax ,s ldd <$001E lbsr L1B32 subd #$0002 bsr L19C0 lbsr L1B63 ATD: LDD moved for size leay $0A,s lbsr L1BB4 tfr x,y bsr L19C3.0 ATD: LEAX moved for size leax ,s leay $0A,s bsr L19C6 lbsr L1B63 ATD: LDD moved for size leay <$19,s lbsr L1BB4 tfr x,y bsr L19C3.0 ATD: LEAX moved for size leax <$32,s leay <$23,s lbsr L1B3B ldd <$001C bsr L19C0 leax <$37,s bsr L19C6.0 ATD: LEAY moved for size bsr L19C0.0 ATD: LDD moved for size leay $0A,s 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 L1A57 leax <$32,s leay <$23,s bsr L1A6E tfr x,y bsr L1A6E.0 ATD: LEAX moved for size ldd <$001C 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+SysRet * 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 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 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 L1B3B pshs d IFNE H6309 ldq ,y stq ,x ELSE ldd 2,y std <$B5 std 2,x ldd ,y std ,x ENDC ldb 4,y stb 4,x puls pc,d L1B52 exg y,u exg x,y bsr L1B3B exg x,y exg y,u 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,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,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 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 L1C2D rts L1C2E pshs d ldd ,x cmpd ,y bne L1C4D ldd $02,x cmpd $02,y bne L1C44 ldb $04,x cmpb $04,y beq L1C4D L1C44 bhi L1C4A lda #$08 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 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 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. bsr L1F1D ldx <$0072 lbra L1CC6 * 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 rts * Bit shift table to shift to the left 3,1 or 0 times * Used by FFill when filling to the left 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 VTIO. * 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+SysRet * 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 * 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+SysRet 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 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 [>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 * end