title Block Move Routines for the 6545 CRT Controller. (C) 1983 By NLS .comment % ######################################################## ## ## ## KAYPRO 10 System ## ## ## ## By M. Sherman ## ## ## ## block move routines for the 6545 ## ## ## ## Copyright (C) 1983 By Non-Linear Systems, Inc ## ## No warranty is made, expressed or implied. ## ## ## ######################################################## ## Date: 03/28/83 [77] ## ######################################################## Current revision: 7.7 28-Mar-83 Previous revision: 7.6 11-Mar-83 Prev. working rev.: 7.5 14-Feb-83 Changes: Attempt to add insert line. (revision 7.5) Changes: Updated scrolling (movsts), insert line (revision 7.6) Changes: Final modifications and debugging prior to shipping (version 7.7) includes the following routines: MOVSTS: move status line (if preserved=true), scroll screen MDIR: move data with attributes (emulates Z-80 LDIR) MDDR: move data with attributes (emulates Z-80 LDDR) DLTLIN: delete the current cursor line. INSLIN: insert a line at the current cursor location. % page extrn clrdis, regrst, carret, clreol, putcur extrn cursor, ccol, crow, vrbase, vatt public mdir, mddr, movsts, dltlin, inslin vcdata equ 1fh ; video ram data port vccmd equ 1ch ; register select port vcstat equ 1ch ; vc status port scrcmd equ 0c1ch ; used with regrst to alter base address rwcmd equ 121ch ; used with regrst to set up data address strcmd equ 1fh ; 'tickle', 'dummy' or strobe register. lastlin equ 0730h ; beginning address of last line (except stat) linesiz equ 80 ; line length in counting numbers bufsiz equ linesiz ; buffer size, if any hiadd equ 12h ; high byte of data address port loadd equ 13h ; low byte of data address port vcrdat equ vccmd+1 ; video controller register data port linesps equ 24 .Z80 page ; move status line and scroll ; movsts: ld a,(vatt) ; first, check to see if the status line and 20h ; is to be preserved or not. jr z,mvsts2 ; if bit 5 is zero, no. else... ; status line preservation is TRUE. Move the status line before doing ; anything else. ; mvsts: ld hl,(vrbase) ld de,lastlin+linesiz ld bc,linesiz ; amount to move add hl,de ; hl=source, de=statline ld a,h ; qualify it and 07h ld h,a ld d,h ; copy it into de, ld e,l ; de=source. add hl,bc ; de=source, hl=destination ld a,h ; qualify it and 07h ld h,a ex de,hl ; hl=source, de=destination push hl ; save status line address call mdir ; if so, move it pop de ; status line address in de ld hl,linesiz ; amount to clear call clrdis ; clear it ld hl,(vrbase) ld de,linesiz add hl,de ld a,h and 07h ld h,a ld (vrbase),hl ex de,hl ld bc,scrcmd jp regrst ; scroll screen and exit ; enter here for scroll if status line preservation IS NOT enabled. ; MVSTS2 scrolls the screen, then clears the status line. ; mvsts2: ld hl,(vrbase) ld de,linesiz add hl,de ld a,h and 07h ld h,a ld (vrbase),hl ; new base address ex de,hl ld bc,scrcmd call regrst ld hl,(vrbase) ld de,linesps*linesiz ; starting addr., status line add hl,de ld a,h and 07h ld h,a ex de,hl ld hl,linesiz jp clrdis ; clear status line, exit. ; move a block of data, source in hl, destination in de, count in bc. ; (just like a Z-80 block move, or LDIR, command, only slower.) ; mdir: ld a,b and 07h ; qualify the upper byte, or c ; qualify the count ret z ; not 65,535 please! mdir2: push bc ; save the count rdlopx: in a,(vcstat) or a jp p,rdlopx ; wait until ready to begin ld bc,hiadd*100H+loadd ; address register numbers ; change the data update address register: ld a,b ; high address byte register, UA, out (vccmd),a ; select it. ld a,h ; get high byte, new address, out (vcrdat),a ; put it in high byte, UA. ld a,c ; low address byte, UA, out (vccmd),a ; select it. ld a,l ; new low address byte, out (vcrdat),a ; set it. ld a,strcmd ; strobe register out (vccmd),a ; start a new cycle rdlop1: in a,(vcstat) ; get status or a ; set flags jp p,rdlop1 ; wait until vc is ready in a,(vcdata) ; get a data byte ex af,af' ; save it ld a,b ; change address, out (vccmd),a ld a,d out (vcrdat),a ld a,c out (vccmd),a ld a,e out (vcrdat),a ld a,strcmd out (vccmd),a ex af,af' out (vcdata),a inc de inc hl ld a,d and 7h ld d,a ld a,h and 7h ld h,a ; and now for the attributes rdlop2: in a,(vcstat) or a jp p,rdlop2 ld a,b ; change address, out (vccmd),a ld a,h or 08h ; go to attribute ram out (vcrdat),a ld a,c out (vccmd),a ld a,l out (vcrdat),a ld a,strcmd out (vccmd),a rdlop3: in a,(vcstat) or a jp p,rdlop3 in a,(vcdata) ex af,af' ld a,b ; change address, out (vccmd),a ld a,d or 08h ; attribute ram out (vcrdat),a ld a,c out (vccmd),a ld a,e out (vcrdat),a ld a,strcmd out (vccmd),a ex af,af' out (vcdata),a pop bc dec bc ld a,b or c jp nz,mdir2 jp mdexlp ; make sure last byte got moved ; move a block of data, source in hl, destination in de, count in bc. ; (just like a Z-80 block move, or LDDR, command, only slower.) ; mddr: ld a,b and 07h ; qualify the upper byte, or c ; qualify the count ret z ; not 65,535 please! mddr2: push bc ; save the count ddlopx: in a,(vcstat) or a jp p,ddlopx ; wait until ready to begin ld bc,hiadd*100H+loadd ; address register numbers ; change the data update address register: ld a,b ; high address byte register, UA, out (vccmd),a ; select it. ld a,h ; get high byte, new address, and 07h ; qualify it out (vcrdat),a ; put it in high byte, UA. ld a,c ; low address byte, UA, out (vccmd),a ; select it. ld a,l ; new low address byte, out (vcrdat),a ; set it. ld a,strcmd ; strobe register out (vccmd),a ; start a new cycle ddlop1: in a,(vcstat) ; get status or a ; set flags jp p,ddlop1 ; wait until vc is ready in a,(vcdata) ; get a data byte ex af,af' ; save it ld a,b ; change address, out (vccmd),a ld a,d and 07h out (vcrdat),a ld a,c out (vccmd),a ld a,e out (vcrdat),a ld a,strcmd out (vccmd),a ex af,af' out (vcdata),a inc de inc hl ld a,d and 7h ld d,a ld a,h and 7h ld h,a ; and now for the attributes ddlop2: in a,(vcstat) or a jp p,ddlop2 ld a,b ; change address, out (vccmd),a ld a,h or 08h ; go to attribute ram out (vcrdat),a ld a,c out (vccmd),a ld a,l out (vcrdat),a ld a,strcmd out (vccmd),a ddlop3: in a,(vcstat) or a jp p,ddlop3 in a,(vcdata) ex af,af' ld a,b ; change address, out (vccmd),a ld a,d or 08h ; attribute ram out (vcrdat),a ld a,c out (vccmd),a ld a,e out (vcrdat),a ld a,strcmd out (vccmd),a ex af,af' out (vcdata),a pop bc dec hl dec hl dec de dec de dec bc ld a,b or c jp nz,mddr2 mdexlp: in a,(vcstat) or a jp p,mdexlp ret dltlin: call carret ; do a carriage return ld a,(crow) or a jp z,dscroll ; special scroll ld de,(cursor) ld hl,linesiz cp 23 jp nc,clrdis ; clear last line or status line, exit cp 11 jr nc,dltl1a ; normal delete line, lines 11-22 ex de,hl ; de=linesiz, hl=cursor ld bc,linesiz-1 add hl,bc ; hl=end of current line=dest ld a,h and 07h ; qualify it ld h,a ; hl=dest. ld b,h ld c,l ; bc=dest. sbc hl,de ; hl=source ld a,h and 7h ; qualify it ld h,a ; source in hl push hl ; save source ld de,(vrbase) sbc hl,de ; hl=source-vrbase jr nc,dltl2b ; true count if no carry ld hl,0800h or a ; clear carry sbc hl,de pop de ; source in de add hl,de ; count in hl ld a,h and 07h ld h,b ld b,a ld a,l ld l,c ld c,a ex de,hl ; hl=source, de=dest., bc=count dscrla: inc bc ; count=count-1 call mddr dscroll:call mvsts ; scroll, saving status line ld hl,(cursor) ld de,linesiz add hl,de ex de,hl ; new cursor position in de jp putcur ; place cursor and exit dltl2b: ld d,b ld e,c ; de=dest. ld b,h ld c,l ; bc=count pop hl ; hl=source jr dscrla ; go do it dltl1a: add hl,de ; source = linesiz+destination ld a,h and 7h ; qualify it, ld d,a ld e,l ; put source in de. ld hl,(vrbase) ld bc,lastlin+linesiz add hl,bc ; lastpos=vrbase+(lastlin+linesiz) ld a,h and 07h ; qualify it, ld h,a ; put it back in hl, ld b,a ld c,l ; save lastpos in bc. sbc hl,de ; hl=lastpos-source jr nc,dltl3a ; valid if no carry, ld hl,0800h ; else put boundry in hl, or a ; clear carry sbc hl,de ; hl=boundry-source add hl,bc ; +lastpos dltl3a: ld b,h ; put count in bc ld c,l ld hl,(cursor) ; dest ex de,hl ; in de, source in hl call mdir ; move it. ld hl,(vrbase) ld de,lastlin add hl,de ld a,h and 07h ld d,a ld e,l ; last line in de ld hl,linesiz jp clrdis ; clear the last line ; insert a line inslin: ld a,(crow) cp 12 jp nc,insln2 ; 'normal' insert line ld hl,(vrbase) ; source ld de,linesiz or a ; clear carry sbc hl,de ; hl = new vrbase ld a,h and 07h ; qualify it ld h,a ex de,hl ; dest in de, ld bc,scrcmd ; scroll call regrst ld hl,(cursor) ld bc,(vrbase) or a sbc hl,bc jr nc,insl2a ; hl=amount ld hl,0800h or a ; clear carry flag sbc hl,bc ; hl=800h-source ld a,h and 07h ld h,a ld bc,(cursor) add hl,bc insl2a: ld a,h and 07h ld b,a ld c,l ; amount in bc ; test ld hl,80+48 add hl,bc ld a,h and 07h ld b,a ld c,l ; ld hl,(vrbase) ; source in hl ; test ld de,23*linesiz add hl,de ld a,h and 07h ld h,a ex de,hl ld hl,80 add hl,de ; source in hl, dest in de ld a,h and 07h ld h,a ; call mdir ld hl,(cursor) ld bc,linesiz or a ; clear carry sbc hl,bc ld a,h and 07h ld h,a ; qualify address ex de,hl ; put in de ld a,(ccol) ld c,a ld b,0 ld hl,linesiz sbc hl,bc ; hl=amount push de ; save new cursor address push hl call clrdis ; clear to end of inserted line pop bc ; amount push bc ld hl,(cursor) ld a,(ccol) ld e,a ld d,0 or a sbc hl,de ld a,h and 07h ld d,a ld e,l ; dest in de ld hl,(cursor) ; source in hl call mdir pop bc ; amount ld hl,linesiz or a sbc hl,bc call nz,clrdis ld hl,(vrbase) ld bc,linesiz or a sbc hl,bc ld a,h and 07h ld h,a ld (vrbase),hl ; new vr base, pop de jp putcur ; put cursor and exit insln2: sub 22 jr z,inl33 jp nc,clreol neg ; two's complement, number of lines to move push af ld hl,(vrbase) ld de,79+22*80 ; source ld bc,80 add hl,de ld a,h and 07h ld d,a ld e,l add hl,bc ; destination ld a,h and 07h ld h,a ex de,hl ; hl:=source, de:=dest. pop af push hl ld hl,0 inl22: add hl,bc dec a jr nz,inl22 ld b,h ld c,l ; bc=amount pop hl ; restore source to hl call mddr ; move them inl33: ld hl,(cursor) ; source in de, ld d,h ld e,l ld a,(ccol) ld c,a ; amount to clear, next line ld a,80 sub c ; amount to move and distance to go ld c,a ld b,0 add hl,bc ; dest. in hl, ld a,h and 07h ld h,a ex de,hl ; now hl=source, de=dest, bc=amount call mdir ; move the rest to beginning of next line ld a,(ccol) ld l,a ld h,0 or a call nz,clrdis ; clear to the end of the next line, jp clreol ; clear to the end of this one. defw 0000h END