Mercurial > hg > Members > kono > nitros9-code
changeset 3249:6ea55a46a963
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
author | David Ladd <drencor-xeen@users.sourceforge.net> |
---|---|
date | Mon, 12 Mar 2018 19:35:56 -0500 |
parents | 1d7d6a09a973 |
children | 13737f3608e6 |
files | level1/cmds/grfdrv.asm level1/modules/covdg.asm level1/modules/vtio.asm |
diffstat | 3 files changed, 749 insertions(+), 581 deletions(-) [+] |
line wrap: on
line diff
--- 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 [<V.CnvVct,u] Get offset into screen memory & bit mask for pixel +* Draw a single point. Called by set point/erase point, and circle +* Entry: A=pixel X position to draw +* B=pixel Y position to draw +DrwPt2 jsr [<V.CnvVct,u] Get offset into screen memory (X) & bit mask for pixel (A) +* Draw single point w/o needing conversion of address/mask. Called by Line and Flood Fill L0081 tfr a,b Duplicate pixel mask + IFNE H6309 + comb Flip to keep background pixels + andb ,x + anda <V.Msk1,u and pixel mask with color mask + orr b,a Merge foreground pixel onto background + sta ,x Save it to screen + ELSE comb Flip to keep background pixels andb ,x stb ,x anda <V.Msk1,u and pixel mask with color mask ora ,x Merge foreground pixel onto background sta ,x Save it to screen + ENDC rts - Circle leas -4,s make room on stack -* 6809/6309 - Chg next 4 lines to clra / ldb <V.NChr2,u / std ,s clra - ldb <V.NChr2,u get radius - std ,s store b store on stack and make D=radius (both D and on stack) - addb 1,s Add to itself (D=diameter) - adca #$00 + ldb <V.NChr2,u get radius into D + std ,s store on stack and make D=radius (both D and on stack) + addd ,s IFNE H6309 negd Invert sign of D ELSE @@ -271,11 +281,11 @@ std 2,s Save that L0179 lda ,s cmpa 1,s - bcc L01AB + bhs L01AB ldb 1,s bsr L01B9 clra - ldb $02,s + ldb 2,s bpl L0193 ldb ,s lslb @@ -357,53 +367,83 @@ leas 8,s Eat temp stack & return rts -L0202 pshs d +* Not sure on these, but I think: +* Entry: D=X coord of some sort +* X=Y coord of some sort +L0202 + IFNE H6309 + tfr d,w + ELSE + pshs d + ENDC ldb <V.GCrsY,u Get Y coord of graphics cursor (center of circle) -* 6809/6309 - B is unsigned, so an abx instead of clra / leax d,x should work (-2 bytes/-7 cyc) -* clra -* leax d,x abx cmpx #$0000 Off bottom of screen? bmi L0214 Yes, return cmpx #191 Off top of screen? ble L0216 No, go draw pixels -L0214 puls pc,d Off screen vertically, return - +L0214 + IFNE H6309 + rts + ELSE + puls pc,d Off screen vertically, return + ENDC + L0216 ldb <V.GCrsX,u Get X coord of graphics cursor (center of circle) into D clra tst <V.Mode,u Check graphics mode bmi L0221 2 color, skip ahead lslb 4 color, Shift left 1 bit rola -L0221 addd ,s++ Add to ? +L0221 + IFNE H6309 + addr w,d Add to ? + ELSE + addd ,s++ Add to ? + ENDC tsta If <256, continue beq L0227 rts Else return -L0227 pshs b Save 8 bit version of value +L0227 + IFNE H6309 + tfr b,e Save Y coord in E (3 tfr's in native mode 2 cyc faster) + tfr x,d Move low byte of X to B + tfr e,a Move Y coord to A + ELSE + pshs b Save 8 bit version of value tfr x,d Move low byte of X to B puls a And restore value, this time as A + ENDC tst <V.Mode,u Check graphics mode lbmi DrwPt2 If 2 color, draw pixel on screen & return from there lsra 4 color, shift 1 more first lbra DrwPt2 * $1D - flood fill +* Change by LCB - keep V.Mode in E, since it gets checked. A lot. Do1D clr <V.FFFlag,u Clear flag - leas -$07,s + leas -7,s lbsr L03AB Allocate 512 byte Flood fill stack, if not already allocated lbcs L0346 Not allocated, and couldn't get it, exit with error - lda #$FF + IFNE H6309 + lde <V.Mode,u Get gfx mode, so we can keep in E for faster checking + ENDC + lda #-1 $FF Set direction flag to -1 (X direction, I think) sta <V.4F,u - ldd <V.GCrsX,u + ldd <V.GCrsX,u Get graphics cursor X,Y coords lbsr L0351 lda <V.4C,u sta <V.4D,u + IFNE H6309 + tste which mode? + ELSE tst <V.Mode,u which mode? + ENDC bpl L0261 branch if 128x192 tsta - beq L0267 - lda #$FF + beq L0267 Color 0 byte mask for 2 color + lda #$FF Color 1 byte mask for 2 color bra L0267 * 128x192 4 color pixel table - NOTE THIS IS DUPLICATED IN VTIO @@ -412,11 +452,11 @@ * Entry: A=color # 0-3 L0261 leax <Mode1Clr,pcr Point to 4 color color mask table lda a,x Get mask for selected color -L0267 sta <V.4E,u Save copy of it +L0267 sta <V.4E,u Save copy of color mask cmpa <V.Msk1,u lbeq L0346 - ldd <V.GCrsX,u -L0274 suba #$01 + ldd <V.GCrsX,u Get gfx cursor cursory X,Y coords +L0274 suba #$01 bcs L027F Wrapped negative, skip ahead lbsr L0351 beq L0274 @@ -424,22 +464,22 @@ std 1,s L0282 lbsr L0384 adda #$01 - bcs L0290 + bcs L0290 Wrapped past 256, skip ahead lbsr L0351 bcs L0290 beq L0282 L0290 deca ldx 1,s lbsr L03D3 - neg <V.4F,u + neg <V.4F,u Flip X direction lbsr L03D3 L029C lbsr L03F9 lbcs L0346 - tst <V.4F,u - bpl L02B3 - subb #$01 - bcs L029C - std 3,s + tst <V.4F,u Check current X direction + bpl L02B3 If +1, go increment + subb #$01 negative, so subtract 1 + bcs L029C If wrapped, go back + std 3,s Save coords tfr x,d decb bra L02BD @@ -475,7 +515,7 @@ decb cmpd 5,s beq L02FB - neg <V.4F,u + neg <V.4F,u ?? Maybe direction flag? ldx 5,s lbsr L03D3 neg <V.4F,u @@ -529,7 +569,11 @@ L0351 pshs d cmpb #191 bhi L0380 If past top of screen, exit with carry set - tst <V.Mode,u which gfx mode? + IFNE H6309 + tste which mode? + ELSE + tst <V.Mode,u which mode? + ENDC bmi L0360 2 color, skip ahead cmpa #127 4 color, check if we are past right side of screen bhi L0380 Yes, exit with carry set @@ -540,7 +584,11 @@ bne L0376 Yes, exit with carry clear and other flags set (zero, negative,etc.) lsra No, shift pixel masks right 1 bit lsrb - tst <V.Mode,u If 2 color, check again + IFNE H6309 + tste which mode? + ELSE + tst <V.Mode,u which mode? + ENDC bmi L0367 lsra If 4 color, shift once more (2 bits/pixel) and check again lsrb @@ -564,7 +612,11 @@ ldb <V.Msk1,u stb ,x puls d + IFNE H6309 + tste 2 color mode? + ELSE tst <V.Mode,u 2 color mode? + ENDC bmi L03A3 Yes, skip ahead adda #$03 rts @@ -597,7 +649,7 @@ clrb rts -* Add FFill stack entry (4 bytes) +* Add FFill stack entry (4 bytes). Max of 128 entries allowed. L03D3 pshs d ldd <V.FFSPt,u Get current FFill stack ptr subd #$0004 Add 4 bytes to it @@ -605,7 +657,7 @@ blo L03F2 Yes, error out std <V.FFSPt,u No, Save new FFill stack ptr tfr d,y Move new ptr to indexable register - lda <V.4F,u Get? + lda <V.4F,u Get? (direction flag, maybe?) sta ,y Save on stack stx 1,y Save (mem ptr on screen, I think?) puls d Get ?? back
--- a/level1/modules/covdg.asm Sun Mar 11 01:40:13 2018 -0600 +++ b/level1/modules/covdg.asm Mon Mar 12 19:35:56 2018 -0500 @@ -14,6 +14,12 @@ * * 2017/12/20 Boisy Pitre * Added support for CoCoVGA 64x32 mode +* +* 2 2018/03/02 David Ladd +* L. Curtis Boyle +* General optimizations, and support for new V.ClrBlk and V.CpyBlk +* vector calls (from VTIO) for either 6309 TFM for mini-stack blasting +* (4 bytes/chunk) for screen scroll and screen clears (full & partial) nam CoVDG ttl VDG Console Output Subroutine for VTIO @@ -28,7 +34,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 @@ -54,54 +60,41 @@ ENDC fcb edition -start equ * - lbra Init - lbra Write - lbra GetStat - lbra SetStat -Term pshs y,x - pshs u save U - ldd #COLSIZE*ROWSIZE VDG memory size - ldu <V.ScrnA,u get pointer to memory - os9 F$SRtMem return to system - puls u restore U - ldb <V.COLoad,u - andb #~ModCoVDG - bra L0086 * Init -Init pshs y,x save regs +Init pshs y,x save regs lda #$AF - sta <V.CColr,u save default color cursor - pshs u save static ptr - ldd #COLSIZE*ROWSIZE+256 allocate screen + 256 bytes for now - os9 F$SRqMem get it - tfr u,d put ptr in D - leax ,u and X - bita #$01 odd page? - beq L0052 branch if not - leax >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 <V.ScrnA,u save VDG screen memory + sta <V.CColr,u save default color cursor + pshs u save static ptr + ldd #COLSIZE*ROWSIZE+256 allocate screen + 256 bytes for now + os9 F$SRqMem get it + tfr u,d put ptr in D + leax ,u and X + bita #$01 odd page? + beq L0052 branch if not + leax >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 <V.ScrnA,u save VDG screen memory pshs y leay -$0E,y clra clrb - jsr [<V.DspVct,u] display screen (routine in VTIO) + jsr [<V.DspVct,u] display screen (routine in VTIO) puls y - stx <V.CrsrA,u save start cursor position - leax >COLSIZE*ROWSIZE,x point to end of screen - stx <V.ScrnE,u save it -LDClrCh lda #$60 get default character - sta <V.CChar,u put character under the cursor - sta <V.Chr1,u only referenced here ?? + stx <V.CrsrA,u save start cursor position + leax >COLSIZE*ROWSIZE,x point to end of screen + stx <V.ScrnE,u save it +LDClrCh lda #$60 get default character + sta <V.CChar,u put character under the cursor + sta <V.Chr1,u only referenced here ?? - IFNE COCOVGA + IFNE COCOVGA ***** START OF COCOVGA 64x32 MODE - clr <V.Caps,u lowercase mode + clr <V.Caps,u lowercase mode pshs cc,u orcc #IntMasks leax VGASetup,pcr @@ -112,415 +105,450 @@ decb bne x@ - lda $FF02 clear any pending vsync -tlp@ lda $FF03 wait for flag to indicate - bpl tlp@ falling edge of FS - lda $FF02 clear vsync interrupt flag - + lda $FF02 clear any pending vsync +tlp@ lda $FF03 wait for flag to indicate + bpl tlp@ falling edge of FS + lda $FF02 clear vsync interrupt flag * PROGRAM THE COCOVGA COMBO LOCK -BT13 lda $FF22 GET CURRENT PIA VALUE - tfr A,B COPY TO B REG TOO - anda #$07 MASK OFF BITS WE'LL CHANGE - ora #$90 SET COMBO LOCK 1 BITS - sta $FF22 WRITE TO PIA FOR COCOVGA - anda #$07 CLEAR UPPER BITS - ora #$48 SET COMBO LOCK 2 BITS - sta $FF22 WRITE TO PIA - anda #$07 CLEAR UPPER BITS - ora #$A0 SET COMBO LOCK 3 BITS - sta $FF22 WRITE TO PIA - anda #$07 CLEAR UPPER BITS - ora #$F8 SET COMBO LOCK 4 BITS - sta $FF22 WRITE TO PIA - anda #$07 CLEAR UPPER BITS - ora #$00 SET REGISTER BANK 0 FOR COCOVGA - sta $FF22 WRITE TO PIA +BT13 lda $FF22 GET CURRENT PIA VALUE + tfr A,B COPY TO B REG TOO + anda #$07 MASK OFF BITS WE'LL CHANGE + ora #$90 SET COMBO LOCK 1 BITS + sta $FF22 WRITE TO PIA FOR COCOVGA + anda #$07 CLEAR UPPER BITS + ora #$48 SET COMBO LOCK 2 BITS + sta $FF22 WRITE TO PIA + anda #$07 CLEAR UPPER BITS + ora #$A0 SET COMBO LOCK 3 BITS + sta $FF22 WRITE TO PIA + anda #$07 CLEAR UPPER BITS + ora #$F8 SET COMBO LOCK 4 BITS + sta $FF22 WRITE TO PIA + anda #$07 CLEAR UPPER BITS +* 6809/6309 - Isn't this next line useless? It does not change any bits, ever + ora #$00 SET REGISTER BANK 0 FOR COCOVGA + sta $FF22 WRITE TO PIA * Wait for next VSYNC so CoCoVGA can process data from the current video page -tlp@ lda $FF03 - bpl tlp@ +tlp@ lda $FF03 + bpl tlp@ * Restore PIA state and return to text mode - restore original video mode, SAM page * VDG -> 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.COLoad,u - orb #ModCoVDG set to CoVDG found (?) + orb #ModCoVDG set to CoVDG found (?) L0086 stb <V.COLoad,u clrb puls pc,y,x - IFNE COCOVGA + IFNE COCOVGA ***** START OF COCOVGA 64x32 MODE -VGASetup fcb $00 Reset register - fcb $81 Edit mask - fcb $00 Reserved - fcb $03 Font - fcb $00 Artifact - fcb $00 Extras - fcb $00 Reserved - fcb $00 Reserved - fcb $02 Enhanced Modes +VGASetup fcb $00 Reset register + fcb $81 Edit mask + fcb $00 Reserved + fcb $03 Font + fcb $00 Artifact + fcb $00 Extras + fcb $00 Reserved + fcb $00 Reserved + fcb $02 Enhanced Modes VGASetupLen equ *-VGASetup ***** END OF COCOVGA 64x32 MODE - ENDC + ENDC +start bra Init + nop Can be used for a constant + bra Write + nop Can be used for a constant + lbra GetStat + lbra SetStat +Term pshs y,x + pshs u save U + ldd #COLSIZE*ROWSIZE VDG memory size + ldu <V.ScrnA,u get pointer to memory + os9 F$SRtMem return to system + puls u restore U + ldb <V.COLoad,u + andb #~ModCoVDG + bra L0086 * Write * Entry: A = char to write * Y = path desc ptr -Write tsta - bmi L00D0 - cmpa #$1F byte $1F? - bls Dispatch branch if lower or same - ldb <V.CFlag,u - beq L00B0 - cmpa #$5E - bne L00A0 - clra - bra L00D0 -L00A0 cmpa #$5F - bne L00A8 - lda #$1F - bra L00D0 -L00A8 cmpa #$60 - bne L00C0 - lda #$67 +Write tsta Alt (hi bit) char? + bmi L00D0 Yes, go straight to print + cmpa #$1F Ctrl char? ($00-$1F)? + bls Dispatch Yes, special handling + ldb <V.CFlag,u regular ASCII char; get true lowercase flag + beq L00B0 Not set, skip ahead +* VDG-T1 translations + cmpa #$5E ^ symbol? + bne L00A0 Nope, check next + clra 0 char on VDG + bra L00D0 Put on screen + +L00A0 cmpa #$5F _ Underline char? + bne L00A8 No, check next + lda #$1F $1F char on VDG + bra L00D0 Put on screen + +L00A8 cmpa #$60 ' Single quote? + bne L00C0 No, skip ahead to common translations + lda #$67 $67 char on VDG bra L00D0 -L00B0 cmpa #$7C - bne L00B8 - lda #$21 - bra L00D0 -L00B8 cmpa #$7E - bne L00C0 - lda #$2D - bra L00D0 -L00C0 cmpa #$60 - bcs L00C8 - suba #$60 - bra L00D0 -L00C8 cmpa #$40 - bcs L00CE - suba #$40 -L00CE eora #$40 -L00D0 ldx <V.CrsrA,u get cursor address in X - sta ,x+ store character at address - stx <V.CrsrA,u update cursor address - cmpx <V.ScrnE,u end of screen? - bcs L00DF branch if not - bsr SScrl else if at end of screen, scroll it -L00DF bra ShowCrsr ends with a CLRB/RTS anyhow + +* Regular VDG translations +L00B0 cmpa #$7C | Pipe symbol? + bne L00B8 No, check next + lda #$21 Yes, change to ! pipe symbol + bra L00D0 Put on screen + +L00B8 cmpa #$7E ~ Tilde symbol? + bne L00C0 Nope, go do common translations + lda #$2D Tilde symbol for VDG + bra L00D0 Put on screen + +* Common translation to both VDG chips +L00C0 cmpa #$60 Char below $60? + blo L00C8 Yes, check next range + suba #$60 Drop by $60 for VDG translation + bra L00D0 Put on screen + +L00C8 cmpa #$40 Char below $40? + blo L00CE Yes, Flip case bit only + suba #$40 Drop for VDG +L00CE eora #$40 Force to non-inverse chars on regular VDG +L00D0 ldx <V.CrsrA,u get cursor address in X + sta ,x+ store character at address + stx <V.CrsrA,u update cursor address + cmpx <V.ScrnE,u end of screen? + blo L00DF No, just display the cursor + bsr SScrl Yes, scroll the screen first +L00DF bra ShowCrsr And turn the cursor back on * Screen Scroll Routine -SScrl - IFNE H6309 - ldx <V.ScrnA,u get address of screen - ldd #COLSIZE*256+$60 - leay a,x down one line - ldw #COLSIZE*ROWSIZE-COLSIZE - tfm y+,x+ scroll screen up - stx <V.CrsrA,u save new cursor address - ELSE - ldy <V.ScrnA,u get address of screen - ldx <V.ScrnE,u get address of end of screen - pshs u,y,x save u y x on stack - leau <COLSIZE,y get address of second line -ScrlLp@ pulu d,x pull D and X off of U stack for line two - std ,y++ write D into new location - stx ,y++ write X into new location - cmpu ,s compare U to end of screen - bls ScrlLp@ check if we reached end of line if not do more - puls x,y,u restore U X and D registers - leax -COLSIZE,x - stx <V.CrsrA,u - ldd #COLSIZE*256+$60 A=clear out row... B= with spaces - ENDC -L00FD stb ,x+ do it... - deca end of rope? - bne L00FD branch if not +SScrl ldd #COLSIZE*ROWSIZE-COLSIZE Size of screen minus one line + ldx >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.ScrnA,u Get ptr to start of text screen + leau <COLSIZE,y Point to start of 2nd line + jsr ,x Call copy block vector (U will point to end of screen+1) + ldx #COLSIZE Size of block to clear (bottom line) + ldb #$60 VDG Space char + puls y Get clear block vector + jsr ,y Clear last line (U was pointing to end of last line from above, so it picks up where it left off. I think) +* Since 6309 returns with U=ptr to end of screen, and 6809 returns with ptr to start of last line, +* we need to differentiate here + IFNE H6309 + leax -COLSIZE,u 6309 - Bump back to start of last line + ELSE + leax ,u 6809 - already pointing to start of last line + ENDC + puls u Get back static mem ptr + stx <V.CrsrA,u Save new cursor position (Start of last line) + rts & return + +* Ctrl char ($00-$1F) special char dispatch +Dispatch cmpa #$1B escape code? + bhs bad@ branch if same or greater (special control codes for screen controls) + cmpa #$0E $0E? + bhi L0102 branch if higher than + leax <DCodeTbl,pcr deal with screen codes + lsla adjust for table entry size + ldd a,x get address in D + jmp d,x and jump to routine +bad@ comb + ldb #E$Write L0102 rts -Dispatch cmpa #$1B escape code? - bcc bad@ branch if same or greater - cmpa #$0E $0E? - bhi L0102 branch if higher than - leax <DCodeTbl,pcr deal with screen codes - lsla adjust for table entry size - ldd a,x get address in D - jmp d,x and jump to routine -bad@ comb - ldb #E$Write - rts - -* display functions dispatch table -DCodeTbl fdb NoOp-DCodeTbl $00:no-op (null) - fdb CurHome-DCodeTbl $01:HOME cursor - fdb CurXY-DCodeTbl $02:CURSOR XY - fdb DelLine-DCodeTbl $03:ERASE LINE - fdb ErEOLine-DCodeTbl $04:CLEAR TO EOL - fdb Do05-DCodeTbl $05:CURSOR ON/OFF - fdb CurRght-DCodeTbl $005e $06:CURSOR RIGHT - fdb NoOp-DCodeTbl $07:no-op (bel:handled in VTIO) - fdb CurLeft-DCodeTbl $0050 $08:CURSOR LEFT - fdb CurUp-DCodeTbl $0119 $09:CURSOR UP - fdb CurDown-DCodeTbl $0038 $0A:CURSOR DOWN - fdb ErEOScrn-DCodeTbl $006c $0B:ERASE TO EOS - fdb ClrScrn-DCodeTbl $0070 $0C:CLEAR SCREEN - fdb Retrn-DCodeTbl $001e $0D:RETURN - fdb DoAlpha-DCodeTbl $012a $0E:DISPLAY ALPHA +* display functions dispatch table. +DCodeTbl fdb L014D-DCodeTbl $00:no-op (null) + fdb CurHome-DCodeTbl $01:HOME cursor + fdb CurXY-DCodeTbl $02:CURSOR XY + fdb DelLine-DCodeTbl $03:ERASE LINE + fdb ErEOLine-DCodeTbl $04:CLEAR TO EOL + fdb Do05-DCodeTbl $05:CURSOR ON/OFF + fdb CurRght-DCodeTbl $06:CURSOR RIGHT + fdb L014D-DCodeTbl $07:no-op (bel:handled in VTIO) + fdb CurLeft-DCodeTbl $08:CURSOR LEFT + fdb CurUp-DCodeTbl $09:CURSOR UP + fdb CurDown-DCodeTbl $0A:CURSOR DOWN + fdb ErEOScrn-DCodeTbl $0B:ERASE TO EOS + fdb ClrScrn-DCodeTbl $0C:CLEAR SCREEN + fdb Retrn-DCodeTbl $0D:RETURN + fdb DoAlpha-DCodeTbl $0E:DISPLAY ALPHA * $0D - move cursor to start of line (carriage return) -Retrn bsr HideCrsr hide cursor - IFNE H6309 - aim #$E0,<V.CrsAL,u - ELSE - tfr x,d put cursor address in D - andb #~(COLSIZE-1) place at start of line - stb <V.CrsAL,u and save low cursor address - ENDC -ShowCrsr ldx <V.CrsrA,u get cursor address - lda ,x get char at cursor position - sta <V.CChar,u save it - lda <V.CColr,u get cursor character - beq L014D branch if none -L014B sta ,x else turn on cursor -NoOp -L014D clrb +Retrn bsr HideCrsr hide cursor + IFNE H6309 + aim #$E0,<V.CrsAL,u Force cursor to beginning of current line (clear low 5 bits of address) + ELSE + tfr x,d put cursor address in D + andb #~(COLSIZE-1) place at start of line + stb <V.CrsAL,u and save low cursor address + ENDC +ShowCrsr ldx <V.CrsrA,u get cursor address + lda ,x get char at cursor position + sta <V.CChar,u save it + lda <V.CColr,u get cursor character + beq L014D If cursor off, don't put on screen +L014B sta ,x else turn on cursor +L014D clrb & exit w/o error rts * $0A - cursor down (line feed) -CurDown bsr HideCrsr hide cursor - leax <COLSIZE,x move X down one line - cmpx <V.ScrnE,u at end of screen? - bcs L0162 branch if not - leax <-COLSIZE,x else go back up one line - pshs x save X - lbsr SScrl and scroll the screen - puls x restore pointer -L0162 stx <V.CrsrA,u save cursor pointer - bra ShowCrsr show cursor +CurDown bsr HideCrsr hide cursor + leax <COLSIZE,x move X down one line + cmpx <V.ScrnE,u at end of screen? + blo L0162 branch if not + leax <-COLSIZE,x else go back up one line + pshs x save cursor position + lbsr SScrl & scroll the screen + puls x restore pointer +L0162 stx <V.CrsrA,u save cursor pointer + bra ShowCrsr show cursor * $08 - cursor left -CurLeft bsr HideCrsr hide cursor - cmpx <V.ScrnA,u compare against start of screen - bls L0173 ignore it if at the screen start - leax -$01,x else back up one - stx <V.CrsrA,u save updated pointer -L0173 bra ShowCrsr and show cursor +CurLeft bsr HideCrsr hide cursor + cmpx <V.ScrnA,u compare against start of screen + bls L0173 ignore it if at the screen start + leax -1,x else back up one + stx <V.CrsrA,u save updated pointer +L0173 bra ShowCrsr and show cursor * $06 - cursor right -CurRght bsr HideCrsr hide cursor - leax $01,x move to the right - cmpx <V.ScrnE,u compare against end of screen - bcc L0181 if past end, ignore it - stx <V.CrsrA,u else save updated pointer -L0181 bra ShowCrsr and show cursor +CurRght bsr HideCrsr hide cursor + leax 1,x move to the right + cmpx <V.ScrnE,u compare against end of screen + bhs L0181 if past end, ignore it + stx <V.CrsrA,u else save updated pointer +L0181 bra ShowCrsr and show cursor * $0B - erase to end of screen -ErEOScrn bsr HideCrsr kill the cusror - bra L0189 and clear rest of the screen +ErEOScrn bsr HideCrsr kill the cusror + bra L0189 and clear rest of the screen * $0C - clear screen -ClrScrn bsr CurHome home cursor -L0189 equ * - IFNE H6309 - ldw <V.ScrnE,u - subr x,w - leay LDClrCh+1,pc - tfm y,x+ - ELSE - lda #$60 get default char -L018B sta ,x+ save at location - cmpx <V.ScrnE,u end of screen? - bcs L018B branch if not - ENDC - bra ShowCrsr now show cursor +ClrScrn bsr CurHome home cursor (and set X=ptr to start of screen) +* Entry point for partial screen clear +* Entry: X=ptr to start address to clear from +* For V.ClrBlk,u, entry is: B=value to clear with, X=size to clear, U=End of clear block address+1 +L0189 + IFNE H6309 + pshs u Save static mem ptr + ldy <V.ScrnE,u Get ptr to end of screen + subr x,y Calc size of clear by subtracting current cursor address + leax ,y X=size to clear + ldy >V.ClrBlk,u Get Clear Block subroutine address + ELSE + pshs x Save start addr to clear from + ldd <V.ScrnE,u Get ptr to end of screen + subd ,s++ Calc size of clear (subtract start addr) + tfr d,x Move size to X + ldy >V.ClrBlk,u Get Clear Block subroutine address + pshs u Save static mem ptr + ENDC + ldu <V.ScrnE,u Point to end address of screen + ldb #$60 VDG Space char + jsr ,y Go clear + puls u Get static mem ptr back + bra ShowCrsr Turn cursor back on + * $01 - home cursor -CurHome bsr HideCrsr hide cursor - ldx <V.ScrnA,u $1D get pointer to screen - stx <V.CrsrA,u $21 save as new cursor position - bra ShowCrsr and show it +CurHome bsr HideCrsr hide cursor + ldx <V.ScrnA,u get pointer to screen + stx <V.CrsrA,u save as new cursor position + bra ShowCrsr and show it * Hides the cursor from the screen * Exit: X = address of cursor -HideCrsr ldx <V.CrsrA,u $21 get address of cursor in X - lda <V.CChar,u $23 get value of char under cursor - sta ,x put char in place of cursor - clrb must be here, in general, for [...] BRA HideCrsr +HideCrsr ldx <V.CrsrA,u get address of cursor in X + lda <V.CChar,u get value of char under cursor + sta ,x put char in place of cursor +NoErr1 clrb must be here, in general, for [...] BRA HideCrsr rts * $05 XX - set cursor off/on/color per XX-32 -Do05 ldb #$01 need additional byte - leax <CrsrSw,pcr - bra L01E5 +Do05 ldb #$01 need additional byte + leax <CrsrSw,pcr Get vector to return to after we get byte + bra L01E5 Save vector, and go get parameter byte + +CrsrSw lda <V.NChr2,u get next char + suba #C$SPAC take out ASCII space + bne L01BB branch if not zero + sta <V.CColr,u else save cursor color zero (no cursor) + bra HideCrsr and hide cursor -CrsrSw lda <V.NChr2,u get next char - suba #C$SPAC take out ASCII space - bne L01BB branch if not zero - sta <V.CColr,u else save cursor color zero (no cursor) - bra HideCrsr and hide cursor -L01BB cmpa #$0B greater than $0B? - bge L014D yep, just ignore byte - cmpa #$01 is it one? - bgt L01C7 branch if greater - lda #$AF else get default blue cursor color - bra L01D7 and save cursor color -L01C7 cmpa #$02 is it two? - bgt L01CF branch if larger - lda #$A0 else get black cursor color - bra L01D7 and save it -** BUG ** BUG ** BUG ** BUG -L01CF suba #$03 ** BUG FIXED! ** !!! Was SUBB - lsla shift into upper nibble +L01BB cmpa #11 >=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.CColr,u save new cursor - ldx <V.CrsrA,u get cursor address - lbra L014B branch to save cursor in X +L01D7 sta <V.CColr,u save new cursor + ldx <V.CrsrA,u get cursor address + lbra L014B branch to save cursor in X * $02 XX YY - move cursor to col XX-32, row YY-32 -CurXY ldb #$02 we want to claim next two chars - leax <DoCurXY,pcr point to processing routine -L01E5 stx <V.RTAdd,u store routine to return to - stb <V.NGChr,u get two more chars - clrb +CurXY ldb #2 we neeed two more parameters + leax <DoCurXY,pcr Get vector to return to after we get params +L01E5 stx <V.RTAdd,u Save it + stb <V.NGChr,u Save # chars needed as params + clrb No error, and go get missing param bytes rts -DoCurXY bsr HideCrsr hide cursor - ldb <V.NChr2,u get ASCII Y-pos - subb #C$SPAC take out ASCII space - lda #COLSIZE go down - mul multiply it - addb <V.NChar,u add in X-pos +DoCurXY bsr HideCrsr hide cursor + ldb <V.NChr2,u get ASCII Y-pos + subb #C$SPAC take out ASCII space + lda #COLSIZE Calculate vertical offset from start of screen to line we want + mul multiply it + addb <V.NChar,u add in X-pos adca #$00 - subd #C$SPAC take out another ASCII space - addd <V.ScrnA,u add top of screen address - cmpd <V.ScrnE,u at end of the screen? - lbcc L014D exit if off the screen - std <V.CrsrA,u otherwise save new cursor address - lbra ShowCrsr and show cursor + subd #C$SPAC take out another ASCII space + addd <V.ScrnA,u add top of screen address + cmpd <V.ScrnE,u past end of screen? + bhs NoErr1 Yes, ignore & exit w/o error + std <V.CrsrA,u otherwise save new cursor address + lbra ShowCrsr and show cursor * $04 - erase to end of line -ErEOLine bsr HideCrsr hide cursor - tfr x,d move current cursor position in D - andb #COLSIZE-1 number of characters put on this line +ErEOLine bsr HideCrsr hide cursor + tfr x,d move current cursor position to D + andb #COLSIZE-1 number of characters put on this line pshs b - ldb #COLSIZE + ldb #COLSIZE Calculate # of chars left in line subb ,s+ - bra L0223 and clear one line + bra L0223 and clear that many * $03 - erase line -DelLine lbsr Retrn do a CR - ldb #COLSIZE line length -L0223 lda #$60 get default character - ldx <V.CrsrA,u get cursor address -L0228 sta ,x+ fill screen line with 'space' - decb decrement - bne L0228 and branch if not end - lbra ShowCrsr else show cursor +DelLine lbsr Retrn do a CR + ldb #COLSIZE line length +* Entry: B=# of bytes to erase, X=ptr to start of copy +L0223 ldy >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 <V.ScrnA,u compare against start of screen - bcs L023E branch if we went beyond - stx <V.CrsrA,u else store updated X -L023E lbra ShowCrsr and show cursor +CurUp lbsr HideCrsr hide cursor + leax <-COLSIZE,x move X up one line + cmpx <V.ScrnA,u We past top of screen? + blo L023E Yes, leave cursor pos along and turn it back on + stx <V.CrsrA,u No, save new cursor Y position +L023E lbra ShowCrsr Show cursor & return from there * $0E - switch screen to alphanumeric mode -DoAlpha clra - clrb - jmp [<V.DspVct,u] display screen (routine in VTIO) +DoAlpha clra + clrb Text mode + jmp [<V.DspVct,u] display screen (routine in VTIO) * GetStat -GetStat ldx PD.RGS,y get caller's regs - cmpa #SS.AlfaS AlfaS? - beq Rt.AlfaS branch if so - cmpa #SS.Cursr Cursr? - beq Rt.Cursr branch if so +GetStat ldx PD.RGS,y get caller's regs + cmpa #SS.AlfaS AlfaS? + beq Rt.AlfaS branch if so + cmpa #SS.Cursr Cursr? + beq Rt.Cursr branch if so -* SetStat +* SetStat - All SetStat calls return "Unknown Service" error SetStat comb ldb #E$UnkSvc rts * SS.AlfaS getstat -Rt.AlfaS ldd <V.ScrnA,u memory address of buffer - std R$X,x save in caller's X - ldd <V.CrsrA,u get cursor address - std R$Y,x save in caller's Y - lda <V.Caps,u save caps lock status in A and exit +Rt.AlfaS ldd <V.ScrnA,u memory address of buffer + std R$X,x save in caller's X + ldd <V.CrsrA,u get cursor address + std R$Y,x save in caller's Y + lda <V.Caps,u save caps lock status in A and exit bra SaveA * SS.Cursr getstat -Rt.Cursr ldd <V.CrsrA,u get address of cursor - subd <V.ScrnA,u subtract screen address - pshs b,a D now holds cursor position relative to screen +Rt.Cursr ldd <V.CrsrA,u get address of cursor + subd <V.ScrnA,u subtract screen address + pshs d D now holds cursor position relative to screen clra andb #COLSIZE-1 - addb #COLSIZE compute column position - std R$X,x save column position to caller's X - puls b,a then divide by 32 - lsra + addb #COLSIZE compute column position + std R$X,x save column position to caller's X + puls d then divide by 32 +* NOTE: will COCOVGA need more 16 bit shifts? It's a 2K screen. + lsra rolb rolb rolb rolb - IFNE COCOVGA - rolb - ENDC + IFNE COCOVGA + rolb By 64 is CocoVGA (64x32) + ENDC clra - andb #ROWSIZE-1 lines on the screen + andb #ROWSIZE-1 lines on the screen addb #COLSIZE - std R$Y,x and save column to caller's Y - ldb <V.CFlag,u - lda <V.CChar,u get character under cursor - bmi SaveA if hi bit set, go on - cmpa #$60 VDG space? - bcc L02A5 branch if greater than - cmpa #$20 - bcc L02A9 - tstb - beq L02A3 - cmpa #$00 - bne L029B - lda #$5E - bra SaveA save it and exit + std R$Y,x and save column to caller's Y + ldb <V.CFlag,u Get true lowercase flag + lda <V.CChar,u get character under cursor + bmi SaveA if hi bit set, return that value to caller + cmpa #$60 Lowercase? + bhs L02A5 Yes, skip ahead + cmpa #$20 #, uppercase, some punctuation? + bhs L02A9 Yes, Change if VDG-T1 + tstb Real lowercase enabled? + beq L02A3 No, convert to ASCII from VDG code + tsta VDG caret? + bne L029B No, try some other special ones + lda #$5E Replace with ASCII caret ^ + bra SaveA save it and exit -L029B cmpa #$1F - bne L02A3 - lda #$5F +L029B cmpa #$1F VDG underscore? + bne L02A3 No, done special checks + lda #$5F Yes, replace with underscore bra SaveA -L02A3 ora #$20 turn it into ASCII from VDG codes -L02A5 eora #$40 + +L02A3 ora #$20 turn it into ASCII from VDG codes +L02A5 eora #$40 Switch to uppercase bra SaveA -L02A9 tstb - bne SaveA - cmpa #$21 remap specific codes - bne L02B4 - lda #$7C + +L02A9 tstb True lowercase on with VDG-T1? + bne SaveA yes, save char + cmpa #$21 No, remap specific codes - exclamation/pipe? + bne L02B4 No, try one more special one + lda #$7C Replace with actual ASCII pipe bra SaveA + L02B4 cmpa #$2D bne SaveA - lda #$7E + lda #$7E Replace with ASCII tilde SaveA sta R$A,x clrb rts
--- a/level1/modules/vtio.asm Sun Mar 11 01:40:13 2018 -0600 +++ b/level1/modules/vtio.asm Mon Mar 12 19:35:56 2018 -0500 @@ -39,6 +39,18 @@ * L. Curtis Boyle * Fixed bug with SS.Ready GetStat call - it was not saving the # of chars * available in the keyboard buffer to caller's B register +* +* 4 2018/03/02 David Ladd +* L. Curtis Boyle +* Fixed SS.ComSt call so that changing Coco 3 or Coco2B T1 VDG between real +* lowercase and inverse video takes effect as soon as the call is made (it +* setting flags, but not updating the hardware until the next switch to Graphics +* mode and back to text mode happened. +* Also some more general optimizations, and installed the V.ClrBlk and V.CpyBlk +* vectors calls (to use 6309 TFM and 6809 mini-stack blasting) for memory clears +* and memory copies. These will also be accessible from VTIO's other co-modules, +* for a speed increase. + nam VTIO ttl OS-9 Level One V2 CoCo I/O driver @@ -51,7 +63,7 @@ tylg set Drivr+Objct atrv set ReEnt+rev rev set $00 -edition set 1 +edition set 2 mod eom,name,tylg,atrv,start,size @@ -62,13 +74,6 @@ name fcs /VTIO/ fcb edition -start lbra Init - lbra Read - lbra Write - lbra GetStat - lbra SetStat - lbra Term - * Init * * Entry: @@ -93,7 +98,7 @@ L002E sta ,x+ clear mem decb decrement counter bne L002E continue if more - leax FlashCursor,pcr Point to dummy cursor flash (just an rts). + leax <FlashCursor,pcr Point to dummy cursor flash (just an rts). stx V.Flash,u Setup cursor flash coma A = $FF comb B = $FF @@ -107,30 +112,19 @@ * I presume this should also get IFEQ to specify 50 for PAL systems lda #60 Init clock ctr to 60 sta <V.ClkCnt,u - leax >AltIRQ,pcr get IRQ routine ptr + leax <AltIRQ,pcr get IRQ routine ptr stx >D.AltIRQ store in AltIRQ leax >SetDsply,pcr get display vector stx <V.DspVct,u store in vector address leax >XY2Addr,pcr get address of XY2Addr stx <V.CnvVct,u Save as vector get mem location and pixel mask based on X,Y coords on gfx screen + leax >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 <IT.PAR,y get parity and baud lbra SetupTerm process them -* Term -* -* Entry: -* U = address of device memory area -* -* Exit: -* CC = carry set on error -* B = error code -* -Term pshs cc - orcc #IRQMask mask interrupts - ldx >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.Proc get pointer to current proc desc - ldb <P$Signal,x get signal recvd - beq Read branch if no signal - cmpb #S$Window window signal? - bcc Read branch if so - coma + os9 F$Sleep sleep forever + clr V.WAKE,u clear wake + ldx <D.Proc get pointer to current proc desc + ldb <P$Signal,x get signal recvd + beq Read branch if no signal + cmpb #S$Window window signal? + bhs Read Window signal or higher (none of the main system ones), go read + coma Otherwise, return with signal code as error rts * Check if we need to wrap around tail pointer to zero -L009D incb increment pointer - cmpb #$7F at end? - bls L00A3 branch if not - clrb else clear pointer (wrap to head) +L009D incb increment pointer + cmpb #$7F at end? + bls L00A3 branch if not + clrb else clear pointer (wrap to head) L00A3 rts * @@ -573,8 +567,8 @@ lslb lslb lslb - pshs b Save shifted version - ora ,s+ Combine shifted version with original & remove from stack + pshs b + ora ,s+ ldb ,s Get original dragon formatted one back (-2 cyc) andb #%00111100 Shift middle 4 rows down 2 places lsrb @@ -617,6 +611,22 @@ fcb $32,$34,$36 F2 key +start lbra Init + lbra Read + bra Write + nop Could be used for a constant + lbra GetStat + lbra SetStat +* Term +* Entry: U = address of device memory area +* Exit: CC = carry set on error +* B = error code +Term pshs cc + orcc #IRQMask mask interrupts + 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 <COEscape,pcr else it's $1F... set up to get next char -L03BD ldb #$01 +L03BD ldb #$01 This entry point requests 1 byte of parameters L03BF stx <V.RTAdd,u stb <V.NGChr,u L03C5 clrb @@ -690,6 +700,7 @@ * Show VDG or Graphics screen. Set up as a vector (V.DspVct) * Entry: B = 0 for VDG, 1 for Graphics +* A = color setting of some sort SetDsply pshs x,a stb <V.Alpha,u save passed flag in B lda >PIA1Base+2 @@ -700,22 +711,22 @@ ora <V.CFlag,u L03DE sta >PIA1Base+2 sta <V.PIA1,u + ldx #$FFC6 Point to SAM to set up where to map tstb display graphics? bne DoGfx Yes, do that * Set up VDG screen for text -DoVDG stb >$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 <V.ScrnA,u get pointer to alpha screen - bra L0401 + bra L0401 * Set up VDG screen for graphics -DoGfx stb >$FFC0 - stb >$FFC3 - stb >$FFC5 +DoGfx stb -6,x $FFC0 + stb -3,x $FFC3 + stb -1,x $FFC5 lda <V.SBAdd,u get pointer to graphics screen (just need hi byte-VDG needs 512 byte boundaries) L0401 ldb #$07 7 SAM double-byte settings to do - ldx #$FFC6 Point to SAM to set up where to map lsra L0407 lsra bcs L0410 If bit set, store on odd byte @@ -729,16 +740,22 @@ clrb Return w/o error puls pc,x -* Comodule filename list. 6809/6309 - Try to move elsewhere to allow some 8 bit ,pcr's -GrfDrv fcs /GrfDrv/ -CoVDG fcs /CoVDG/ -CoWP fcs /CoWP/ -CoHR fcs /CoHR/ -Co42 fcs /Co42/ -CoVGA fcs /CoVGA/ +* Return key sense information +SSKYSNS ldb <V.KySns,u get key sense info + stb R$A,x put in caller's A + clrb + rts + +* Return screen size +SSSCSIZ clra clear upper 8 bits of D + ldb <V.Col,u get column count + std R$X,x save in X + ldb <V.Row,u get row count + std R$Y,x save in Y + clrb no error + rts * GetStat -* * Entry: * A = function code * Y = address of path descriptor @@ -761,9 +778,6 @@ SSEOF clrb rts -*6809/6309 note: If we move a call or two before GetStat above, may be able to eliminate a -* couple of long branch instructions below - L0439 cmpa #SS.Joy joystick? beq SSJOY branch if so cmpa #SS.ScSiz screen size? @@ -771,26 +785,13 @@ cmpa #SS.KySns keyboard sense? beq SSKYSNS branch if so cmpa #SS.DStat display status? - lbeq SSDSTAT branch if so + beq SSDSTAT branch if so ldb #$06 getstat entry into CO-module lbra JmpCO -* Return key sense information -SSKYSNS ldb <V.KySns,u get key sense info - stb R$A,x put in caller's A - clrb - rts - -* Return screen size -SSSCSIZ clra clear upper 8 bits of D - ldb <V.Col,u get column count - std R$X,x save in X - ldb <V.Row,u get row count - std R$Y,x save in Y - clrb no error - rts - -* Get joystick values +* Get joystick values. Could move ldy up to just after ORCC, and then ldx #PIA0Base+1 +* then, for the 8 references to PIA0Base, use no offset/5 bit offset (saves 8 bytes, +* and 3 cycles - hopefully that doesn't screw up joystick reads with jitter, etc. SSJOY pshs y,cc orcc #IRQMask mask interrupts lda #$FF @@ -808,29 +809,30 @@ L0486 sta R$A,x 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 <V.Mode,u get video mode @@ -889,23 +891,21 @@ lsra else divide by 8 L0517 lsra lsra - pshs a save on stack + pshs a save on stack (A=horizontal byte on line pixel will be on) ldb #191 get max Y subb 2,s subtract from Y on stack lda #32 bytes per line mul addb ,s+ add offset on stack adca #$00 -* 6809/6309 - since we are going to pull X & Y off the stack anyways, use X here (byte shorter, cycle -* faster for both ldy and sty) - ldx <V.SBAdd,u get base address - leax d,x move D bytes into address - lda ,s pick up original X coor + ldx <V.SBAdd,u get base address of gfx screen + leax d,x Point to byte pixel will be drawing on + lda ,s pick up original X coord stx ,s put offset addr on stack - anda <V.PixBt,u - ldx <V.MTabl,u - lda a,x - puls pc,y,x X = offset address, Y = base + anda <V.PixBt,u Just keep X pixel 0-7 (or 0-3) + ldx <V.MTabl,u Get ptr to pixel mask table (already set up for 4 or 8) + lda a,x Get mask for specific pixel we will be drawing + puls pc,y,x X = offset address, Y = base, A=pixel mask * SetStat * @@ -957,7 +957,6 @@ leay 2,y else move to next entry inc ,s increment B on stack ldd ,y second entry empty? -* 6809/6309 - change to bne BadMode2 bne L059E if not, no room for more... error out L058E lbsr GetMem allocate graphics buffer memory bcs L05A1 branch if error @@ -969,12 +968,8 @@ clrb call is ok rts and return -* 6809/6309 - after above change done, delete these 2 lines L059E ldb #E$BMode coma - -*6809/6309 - After above changes, move label L05A1 to just before BadMode label, -* change line to puls a L05A1 puls pc,a * Select a graphics buffer @@ -1011,7 +1006,7 @@ lda #ModCoVDG CoVDG is loaded bit ldx #$2010 32x16 pshs u,y,x,a - leax >CoVDG,pcr + leax <CoVDG,pcr bsr LoadCoModule puls u,y,x,a bcs L0600 @@ -1021,6 +1016,14 @@ bne NoError lbra SetDsply +* All co-modules except grfdrv + +CoVDG fcs /CoVDG/ +CoWP fcs /CoWP/ +CoHR fcs /CoHR/ +Co42 fcs /Co42/ +CoVGA fcs /CoVGA/ + GoCoWP bita #ModCoWP CoWP needed ? beq GOCo42 No, try next co-module stb <V.CFlag,u allow lowercase @@ -1028,7 +1031,7 @@ lda #ModCoWP 'CoWP is loaded' bit ldx #$5019 80x25 WordPark RS supports 25 lines pshs u,y,x,a - leax >CoWP,pcr + leax <CoWP,pcr * 6809/6309 - Try embedding LoadCoModule since short and only called from here. * Entry: X=ptr to co-module name SetupCoModule @@ -1047,7 +1050,7 @@ lda #ModCo42 'Co42 is loaded' bit ldx #$2A18 42x24 pshs u,y,x,a - leax >Co42,pcr + leax <Co42,pcr bra SetupCoModule GOCoHR ldb #$10 @@ -1056,7 +1059,7 @@ lda #ModCoHR 'CoHR is loaded' bit ldx #$3318 51x24 pshs u,y,x,a - leax >CoHR,pcr + leax <CoHR,pcr bra SetupCoModule LoadCoModule @@ -1109,9 +1112,6 @@ os9 F$Load puls pc,u -* 128x192 color mask table for 4 color modes -Mode1Clr fcb $00,$55,$aa,$ff - GfxDispatch cmpa #$15 GrfDrv-handled code? bhs GoGrfo Yep, pass code over to it @@ -1120,17 +1120,10 @@ suba #$10 bsr GfxActv check if first gfx screen was alloc'ed bcs L0663 if not, return with error - leax <gfxtbl,pcr else point to jump table - lsla multiply by two - ldd a,x get address of routine - jmp d,x jump to it + leax gfxtbl,pcr else point to jump table + ldb a,x get address of routine + jmp b,x jump to it -* Jump table for graphics codes $10-$14 -gfxtbl fdb Do10-gfxtbl $10 - Preset Screen - fdb Do11-gfxtbl $11 - Set Color - fdb Do12-gfxtbl $12 - End Graphics - fdb Do13-gfxtbl $13 - Erase Graphics - fdb Do14-gfxtbl $14 - Home Graphics Cursor GfxActv ldb <V.Rdy,u gfx screen allocated? bne L0606 Yes, exit with no error @@ -1143,14 +1136,16 @@ ldx <V.GrfDrvE,u get GrfDrv entry point bne L0681 branch if not zero pshs y,a else preserve regs - leax >GrfDrv,pcr get pointer to name string + leax <GrfDrv,pcr get pointer to name string bsr LinkSub link to GrfDrv bcc L067B branch if ok - leax >GrfDrv,pcr get pointer to name string + leax <GrfDrv,pcr get pointer to name string bsr LoadSub bcc L067B puls pc,y,a else exit with error +GrfDrv fcs /GrfDrv/ + L067B sty <V.GrfDrvE,u save module entry pointer L067F puls y,a restore regs L0681 clra A = GrfDrv address offset in statics @@ -1191,34 +1186,29 @@ DispGfx ldb <V.Rdy,u already allocated initial buffer? bne L06D1 Yes, skip allocating bsr GetMem else get graphics memory -* 6809/6309 - after below E$BMode is change to LBRA, change this to bcs L06B3 bcs L06B3 Couldn't get RAM; return with error std <V.SBAdd,u save ptr to graphics RAM std <V.GBuff,u And again inc <V.Rdy,u ok, we're ready - lbsr EraseGfx clear gfx mem -L06D1 lda <V.NChr2,u get character after next + lbsr Do13 clear gfx mem +L06D1 lda <V.NChr2,u get 2nd parm (color set/foreground/background color selection) sta <V.PMask,u save color set (0-15) anda #%00000011 mask out all but lower 2 bits - leax >Mode1Clr,pcr point to color mask table + leax <Mode1Clr,pcr point to color mask table lda a,x get byte sta <V.Msk1,u save mask byte here sta <V.Msk2,u and here - lda <V.NChar,u get next char, mode byte (0-1) + lda <V.NChar,u get 1st parm (gfx mode) mode byte (0-1) cmpa #$01 compare against max bls L06F0 branch if valid lbra BadMode else invalid mode specified, send error -* 6809/6309 tsta redundant if we change beq L0710 to blo L0710 (lower than cmpa#1 above) -L06F0 tsta test user supplied mode byte - beq L0710 branch if 256x192 +L06F0 blo L0710 branch if 256x192 * NOTE: CHECK CO-MODULES; I DON'T SEE V.MCol or V.MCol+1 being used ANYWHERES in VTIO ldd #$C003 4 color mode; Make pixel masks for start and end pixels in a byte std <V.MCol,u Save them for re-use -* 6809/6309 - change next 3 lines to: ldd #$E001 / stb <V.Mode,u - lda #$01 - sta <V.Mode,u 128x192 mode - lda #$E0 + ldd #$E001 + stb <V.Mode,u 128x192 4 color mode ldb <V.NChr2,u andb #$08 beq L0709 @@ -1235,22 +1225,26 @@ sta <V.Msk1,u sta <V.Msk2,u L0723 sta <V.Mode,u 256x192 mode -* 6809/6309 - LDD #$F007 - lda #$F0 - ldb #$07 Base 0 # pixels in a byte + ldd #$F007 ? & Base 0 # pixels in a byte leax <L0746,pcr Point to 2 color pixel masks table L072D stb <V.PixBt,u Save base 0 # pixels in a byte stx <V.MTabl,u Save ptr to pixel mask table ldb <V.NChr2,u andb #$04 lslb -* 6309 - orr b,a replaces two lines + IFNE H6309 + orr b,a + ELSE pshs b ora ,s+ + ENDC ldb #$01 * Indicate screen is current lbra SetDsply +* 128x192 color mask table for 4 color modes +Mode1Clr fcb $00,$55,$aa,$ff + * 4 color pixel masks L0742 fcb $c0,$30,$0c,$03 @@ -1267,10 +1261,15 @@ inc <V.NChar,u L075F lbra L06D1 -* $12 - end graphics +* $12 - end graphics. This needs to be modified to properly handle CoHR/Co42 co-modules; +* since they *replace* the original alpha mode, they should never be de-allocated. Only +* extra pages should be de-allocated. Do12 leax <V.GBuff,u point to first buffer -* 6309 - TFR 0,y (same speed, 2 bytes smaller) + IFNE H6309 + tfr 0,y Same speed/2 bytes smaller on 6309 + ELSE ldy #0 Y = 0 + ENDC ldb #3 free 3 gfx screens max pshs u,b L076D ldd #6144 size of graphics screen @@ -1289,50 +1288,46 @@ sta <V.Rdy,u gfx mem no longer allocated lbra SetDsply +* Jump table for graphics codes $10-$14 +gfxtbl fcb Do10-gfxtbl $10 - Preset Screen + fcb Do11-gfxtbl $11 - Set Color + fcb Do12-gfxtbl $12 - End Graphics + fcb Do13-gfxtbl $13 - Erase Graphics + fcb Do14-gfxtbl $14 - Home Graphics Cursor + Do10 leax <Preset,pcr set up return address lbra L03BD -* NOTE! Shouldn't this be lda <V.NChar,u ?? -Preset lda <V.NChr2,u get next char +Preset lda <V.NChr2,u get param byte tst <V.Mode,u which mode? bpl L07A7 branch if 128x192 4 color ldb #$FF assume we will clear with $FF anda #$01 mask out all but 1 bit (2 colors) - beq EraseGfx erase graphic screen with color $00 + beq Do13 erase graphic screen with color $00 bra L07B2 else erase screen with color $FF L07A7 anda #$03 mask out all but 2 bits (4 colors) - leax >Mode1Clr,pcr point to color table + leax <Mode1Clr,pcr point to color table ldb a,x get appropriate byte bra L07B2 and start the clearing -* Erase graphics screen. Change to mini stack blast for 6809, TFM for 6309 -* NOTE: Make a vector, so that all the various co-modules (including grfdrv) -* can share this, and make more entry parameters (color mask, start addr of -* clear, and size). V.ClrBlk or something like that will need to be added -* to cocovtio.d +* Erase graphics screen. Changed to use new V.ClrBlk vector (mini stack blast +* for 6809, TFM for 6309) * Long term - make a system call for this, so that all system modules (and * even user programs) can use it. Mini-stack blast for 6809, tfm for 6309) * This would clear a contiguous chunk of RAM (in 4 byte chunks only). -* NOTE: FOLLOWING CODE IS FOR TESTING CONCEPT AND SPEED. IF IT WORKS, WE WILL -* MAKE IT MORE GENERIC (CURRENTLY HARDCODED FOR 6K SCREENS ONLY) AND MAKE IT -* A VECTOR THAT CAN BE CALLED FROM VTIO,CO***, AND GRFDRV) -Do13 -EraseGfx clrb Color 0 to clear with -L07B2 pshs y,x,u Save regs - tfr b,a Dupe color to D - tfr d,x Move to X&Y - leay ,x - ldu <V.SBAdd,u Get base address for screen - leau >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 <V.SBAdd,u Add size to ptr to start of screen + tfr d,u U=ptr to end of screen+1 + ldx #6144 Size to clear into register for vector + puls b Get color code back + jsr ,y Call ClrBlk vector + puls u Get back static mem ptr * Home Graphics cursor Do14 clra clrb @@ -1341,21 +1336,27 @@ * * Ding - tickle CoCo's PIA to emit a sound -* -Ding pshs d - lda >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