# HG changeset patch # User David Ladd # Date 1520901356 18000 # Node ID 6ea55a46a96337e1f3571a2a2e877ac0518c8447 # Parent 1d7d6a09a973f93bb7237041d7bce92e2c799c43 Updated vtio.asm for some optimizations that can be shared between grfdrv.asm, covdg.asm. Updated grfdrv.asm to take advantage of the vector changes in vtio.asm Updated covdg.asm to take advantage of the vecor changes in vtio.asm diff -r 1d7d6a09a973 -r 6ea55a46a963 level1/cmds/grfdrv.asm --- a/level1/cmds/grfdrv.asm Sun Mar 11 01:40:13 2018 -0600 +++ b/level1/cmds/grfdrv.asm Mon Mar 12 19:35:56 2018 -0500 @@ -8,6 +8,7 @@ * ------------------------------------------------------------------ * 1 ????/??/?? * From Tandy OS-9 Level One VR 02.00.00. +* 2 2018/03/06 Various minor optimizations, and some 6309 optimizations nam GrfDrv ttl Graphics module @@ -22,7 +23,7 @@ tylg set Systm+Objct atrv set ReEnt+rev rev set $00 -edition set 1 +edition set 2 mod eom,name,tylg,atrv,start,size @@ -242,24 +243,33 @@ bsr DrwPt2 bra L014A -DrwPt2 jsr [256,x else move X up 256 bytes - bra L0056 and return first 256 bytes -L0052 leau >COLSIZE*ROWSIZE,u else move X up 512 bytes -L0056 ldd #256 and return last 256 bytes - os9 F$SRtMem free it! - puls u restore static ptr - stx 256,x else move X up 256 bytes + bra L0056 and return first 256 bytes + +L0052 leau >COLSIZE*ROWSIZE,u else move X up 512 bytes +L0056 ldd #256 and return last 256 bytes + os9 F$SRtMem free it! + puls u restore static ptr + stx COLSIZE*ROWSIZE,x point to end of screen - stx COLSIZE*ROWSIZE,x point to end of screen + stx CG2: - lda $FF22 - anda #$8F - ora #$A0 - sta $FF22 + lda $FF22 + anda #$8F + ora #$A0 + sta $FF22 * SAM -> CG2: - sta $FFC0 clear GM0 - sta $FFC3 set GM1 - sta $FFC4 clear GM2 - + sta $FFC0 clear GM0 + sta $FFC3 set GM1 + sta $FFC4 clear GM2 puls u,cc ***** END OF COCOVGA 64x32 MODE - ENDC - - lbsr ClrScrn clear the screen - + ENDC + lbsr ClrScrn clear the screen * Setup page to ldb V.ClrBlk,u Get Clear block vector for later + pshs u,x Save static mem ptr & Clear block vector + ldx >V.CpyBlk,u Get vector to Copy block + ldy V.ClrBlk,u Get Clear Block subroutine address + ELSE + pshs x Save start addr to clear from + ldd V.ClrBlk,u Get Clear Block subroutine address + pshs u Save static mem ptr + ENDC + ldu =11? + bge NoErr1 yep, ignore & return w/o error + cmpa #1 is it one (Blue cursor from level 1)? + bgt L01C7 No, try next + lda #$AF Yes, default blue cursor color + bra L01D7 and save it + +L01C7 cmpa #2 is it two (black cursor from level 1)? + bgt L01CF branch if larger + lda #$A0 else get black cursor color + bra L01D7 and save it + +L01CF lsla shift into upper nibble lsla lsla lsla ora #$8F -L01D7 sta V.ClrBlk,u Get ClrBlk vector (before we destroy u) + pshs u Save static mem ptr + leau b,x Point U to end of line + clra D=size + tfr d,x Move to X for ClrBlk + ldb #$60 VDG space char + jsr ,y Call ClrBlk + puls u Get static mem back + lbra ShowCrsr Turn cursor back on & return from there * $09 - cursor up -CurUp lbsr HideCrsr hide cursor - leax <-COLSIZE,x move X up one line - cmpx AltIRQ,pcr get IRQ routine ptr + leax D.AltIRQ store in AltIRQ leax >SetDsply,pcr get display vector stx XY2Addr,pcr get address of XY2Addr stx ClrBlk,pcr get address for mini-stack blast clear mem routine + stx >V.ClrBlk,u Save as vector + leax >CpyBlk,pcr get address for mini-stack blast mem copy (scroll) routine + stx >V.CpyBlk,u Save as vector ldd D.Clock get clock vector - stx >D.AltIRQ and put back in AltIRQ - puls pc,cc Restore interrups & return - * Read * * Entry: @@ -147,38 +141,38 @@ * ldy #$aa57 * puls y - leax V.InBuf,u point X to input buffer - ldb V.IBufT,u get tail pointer - orcc #IRQMask mask IRQ - cmpb V.IBufH,u same as head pointer - beq Put2Bed if so, buffer is empty, branch to sleep - abx X now points to curr char - lda ,x get char - bsr L009D check for tail wrap - stb V.IBufT,u store updated tail + leax V.InBuf,u point X to input buffer + ldb V.IBufT,u get tail pointer + orcc #IRQMask mask IRQ + cmpb V.IBufH,u same as head pointer + beq Put2Bed if so, buffer is empty, branch to sleep + abx X now points to curr char + lda ,x get char + bsr L009D check for tail wrap + stb V.IBufT,u store updated tail andcc #^(IRQMask+Carry) unmask IRQ FlashCursor rts -Put2Bed lda V.BUSY,u get calling process ID - sta V.WAKE,u store in V.WAKE - andcc #^IRQMask clear interrupts +Put2Bed lda V.BUSY,u get calling process ID + sta V.WAKE,u store in V.WAKE + andcc #^IRQMask clear interrupts ldx #$0000 - os9 F$Sleep sleep forever - clr V.WAKE,u clear wake - ldx D.Clock get clock vector + stx >D.AltIRQ and put back in AltIRQ + puls pc,cc Restore interrupts & return + * Write - move to just after initial jump table to make short branch, since this * will be the most often used routine in VTIO * @@ -679,7 +689,7 @@ Escape beq L03C5 if $1E, we conveniently ignore it leax PIA1Base+2 @@ -700,22 +711,22 @@ ora PIA1Base+2 sta $FFC0 No, set up for 32x16 text screen - stb >$FFC2 - stb >$FFC4 + stb -6,x $FFC0 No, set up for 32x16 text screen + stb -4,x $FFC2 + stb -2,x $FFC4 lda $FFC0 - stb >$FFC3 - stb >$FFC5 +DoGfx stb -6,x $FFC0 + stb -3,x $FFC3 + stb -1,x $FFC5 lda PIA0Base+3 ora #$08 - ldy R$X,x + leay ,y bne L0494 anda #$F7 -L0494 sta >PIA0Base+3 - lda >PIA0Base+1 +L0494 ldy #PIA0Base+1 Point to PIA most used address in following routine + sta 2,y PIA0Base+3 + lda ,y PIA0Base+1 anda #$F7 bsr L04B3 - std R$X,x - lda >PIA0Base+1 + std R$X,x Save X coord of joystick + lda ,y PIA0Base+1 ora #$08 bsr L04B3 pshs d ldd #63 subd ,s++ - std R$Y,x + std R$Y,x Save Y coord of joystick clrb puls pc,y,cc -L04B3 sta >PIA0Base+1 +L04B3 sta ,y PIA0Base+1 ldd #$7F40 L04C7 pshs b sta >PIA1Base - tst >PIA0Base + tst -1,y PIA0Base bpl L04D5 adda ,s+ L04BC lsrb @@ -880,8 +882,8 @@ clrb L050E rts -* This vector also gets called from Grfdrv -* Entry: A = X coor, B = Y coor +* This vector also gets called from Grfdrv via V.CnvVct +* Entry: A = X coord, B = Y coord * Exit: Y=Base address of screen, X=ptr to byte on screen, A=pixel mask for specific pixel XY2Addr pshs y,d save off regs ldb CoVDG,pcr + leax CoWP,pcr + leax Co42,pcr + leax CoHR,pcr + leax GrfDrv,pcr get pointer to name string + leax GrfDrv,pcr get pointer to name string + leax Mode1Clr,pcr point to color mask table + leax Mode1Clr,pcr point to color table + leax 6144,u Point to end of screen+1 - ldd #$0600 6 blocks of 256 (how many 4 byte chunks to clear) -InCLSLp pshu x,y 4 bytes cleared - decb - bne InCLSLp Not done 256*4 (1k) bytes - deca Dec 1K blocks ctr - bne InCLSLp Do till done - puls x,y,u Restore regs - +* Entry for clearing with color 0 +Do13 clrb Color 0 to clear with +* Entry for clearing with color in B +L07B2 pshs b,u Save color code & static mem ptr + ldy >V.ClrBlk,u Get ptr to ClrBlk routine + ldd #6144 Size of gfx screen to clear + addd PIA0Base+1 - ldb >PIA0Base+3 +* 6809/6309 - preserve X as well, and then ldx #PIA0Base+3 and used ,x offsets +* NOTE: This is much more sophisticated than the Dragon version. Not sure if +* it has to be. (See DoBell in CoHR/Co42) +Ding pshs d,x + ldx #PIA0Base+3 Point to most common address we will be using + lda -2,x >PIA0Base+1 + ldb ,x >PIA0Base+3 pshs d -* 6309 - ANDD #$F7F7 + IFNE H6309 + andd #$F7F7 + ELSE anda #$F7 andb #$F7 - sta >PIA0Base+1 - stb >PIA0Base+3 + ENDC + sta -2,x >PIA0Base+1 + stb ,x >PIA0Base+3 lda >PIA1Base+3 pshs a ora #$08 sta >PIA1Base+3 - ldb #$0A + ldb #10 Outside loop ctr L07E6 lda #$FE bsr DingDuration lda #$02 @@ -1365,9 +1366,9 @@ puls a sta >PIA1Base+3 puls d - sta >PIA0Base+1 - stb >PIA0Base+3 - puls pc,d + sta -2,x >PIA0Base+1 + stb ,x >PIA0Base+3 + puls pc,x,d DingDuration sta >PIA1Base @@ -1376,6 +1377,93 @@ bne L0805 rts +* Since these are called by a JSR vector, they doesn't need to be near anything, so put +* both ClrBlk & CpyBlk at end of VTIO, and set up vectors to them in VTIO Init routine + +* ClrBlk - Clear contiguous block of memory with a byte value (grfdrv level II text mode +* patches will need 16 bit word value to cover attribute/character bytes) +* HOPEFULLY OPTIMIZED SMALLER FOR 6809 03/12/2018 LCB +* Entry: B=byte value to clear with +* X=size +* U=ptr to end+1 of memory to clear up to +* Exit: U=Ptr to start of block of memory cleared (if 6809) OR +* Ptr to end of block of memory cleared (if 6309) +* NOTE that D and X are destroyed in 6809 version +* Will need to check all calling routines from various modules, to see which of above +* should be default (if ptr is needed), and adjust the other to match +* ClrBlk (aside from set up and/or leftover bytes) takes 3 cyc/byte in 6309 mode, and +* 3.5 cyc/byte in 6809 mode (except every 1,024th byte takes a few extra) +* Since these are called by a JSR vector, they doesn't need to be near anything, so put +* both ClrBlk & CpyBlk at end of VTIO, and set up vectors to them in VTIO Init routine +ClrBlk + IFNE H6309 + pshs b Save value to clear with + tfr x,w Move size to TFM size register + subr w,u Calc start ptr of block (TFM can't do 1 location to decrementing address) + tfm s,u+ Clear mem + puls b,pc Eat stack & return + ELSE + tfr b,a D=double copy of value to clear memory with + exg x,d D=Size to clear (in bytes), X=2 byte value to clear with + pshs b,x Save 16 bit value to clear with, & LSB of size (to check for leftover bytes) + lsra Divide size by 4 (since we are doing 4 bytes at a time) + rorb + lsra + rorb + pshs d Save mini-stackblast counters + ldd 2,s Get A=LSB of # of bytes to clear, B=byte to clear with + anda #$3 Non-even multiple of 4? + beq NoOdd Even, skip single byte cleanup copy +OverLp stb ,-u Save odd bytes + deca + bne OverLp +NoOdd ldd ,s++ Get Mini-stack blast ctrs back + beq ExitClrB No 4 byte blocks, done + tsta Special case: Is A=0? + bne NormClr No, start stack blasting + inca If A=0, bump to 1 so we don't wrap and try to do 256 1K copies +NormClr leay ,x Dupe 16 bit clear value to Y +ClrLp pshu x,y Clear 4 bytes + decb Dec "leftover" (<256) 4 byte block counter + bne ClrLp Keep doing till that chunk is done + deca Dec 1Kbyte counter + bne ClrLp Still going (B has been set to 0, so inner loop is 256 now) +ExitClrB puls b,x,pc Eat temp regs & return + ENDC + +* CpyBlk - Copy contiguous block of memory with a byte value (for screen scrolling, insert/delete line,etc.) +* New, more optimized version (I hope) as of March 12, 2018 +* Entry: D=size of copy +* Y=ptr to destination of copy +* U=ptr to source of copy (PULU from here on 6809 version) +* Exit: U=Ptr to end of source copy+1 +* Y=Ptr to end of dest copy+1 +* D=NOTE: NEW CODE WILL HAVE D AS END ADDRESS OF SOURCE OF COPY +* NOTE: No routines in VTIO use this call - it will be called from sub-modules. Putting it in here +* since VTIO always gets initialized first. + IFNE H6309 +CpyBlk tfr d,w Copy size to TFM size register + tfm u+,y+ Copy memory + rts + ELSE +CpyBlk leax d,u Calculate source end address + pshs x Save on stack to compare with so we know when to stop + andb #$03 Check if we have odd bytes leftover (1-3) + beq CpyLpSt No, skip to check if copy is done, and stack blast 4 byte chunks if yes +CpyLp2 lda ,u+ (6) Copy extra 1-3 bytes + sta ,y+ (6) + decb (2) + bne CpyLp2 (3) + bra CpyLpSt Start with cmpu to end of copy (if copy was only 1-3 bytes, we are done already) + +* Now, copy all 4 byte chunks. End address remains the same, so we can eliminate some stuff we had before +CpyLp pulu d,x Get 4 bytes from source (ascending order) + std ,y++ Copy to destination + stx ,y++ +CpyLpSt cmpu ,s Done 4 byte blast copy? + blo CpyLp No, keep doing until done + puls pc,d Get end address of source copy and return + ENDC emod eom equ * end