diff --git a/branches/wbw/Doc/Source/RomWBW Architecture.docx b/branches/wbw/Doc/Source/RomWBW Architecture.docx index d8d4b6e3..8e3a5f9b 100644 Binary files a/branches/wbw/Doc/Source/RomWBW Architecture.docx and b/branches/wbw/Doc/Source/RomWBW Architecture.docx differ diff --git a/branches/wbw/Source/ansi.asm b/branches/wbw/Source/ansi.asm index 85bf8bb4..5a5671e6 100644 --- a/branches/wbw/Source/ansi.asm +++ b/branches/wbw/Source/ansi.asm @@ -4,12 +4,24 @@ ;================================================================================================== ; ; TODO: -; - SOME FUNCTIONS ARE NOT IMPLEMENTED!!! +; 1) INSERT/DELETE CHARACTERS CTL SEQUENCES +; 2) OTHER CTL SEQUENCES? +; +;================================================================================================== +; ANSI EMULATION MODULE CONSTANTS +;================================================================================================== +; +ANSI_DEFATTR .EQU 0 ; ALL ATTRIBUTES OFF +ANSI_DEFCOLOR .EQU 7 ; WHITE ON BLACK +; +;================================================================================================== +; ANSI EMULATION MODULE +;================================================================================================== ; ANSI_INIT: PRTS("ANSI: RESET$") ; - JR ANSI_INI ; REUSE THE INI FUNCTION BELOW + JP ANSI_INI ; REUSE THE INI FUNCTION BELOW ; ; ; @@ -26,9 +38,9 @@ ANSI_DISPATCH: DEC A JR Z,ANSI_CFG ; $34 CP 8 - JR Z,ANSI_INI ; $38 + JP Z,ANSI_INI ; $38 CP 9 - JR Z,ANSI_QRY ; $39 + JP Z,ANSI_QRY ; $39 CALL PANIC ; ;================================================================================================== @@ -37,13 +49,40 @@ ANSI_DISPATCH: ; ; READ A CHARACTER ; -ANSI_IN: ; JUST DEFER TO KEYBOARD +ANSI_IN: ; HANDLE INPUT REQUEST +; + ; RETURN QUEUED DATA IF WE HAVE ANY + LD A,(ANSI_QLEN) ; GET THE CURRENT QUEUE LENGTH + OR A ; SET FLAGS + JR Z,ANSI_IN1 ; NOTHING THERE, GO TO KEYBOARD READ + DEC A ; DECREMENT THE QUEUE LENGTH + LD (ANSI_QLEN),A ; AND SAVE IT + LD HL,(ANSI_QPTR) ; GET THE QUEUE POINTER + LD A,(HL) ; GET THE NEXT QUEUE BYTE + INC HL ; INCREMENT THE POINTER + LD (ANSI_QPTR),HL ; AND SAVE IT + LD E,A ; RETURN VALUE IN E + XOR A ; SIGNAL SUCCESS + RET ; DONE +; +ANSI_IN1: ; PERFORM ACTUAL KEYBOARD INPUT LD B,BF_VDAKRD ; SET FUNCTION TO KEYBOARD READ - JP EMU_VDADISP ; CHAIN TO VDA DISPATCHER + CALL EMU_VDADISP ; CALL VDA DISPATCHER + LD A,E ; CHARACTER READ INTO A + BIT 7,A ; TEST HIGH BIT + JR NZ,ANSI_IN2 ; HANDLE $80 OR HIGHER AS SPECIAL CHAR + XOR A ; OTHERWISE, SIGNAL SUCCESS + RET ; AND RETURN THE KEY +; +ANSI_IN2: ; HANDLE SPECIAL KEY + CALL ANSI_KDISP ; IF $80 OR HIGHER, DISPATCH + JR ANSI_IN ; AND LOOP ; ; WRITE A CHARACTER W/ EMULATION ; ANSI_OUT: + LD HL,ANSI_OUT2 ; RETURN ADDRESS + PUSH HL ; PUT IT ON STACK LD A,E ; GET THE INCOMING CHARACTER CP $20 ; $00-$1F IS C0 JP C,ANSI_C0DISP ; IF C0, DO C0 DISPATCH @@ -54,15 +93,46 @@ ANSI_OUT: ; ANSI_OUT1: ; PROCESS OTHER CHARS VIA STATE MACHINE LD HL,(ANSI_STATE) ; LOAD THE CURRENT STATE - CALL JPHL ; DO IT + JP (HL) ; DO IT +; CALL JPHL ; DO IT +; +ANSI_OUT2: ; SET RESULT AND RETURN XOR A ; SIGNAL SUCCESS RET ; ; CHECK INPUT STATUS ; -ANSI_IST: ; DEFER TO KEYBOARD STATUS +ANSI_IST: ; CHECK QUEUE FIRST + LD A,(ANSI_QLEN) ; GET CURRENT QUEUE LENGTH + OR A ; SET FLAGS + RET NZ ; RETURN IF CHAR(S) WAITING +; + ; QUEUE WAS EMPTY, CHECK HARDWARE STATUS LD B,BF_VDAKST ; SET FUNCTION TO KEYBOARD STATUS - JP EMU_VDADISP ; CHAIN TO VDA DISPATCHER + CALL EMU_VDADISP ; CHECK STATUS + OR A ; SET FLAGS + RET Z ; NO KEYS WAITING, RETURN NO JOY +; + ; KEY WAITING, GET IT AND HANDLE IT + LD B,BF_VDAKRD ; SET FUNCTION TO KEYBOARD READ + CALL EMU_VDADISP ; DO IT + LD A,E ; CHARACTER READ TO A + BIT 7,A ; TEST HIGH BIT + JR NZ,ANSI_IST1 ; HANDLE $80 OR HIGHER AS SPECIAL CHAR +; + ; REGULAR CHARACTER RECEIVED, QUEUE IT AND RETURN CHARS WAITING STATUS + LD HL,ANSI_QUEUE ; SET HL TO START OF QUEUE + LD (ANSI_QPTR),HL ; RESET QUEUE POINTER + LD A,E ; RESTORE CHARACTER RECEIVED + LD (HL),A ; SAVE IT AT THE HEAD OF THE QUEUE + XOR A ; ZERO ACCUM + INC A ; ASSUM := 1 (NUM CHARS IN QUEUE) + LD (ANSI_QLEN),A ; SAVE NEW QUEUE LEN + JR ANSI_IST ; REPEAT +; +ANSI_IST1: ; HANDLE SPECIAL KEY + CALL ANSI_KDISP ; DO SPECIAL KEY HANDLING + JR ANSI_IST ; REPEAT ; ; CHECK OUTPUT STATUS ; @@ -91,6 +161,27 @@ ANSI_INI: LD (ANSI_POS),DE ; SAVE CURSOR POSITION LD HL,ANSI_STBASE ; SET STATE TO BASE LD (ANSI_STATE),HL ; DO IT + LD A,ANSI_DEFATTR ; DEFAULT ATTRIBUTE + LD (ANSI_ATTR),A ; CLEAR ATTRIBUTES + LD A,ANSI_DEFCOLOR ; DEFAULT COLOR + LD (ANSI_COLOR),A ; RESET COLOR + XOR A ; ZERO ACCUM + LD (ANSI_WRAP),A ; CLEAR WRAP FLAG + LD (ANSI_LNM),A ; SET LINE FEED NEW LINE MODE + LD (ANSI_CKM),A ; CLEAR DEC CURSOR KEY MODE + LD (ANSI_QLEN),A ; ZERO THE QUEUE LENGTH + LD A,$FF ; SET ALL BITS OF ACCUM + LD (ANSI_AWM),A ; SET DEC AUTOWRAP MODE +; + ; RESET TAB STOPS TO DEFAULT (EVERY 8 CHARACTERS) + LD A,%10000000 ; STOP AT FIRST OF EVERY 8 CHARACTERS + LD HL,ANSI_TABS ; POINT TO TAB STOP BITMAP + LD B,32 ; INIT 32 BYTES +; +ANSI_INI1: ; LOOP TO RESET TAB STOPS + LD (HL),A ; SET A BYTE + INC HL ; POINT TO NEXT BYTE + DJNZ ANSI_INI1 ; LOOP TILL ALL BYTES DONE ; ; RESET THE CURRENT VIDEO DRIVER LD B,BF_VDARES ; SET FUNCTION TO RESET @@ -113,7 +204,7 @@ ANSI_STBASE: ; STATE == BASE ; ANSI_STESC: ; STATE == ESCAPE SEQUENCE RES 7,A ; CLEAR HIGH BIT - CP $30 ; $20 - $2F ARE PARAMETER CHARS + CP $30 ; $20 - $2F ARE INTERMEDIATE CHARS JP C,ANSI_COLLINT ; COLLECT INTERMEDIATE CHARACTERS CP $7F ; $30 - $7E RET NC ; IGNORE $7F @@ -170,6 +261,14 @@ ANSI_C0DISP: ;================================================================================================== ; ANSI_C1DISP: + CP $84 ; IND: INDEX + JP Z,ANSI_LF ; DO IT + CP $85 ; NEL: NEXT LINE + JP Z,ANSI_NEL ; DO IT + CP $88 ; HTS: HORIZONTAL TAB SET + JP Z,ANSI_HTS ; DO IT + CP $8D ; RI: REVERSE INDEX + JP Z,ANSI_RI ; DO IT CP $9B ; CSI: CONTROL SEQ INTRODUCER JP Z,ANSI_CSI ; HANDLE IT ; @@ -181,19 +280,7 @@ ANSI_C1DISP: ;================================================================================================== ; ANSI_ESCDISP: - CP $60 ; $40-$5F - JR NC,ANSI_ESCDISP1 ; NOPE, CONTINUE -; - ; $40-$5F MAP TO $80-$9F IN C1 RANGE - CALL ANSI_CLEAR ; CLEAR STATE RELATED VARIABLES - LD HL,ANSI_STBASE ; BASE STATE - LD (ANSI_STATE),HL ; SET IT - ADD A,$40 ; MAP $40-$5F -> $80-$9F - JP ANSI_C1DISP ; PROCESS AS C1 CHARACTER -; -ANSI_ESCDISP1: - ; CONTINUE ESCAPE SEQ DISPATCHING - ; *DEBUG* +#IF (ANSITRACE >= 2) PRTS("($") PUSH AF LD A,(ANSI_INT) @@ -203,24 +290,47 @@ ANSI_ESCDISP1: POP AF CALL COUT CALL PC_RPAREN - RET +#ENDIF + LD (ANSI_FINAL),A ; RECORD THE FINAL CHARACTER + LD A,(ANSI_INT) ; LOAD THE INTERMEDIATE CHARACTER + OR A ; SET FLAGS + JR Z,ANSI_ESCDISP1 ; NO INT CHARACTER, DO NORMAL DISPATCH + CP '#' ; INTERMEDIATE CHAR == '#'? + JR Z,ANSI_ESCDISP2 ; YES, DO # DISPATCHING + JP ANSI_UNK ; UNKNOWN, ABORT +; +ANSI_ESCDISP1: ; NORMAL ESCAPE DISPATCHING, NO INT CHARACTER + LD A,(ANSI_FINAL) ; GET FINAL CHARACTER + CP $40 ; $30-$3F + JR C,ANSI_ESCDISP1A ; YES, CONTINUE NORMALLY + CP $60 ; $40-$5F + JR NC,ANSI_ESCDISP1A ; NOPE, $60 AND ABOVE CONTINUE NORMALLY +; + ; $40-$5F MAPS TO $80-$9F IN C1 RANGE + CALL ANSI_CLEAR ; CLEAR STATE RELATED VARIABLES + LD HL,ANSI_STBASE ; BASE STATE + LD (ANSI_STATE),HL ; SET IT + ADD A,$40 ; MAP $40-$5F -> $80-$9F + JP ANSI_C1DISP ; PROCESS AS C1 CHARACTER +; +ANSI_ESCDISP1A: ; CONTINUE NORMAL ESCAPE SEQ DISPATCHING + CP 'c' ; RIS: RESET TO INITIAL STATE + JP Z,ANSI_INI ; DO A FULL RESET + JP ANSI_UNK ; UNKNOWN, ABORT +; +ANSI_ESCDISP2: ; ESC DISPATCHING FOR '#' INT CHAR + LD A,(ANSI_FINAL) ; GET FINAL CHARACTER + CP '8' ; DECALN: DEC SCREEN ALIGNMENT TEST + JP Z,ANSI_DECALN ; HANDLE IT + JP ANSI_UNK ; UNKNOWN, ABORT ; ;================================================================================================== ; ANSI CONTROL SEQUENCE DISPATCHING ;================================================================================================== ; ANSI_CTLDISP: - CP 'H' ; CUP: CURSOR POSITION - JP Z,ANSI_CUP - CP 'J' ; ED: ERASE IN DISPLAY - JP Z,ANSI_ED - CP 'K' ; EL: ERASE IN LINE - JP Z,ANSI_EL - CP 'f' ; HVP: HORIZONTAL/VERTICAL POSITION - JP Z,ANSI_CUP - CP 'm' ; SGR: SELECT GRAPHIC RENDITION - JP Z,ANSI_SGR - ; *DEBUG* + LD (ANSI_FINAL),A ; RECORD THE FINAL CHARACTER +#IF (ANSITRACE >= 2) PUSH AF PRTS("($") LD A,(ANSI_PRI) @@ -239,6 +349,74 @@ ANSI_CTLDISP: POP AF CALL COUT CALL PC_RPAREN +#ENDIF + ; BRANCH BASED ON PRIVATE CHARACTER OF SEQUENCE + LD A,(ANSI_PRI) ; GET THE PRIVATE CHARACTER + OR A ; SET FLAGS + JR Z,ANSI_STD ; IF ZERO, NO PRIVATE CHAR, DO STANDARD + CP '?' ; '?' = DEC PRIVATE + JR Z,ANSI_DEC ; HANDLE DEC PRIVATE SEQUENCES + JR ANSI_UNK ; UNKNOWN, ABORT +; +ANSI_STD: ; DISPATCH ON INTERMEDIATE CHAR W/ NO PRIVATE CHAR (STD) + LD A,(ANSI_INT) ; GET THE INTERMEDIATE CHARCACTER + OR A ; SET FLAGS + JR Z,ANSI_STD1 ; NO INTERMEDIATE CHARACTER, HANDLE IT + ; CHECK FOR ANY OTHER STD INTERMEDIATE CHARACTERS HERE... + JR ANSI_UNK ; UNKNOWN, ABORT +; +ANSI_STD1: ; DISPATCH FOR FINAL CHAR W/ NO INTERMEDIATE CHAR AND NO PRIVATE CHAR (STD) + LD A,(ANSI_FINAL) ; GET FINAL CHARACTER + CP 'A' ; CUU: CURSOR UP + JP Z,ANSI_CUU + CP 'B' ; CUD: CURSOR DOWN + JP Z,ANSI_CUD + CP 'C' ; CUF: CURSOR FORWARD + JP Z,ANSI_CUF + CP 'D' ; CUB: CURSOR BACKWARD + JP Z,ANSI_CUB + CP 'H' ; CUP: CURSOR POSITION + JP Z,ANSI_CUP + CP 'J' ; ED: ERASE IN DISPLAY + JP Z,ANSI_ED + CP 'K' ; EL: ERASE IN LINE + JP Z,ANSI_EL + CP 'L' ; IL: INSERT LINE + JP Z,ANSI_IL + CP 'M' ; DL: DELETE LINE + JP Z,ANSI_DL + CP 'f' ; HVP: HORIZONTAL/VERTICAL POSITION + JP Z,ANSI_HVP + CP 'g' ; TBC: TAB CLEAR + JP Z,ANSI_TBC + CP 'h' ; SM: SET MODE + JP Z,ANSI_SM + CP 'l' ; RM: RESET MODE + JP Z,ANSI_RM + CP 'm' ; SGR: SELECT GRAPHIC RENDITION + JP Z,ANSI_SGR + ; CHECK FOR ANY OTHERS HERE + JR ANSI_UNK ; UNKNOWN, ABORT +; +ANSI_DEC: ; DISPATCH ON INTERMEDIATE CHAR W/ PRIVATE CHAR = '?' (DEC) + LD A,(ANSI_INT) ; GET THE INTERMEDIATE CHARCACTER + OR A ; SET FLAGS + JR Z,ANSI_DEC1 ; NO INTERMEDIATE CHARACTER, HANDLE IT + ; CHECK FOR ANY OTHER DEC INTERMEDIATE CHARACTERS HERE... + JR ANSI_UNK ; UNKNOWN, ABORT +; +ANSI_DEC1: ; DISPATCH FOR FINAL CHAR W/ NO INTERMEDIATE CHAR AND PRIVATE CHAR = '?' (DEC) + LD A,(ANSI_FINAL) ; GET FINAL CHARACTER + CP 'h' ; SM: SET DEC MODE + JP Z,ANSI_DECSM + CP 'l' ; RM: RESET DEC MODE + JP Z,ANSI_DECRM + JR ANSI_UNK ; UNKNOWN, ABORT +; +ANSI_UNK: ; DIAGNOSE UNKNOWN SEQUENCE +#IF (ANSITRACE >= 2) + PRTS("***UNK***$") +#ENDIF RET ; ;================================================================================================== @@ -345,16 +523,38 @@ ANSI_CSI: ;================================================================================================== ; ANSI_RENDER: +#IF (ANSITRACE >= 2) + LD A,E + CALL COUT +#ENDIF + PUSH DE + + ; IF WRAP PENDING, DO IT NOW + LD A,(ANSI_WRAP) ; GET THE WRAP FLAG + OR A ; SET FLAGS + CALL NZ,ANSI_NEL ; IF SET, PERFORM A LINEWRAP (CLEARS WRAP FLAG) +; + ; WRITE THE CHARACTER + POP DE ; RECOVER THE CHAR TO RENDER LD B,BF_VDAWRC ; FUNC := WRITE CHARACTER CALL EMU_VDADISP ; SPIT OUT THE RAW CHARACTER - LD A,(ANSI_COL) ; GET CUR COL - INC A ; INCREMENT +; + ; END OF LINE HANDLING (CHECK FOR RIGHT MARGIN EXCEEDED) + LD A,(ANSI_COLS) ; GET SCREEN COLUMNS + LD B,A ; PUT IT IN B + LD A,(ANSI_COL) ; GET COLUMN + INC A ; BUMP IT TO REFLECT NEW CURSOR POSITION LD (ANSI_COL),A ; SAVE IT - LD DE,(ANSI_DIM) ; GET SCREEN DIMENSIONS - CP E ; COMPARE TO COLS IN LINE - RET C ; NOT PAST END OF LINE, ALL DONE - CALL ANSI_CR ; CARRIAGE RETURN - JR ANSI_LF ; LINEFEED AND RETURN + CP B ; PAST MAX? + RET C ; IF NOT, ALL DONE, JUST RETURN +; + ; CURSOR MOVED PAST RIGHT MARGIN, FIX IT AND SET WRAP FLAG + DEC A ; BACK TO RIGHT MARGIN + LD (ANSI_COL),A ; SAVE IT + CALL ANSI_XY ; UPDATE CURSOR POSITION ON SCREEN + LD A,$FF ; LOAD $FF TO SET FLAG + LD (ANSI_WRAP),A ; SAVE FLAG + RET ; AND RETURN ; ANSI_FF: LD DE,0 ; PREPARE TO HOME CURSOR @@ -369,40 +569,295 @@ ANSI_FF: JP ANSI_XY ; HOME CURSOR AND RETURN ; ANSI_BS: - LD DE,(ANSI_POS) ; GET CURRENT ROW/COL IN DE - LD A,E ; GET CURRENT COLUMN - CP 1 ; COMPARE TO COLUMN 1 - RET C ; LESS THAN 1, NOTHING TO DO - DEC E ; POINT TO PREVIOUS COLUMN - LD (ANSI_POS),DE ; SAVE NEW COLUMN VALUE - CALL ANSI_XY ; MOVE CURSOR TO NEW TARGET COLUMN - LD E,' ' ; LOAD A SPACE CHARACTER - LD B,BF_VDAWRC ; SET FUNCTION TO WRITE CHARACTER - CALL EMU_VDADISP ; OVERWRITE WITH A SPACE CHARACTER - JP ANSI_XY ; NEED TO MOVE CURSOR BACK TO NEW TARGET COLUMN + LD A,(ANSI_COL) ; GET CURRENT COLUMN + DEC A ; BACK IT UP BY ONE + RET C ; IF CARRY, MARGIN EXCEEDED, ABORT + LD (ANSI_COL),A ; SAVE NEW COLUMN + JP ANSI_XY ; UDPATE CUSROR AND RETURN ; ANSI_CR: XOR A ; ZERO ACCUM LD (ANSI_COL),A ; COL := 0 JP ANSI_XY ; REPOSITION CURSOR AND RETURN ; -ANSI_LF: +ANSI_LF: ; LINEFEED (FORWARD INDEX) LD A,(ANSI_ROW) ; GET CURRENT ROW - INC A ; BUMP TO NEXT - LD (ANSI_ROW),A ; SAVE IT LD DE,(ANSI_DIM) ; GET SCREEN DIMENSIONS - CP D ; COMPARE TO SCREEN ROWS - JP C,ANSI_XY ; NOT PAST END, ALL DONE - DEC D ; D NOW HAS MAX ROW NUM (ROWS - 1) - SUB D ; A WILL NOW HAVE NUM LINES TO SCROLL - LD E,A ; LINES TO SCROLL -> E + DEC D ; D := MAX ROW NUM + CP D ; >= LAST ROW? + JR NC,ANSI_LF1 ; NEED TO SCROLL + INC A ; BUMP TO NEXT ROW + LD (ANSI_ROW),A ; SAVE IT + JP ANSI_XY ; UPDATE CURSOR AND RETURN +; +ANSI_LF1: ; SCROLL + LD E,1 ; SCROLL FORWARD 1 LINE LD B,BF_VDASCR ; SET FUNCTION TO SCROLL - CALL EMU_VDADISP ; DO THE SCROLLING - LD A,(ANSI_ROWS) ; GET SCREEN ROW COUNT - DEC A ; A NOW HAS LAST ROW + JP EMU_VDADISP ; DO THE SCROLLING AND RETURN +; +ANSI_RI: ; REVERSE INDEX (REVERSE LINEFEED) + LD A,(ANSI_ROW) ; GET CURRENT ROW + OR A ; SET FLAGS + JR Z,ANSI_RI1 ; IF AT TOP (ROW 0), NEED TO SCROLL + DEC A ; BUMP TO PRIOR ROW LD (ANSI_ROW),A ; SAVE IT JP ANSI_XY ; RESPOSITION CURSOR AND RETURN ; +ANSI_HT: ; HORIZONTAL TAB +; + ; CHECK FOR RIGHT MARGIN, IF AT MARGIN, IGNORE + LD A,(ANSI_COLS) ; GET SCREEN COLUMN COUNT + DEC A ; MAKE IT MAX COL NUM + LD B,A ; SAVE IN B + LD A,(ANSI_COL) ; GET CURRENT COLUMN + CP B ; COMPARE TO MAX + RET NC ; IF COL >= MAX, IGNORE +; + ; INCREMENT COL TILL A TAB STOP IS HIT OR RIGHT MARGIN +ANSI_HT1: + INC A ; NEXT COLUMN + PUSH AF ; SAVE COLUMN + PUSH BC ; SAVE MAX COLUMN + LD HL,ANSI_TABS ; POINT TO TABSTOP BITMAP + CALL BITTST ; TEST BIT FOR CURRENT COLUMN + POP BC ; RECOVER MAX COLUMN + POP AF ; RECOVER CUR COLUMN + JR NZ,ANSI_HT2 ; IF TABSTOP HIT, COMMIT NEW COLUMN + CP B ; TEST FOR RIGHT MARGIN + JR NC,ANSI_HT2 ; IF AT RIGHT MARGIN, COMMIT NEW COLUMN + JR ANSI_HT1 ; LOOP UNTIL DONE +; +ANSI_HT2: ; COMMIT THE NEW COLUMN VALUE + LD (ANSI_COL),A ; SAVE THE NEW COLUMN + JP ANSI_XY ; UPDATE CURSOR AND RETURN +; +ANSI_RI1: ; REVERSE SCROLL + LD E,-1 ; SCROLL -1 LINES (REVERSE SCROLL 1 LINE) + LD B,BF_VDASCR ; SET FUNCTION TO SCROLL + JP EMU_VDADISP ; DO THE SCROLLING AND RETURN +; +; +; +ANSI_HTS: ; HORIZONTAL TAB SET + LD HL,ANSI_TABS ; POINT TO TAB STOP BITMAP + LD A,(ANSI_COL) ; SET TAB STOP AT CURRENT COL + CALL BITSET ; SET THE APPROPRIATE BIT + RET +; +; +; +ANSI_TBC: ; TAB CLEAR + LD A,(ANSI_PARLST) ; GET FIRST PARM + OR A ; SET FLAGS + JR Z,ANSI_TBC1 ; 0 = CLEAR TAB AT CURRENT COL + CP 3 ; TEST FOR 3 + JR Z,ANSI_TBC2 ; 3 = CLEAR ALL TABS + RET ; ANYTHING ELSE IS IGNORED +; +ANSI_TBC1: ; CLEAR TAB AT CURRENT COL + LD HL,ANSI_TABS ; POINT TO TAB STOP BITMAP + LD A,(ANSI_COL) ; SET TAB STOP AT CURRENT COL + CALL BITCLR ; CLEAR THE APPROPRIATE BIT + RET ; DONE +; +ANSI_TBC2: ; CLEAR ALL TABS + LD HL,ANSI_TABS ; POINT TO TABSTOP BITMAP + LD B,32 ; CLEAR 32 BYTES + XOR A ; CLEAR WITH VALUE OF ZERO +; +ANSI_TBC3: ; CLEAR ALL TABS LOOP + LD (HL),A ; SET THE CURRENT BYTE + INC HL ; POINT TO NEXT BYTE + DJNZ ANSI_TBC3 ; LOOP UNTIL DONE + RET ; DONE +; +; +; +ANSI_SM: ; SET MODE +ANSI_DECSM: ; SET DEC MODE + LD C,$FF ; FLAG VALUE (SET VALUE) + JR ANSI_MODE ; GO TO SET/RESET MODE +; +ANSI_RM: ; RESET MODE +ANSI_DECRM: ; RESET DEC MODE + LD C,$00 ; FLAG VALUE (RESET VALUE) + JR ANSI_MODE ; GO TO SET/RESET MODE +; +ANSI_MODE: ; (RE)SET MODES, FLAG VALUE IN C + LD A,(ANSI_PARIDX) ; GET CURRENT PARM INDEX + INC A ; INCREMENT TO MAKE IT THE PARM COUNT + LD B,A ; MOVE COUNT TO B FOR LOOPING + LD HL,ANSI_PARLST ; USE HL AS PARM POINTER + +ANSI_MODE1: ; (RE)SET MODE LOOP + CALL ANSI_MODE2 + INC HL + DJNZ ANSI_MODE1 + +ANSI_MODE2: ; (RE)SET MODE LOOP + LD A,(ANSI_PRI) ; GET PRIVATE CHAR + OR A ; SET FLAGS + JR Z,ANSI_MODE3 ; IF ZERO, HANDLE SANDARD MODES + CP '?' ; IF '?', DEC PRIVATE + JR Z,ANSI_MODE4 ; HANDLE DEC PRIVATE MODES + RET ; OTHERWISE IGNORE +; +ANSI_MODE3: ; STANDARD MODES + LD A,(HL) ; GET PARM + INC HL ; INCREMENT POINTER FOR NEXT LOOP + CP 20 ; LNM: LINE FEED NEW LINE MODE? + JR Z,ANSI_MDLNM ; DO IT + RET ; OTHERWISE IGNORE +; +ANSI_MODE4: ; DEC PRIVATE MODES + LD A,(HL) ; GET PARM + CP 1 ; DECCKM: DEC CURSOR KEY MODE + JR Z,ANSI_MDDECCKM ; DO IT + CP 7 ; DECAWM: DEC AUTOWRAP MODE + JR Z,ANSI_MDDECAWM ; DO IT + RET ; OTHERWISE IGNORE +; +ANSI_MDLNM: ; (RE)SET LINE FEED NEW LINE MODE + LD A,C ; GET THE VALUE + LD (ANSI_LNM),A ; SAVE IT + RET +; +ANSI_MDDECCKM: ; (RE)SET DEC CURSOR KEY MODE FLAG + LD A,C ; GET THE VALUE + LD (ANSI_CKM),A ; SAVE IT + RET ; DONE +; +ANSI_MDDECAWM: ; (RE)SET DEC AUTOWRAP MODE + LD A,C ; GET THE VALUE + LD (ANSI_AWM),A ; SAVE IT + RET ; DONE +; +; +; +ANSI_NEL: ; NEXT LINE + CALL ANSI_CR + JP ANSI_LF +; +; +; +ANSI_CUU: ; CURSOR UP + LD A,(ANSI_PARLST) ; GET PARM + OR A ; SET FLAGS + JR NZ,ANSI_CUU1 ; WE HAVE A PARM, CONTINUE + INC A ; DEFAULT TO 1 +; +ANSI_CUU1: + LD B,A ; PARM IN B + LD A,(ANSI_ROW) ; GET CURRENT ROW + SUB B ; DECREMENT BY PARM VALUE + JR NC,ANSI_CUU2 ; NO CARRY, WE ARE GOOD + XOR A ; LESS THAN 0, FIX IT +; +ANSI_CUU2: + LD (ANSI_ROW),A ; SAVE IT + JP ANSI_XY ; MOVE CURSOR AND RETURN +; +; +; +ANSI_CUD: ; CURSOR DOWN + LD A,(ANSI_PARLST) ; GET PARM + OR A ; SET FLAGS + JR NZ,ANSI_CUD1 ; WE HAVE A PARM, CONTINUE + INC A ; DEFAULT TO 1 +ANSI_CUD1: + LD B,A ; PARM IN B + LD A,(ANSI_ROWS) ; GET ROW COUNT + DEC A ; DEC FOR MAX ROW NUM + LD C,A ; MAX ROW NUM IN C + LD A,(ANSI_ROW) ; GET CURRENT ROW + ADD A,B ; ADD PARM VALUE, A HAS NEW ROW + CP C ; COMPARE NEW ROW TO MAX ROW + JR C,ANSI_CUD2 ; IF CARRY, WE ARE WITHIN MARGIN + LD A,C ; OTHERWISE, SET TO MARGIN +; +ANSI_CUD2: + LD (ANSI_ROW),A ; SAVE IT + JP ANSI_XY ; MOVE CURSOR AND RETURN +; +; +; +ANSI_CUF: ; CURSOR FORWARD + LD A,(ANSI_PARLST) ; GET PARM + OR A ; SET FLAGS + JR NZ,ANSI_CUF1 ; WE HAVE A PARM, CONTINUE + INC A ; DEFAULT TO 1 +; +ANSI_CUF1: + LD B,A ; PARM IN B + LD A,(ANSI_COLS) ; GET COL COUNT + DEC A ; DEC FOR MAX COL NUM + LD C,A ; MAX COL NUM IN C + LD A,(ANSI_COL) ; GET CURRENT COL + ADD A,B ; ADD PARM VALUE, A HAS NEW COL + CP C ; COMPARE NEW COL TO MAX COL + JR C,ANSI_CUF2 ; IF CARRY, WE ARE WITHIN MARGINS + LD A,C ; OTHERWISE, SET TO MARGIN +; +ANSI_CUF2: + LD (ANSI_COL),A ; SAVE IT + JP ANSI_XY ; MOVE CURSOR AND RETURN +; +; +; +ANSI_CUB: ; CURSOR BACKWARD + LD A,(ANSI_PARLST) ; GET PARM + OR A ; SET FLAGS + JR NZ,ANSI_CUB1 ; WE HAVE A PARM, CONTINUE + INC A ; DEFAULT TO 1 +; +ANSI_CUB1: + LD B,A ; PARM IN B + LD A,(ANSI_COL) ; GET CURRENT COL + SUB B ; DECREMENT BY PARM VALUE + JR NC,ANSI_CUB2 ; NO CARRY, WE ARE GOOD + XOR A ; LESS THAN 0, FIX IT +; +ANSI_CUB2: + LD (ANSI_COL),A ; SAVE IT + JP ANSI_XY ; MOVE CURSOR AND RETURN +; +; +; +ANSI_CUP: ; CURSOR UPDATE +ANSI_HVP: ; HORIZONTAL/VERTICAL POSITION +; + ; HANDLE ROW NUMBER + LD A,(ANSI_PARLST + 0) ; ROW PARM + DEC A ; ADJUST FOR ZERO OFFSET + JP P,ANSI_CUP1 ; 0 OR MORE, OK, CONTINUE + XOR A ; NEGATIVE, FIX IT +ANSI_CUP1: + LD HL,ANSI_ROWS ; HL POINTS TO ROW COUNT + CP (HL) ; COMPARE TO ROW COUNT + JR C,ANSI_CUP2 ; IN BOUNDS, CONTINUE + LD A,(HL) ; FIX IT, LOAD ROW COUNT + DEC A ; SET TO LAST ROW NUM +ANSI_CUP2: + LD D,A ; COMMIT ROW NUMBER TO D +; + ; HANDLE COL NUMBER + LD A,(ANSI_PARLST + 1) ; COL PARM + DEC A ; ADJUST FOR ZERO OFFSET + JP P,ANSI_CUP3 ; 0 OR MORE, OK, CONTINUE + XOR A ; NEGATIVE, FIX IT +ANSI_CUP3: + LD HL,ANSI_COLS ; HL POINTS TO COL COUNT + CP (HL) ; COMPARE TO COL COUNT + JR C,ANSI_CUP4 ; IN BOUNDS, CONTINUE + LD A,(HL) ; FIX IT, LOAD COL COUNT + DEC A ; SET TO LAST COL NUM +ANSI_CUP4: + LD E,A ; COMMIT COL NUMBER TO E +; + ; COMMIT THE NEW CURSOR POSITION AND RETURN + LD (ANSI_POS),DE ; SAVE IT + JP ANSI_XY ; UPDATE CURSOR AND RETURN +; ; ; ANSI_ED: ; ERASE IN DISPLAY @@ -417,40 +872,37 @@ ANSI_ED: ; ERASE IN DISPLAY ; ANSI_ED1: ; ERASE CURSOR THRU EOS LD DE,(ANSI_POS) ; GET CURSOR POSITION - CALL ANSI_POS2IDX ; HL NOW HAS CURSOR INDEX + CALL ANSI_XY2IDX ; HL NOW HAS CURSOR INDEX PUSH HL ; SAVE IT LD DE,(ANSI_DIM) ; GET SCREEN DIMENSIONS LD E,0 ; COL POSITION := 0 - CALL ANSI_POS2IDX ; HL NOW HAS EOS INDEX + CALL ANSI_XY2IDX ; HL NOW HAS EOS INDEX POP DE ; RECOVER CURSOR POS INDEX OR A ; CLEAR CARRY SBC HL,DE ; SUBTRACT CURSOR INDEX FROM EOS INDEX - LD E,' ' ; FILL WITH BLANKS - LD B,BF_VDAFIL ; SET FUNCTION TO FILL - JP EMU_VDADISP ; PERFORM FILL AND RETURN + JR ANSI_ED4 ; COMPLETE THE FILL ; ANSI_ED2: ; ERASE START THRU CURSOR LD DE,0 ; CURSOR TO 0,0 FOR NOW LD B,BF_VDASCP ; SET FUNCTION TO SET CURSOR POSITION CALL EMU_VDADISP ; DO IT LD DE,(ANSI_POS) ; GET ORIGINAL CURSOR POSITION - CALL ANSI_POS2IDX ; HL NOW HAS INDEX + CALL ANSI_XY2IDX ; HL NOW HAS INDEX INC HL ; ADD 1 POSITION TO ERASE THRU CURSOR POSITION - LD E,' ' ; FILL WITH BLANKS - LD B,BF_VDAFIL ; SET FUNCTION TO FILL - CALL EMU_VDADISP ; DO IT - JP ANSI_XY ; RESTORE CURSOR AND RETURN + JR ANSI_ED4 ; COMPLETE THE FILL ; ANSI_ED3: ; ERASE FULL DISPLAY - LD DE,(ANSI_POS) ; GET CURSOR POS - PUSH DE ; SAVE IT - LD DE,0 ; PREPARE TO HOME CURSOR - LD (ANSI_POS),DE ; SAVE NEW CURSOR POSITION - CALL ANSI_XY ; EXECUTE - CALL ANSI_ED1 ; ERASE THRU EOS - POP DE ; RECOVER CURSOR POS - LD (ANSI_POS),DE ; SAVE IT - JP ANSI_XY ; UPDATE CURSOR AND RETURN + LD DE,0 ; CURSOR POS 0,0 + LD B,BF_VDASCP ; FUNCTION = SET CURSOR POS + CALL EMU_VDADISP ; DO IT + LD DE,(ANSI_DIM) ; DE := SCREEN ROWS/COLS + CALL ANSI_XY2IDX ; HL := CHARS ON SCREEN +; +ANSI_ED4: ; COMMON FILL PROCESS COMPLETION + LD E,' ' ; FILL WITH BLANK + LD B,BF_VDAFIL ; FUNCTION = FILL + CALL EMU_VDADISP ; DO IT + JP ANSI_XY ; RESTORE CURSOR POS AND RETURN ; ; ; @@ -466,18 +918,16 @@ ANSI_EL: ; ERASE IN LINE ; ANSI_EL1: ; ERASE CURSOR THRU EOL LD DE,(ANSI_POS) ; GET CURSOR POSITION - CALL ANSI_POS2IDX ; HL NOW HAS CURSOR INDEX + CALL ANSI_XY2IDX ; HL NOW HAS CURSOR INDEX PUSH HL ; SAVE IT LD DE,(ANSI_POS) ; GET CURSOR POSITION LD E,0 ; COL POSITION := 0 INC D ; ROW := ROW + 1 - CALL ANSI_POS2IDX ; HL NOW HAS EOL INDEX + CALL ANSI_XY2IDX ; HL NOW HAS EOL INDEX POP DE ; RECOVER CURSOR POS INDEX OR A ; CLEAR CARRY SBC HL,DE ; SUBTRACT CURSOR INDEX FROM EOL INDEX - LD E,' ' ; FILL WITH BLANKS - LD B,BF_VDAFIL ; SET FUNCTION TO FILL - JP EMU_VDADISP ; PERFORM FILL AND RETURN + JR ANSI_EL4 ; COMPLETE THE FILL ; ANSI_EL2: ; ERASE START THRU CURSOR LD DE,(ANSI_POS) ; GET CURSOR POS @@ -487,58 +937,121 @@ ANSI_EL2: ; ERASE START THRU CURSOR LD HL,(ANSI_POS) ; GET ORIGINAL CURSOR POSITION LD H,0 ; ONLY ERASE COLUMNS INC HL ; ADD 1 POSITION TO ERASE THRU CURSOR POSITION - LD E,' ' ; FILL WITH BLANKS - LD B,BF_VDAFIL ; SET FUNCTION TO FILL - CALL EMU_VDADISP ; DO IT - JP ANSI_XY ; RESTORE CURSOR AND RETURN + JR ANSI_EL4 ; COMPLETE THE FILL ; ANSI_EL3: ; ERASE FULL LINE - LD DE,(ANSI_POS) ; GET CURSOR POS - PUSH DE ; SAVE IT - LD E,0 ; CURSOR TO START OF LINE - LD (ANSI_POS),DE ; SAVE NEW CURSOR POSITION - CALL ANSI_XY ; EXECUTE - CALL ANSI_EL1 ; ERASE THRU EOL - POP DE ; RECOVER CURSOR POS - LD (ANSI_POS),DE ; SAVE IT - JP ANSI_XY ; UPDATE CURSOR AND RETURN + LD DE,(ANSI_POS) ; GET CURSOR POSITION + LD E,0 ; COL := 0 (START OF ROW) + LD B,BF_VDASCP ; FUNC = SET CURSOR POS + CALL EMU_VDADISP ; DO IT + LD HL,(ANSI_DIM) ; GET SCREEN DIM IN HL + LD H,0 ; H := 0, HL IS NOW CHARS IN A LINE + JR ANSI_EL4 ; COMPLETE THE FILL ; +ANSI_EL4 .EQU ANSI_ED4 ; REUSE CODE ABOVE ; ; -ANSI_HVP: ; HORIZONTAL/VERTICAL POSITION -ANSI_CUP: ; CURSOR UPDATE ; - ; HANDLE ROW NUMBER - LD A,(ANSI_PARLST + 0) ; ROW PARM - DEC A ; ADJUST FOR ZERO OFFSET - JP P,ANSI_CUP1 ; 0 OR MORE, OK, CONTINUE - XOR A ; NEGATIVE, FIX IT -ANSI_CUP1: - LD HL,ANSI_ROWS ; HL POINTS TO ROW COUNT - CP (HL) ; COMPARE TO ROW COUNT - JR C,ANSI_CUP2 ; IN BOUNDS, CONTINUE - LD A,(HL) ; FIX IT, LOAD ROW COUNT - DEC A ; SET TO LAST ROW NUM -ANSI_CUP2: - LD D,A ; COMMIT ROW NUMBER TO D +ANSI_IL: + LD A,(ANSI_PARLST) ; GET PARM + OR A ; SET FLAGS + JR NZ,ANSI_IL1 ; GOT IT CONTINUE + INC A ; NO PARM, DEFAULT TO 1 ; - ; HANDLE COL NUMBER - LD A,(ANSI_PARLST + 1) ; COL PARM - DEC A ; ADJUST FOR ZERO OFFSET - JP P,ANSI_CUP3 ; 0 OR MORE, OK, CONTINUE - XOR A ; NEGATIVE, FIX IT -ANSI_CUP3: - LD HL,ANSI_COLS ; HL POINTS TO COL COUNT - CP (HL) ; COMPARE TO COL COUNT - JR C,ANSI_CUP4 ; IN BOUNDS, CONTINUE - LD A,(HL) ; FIX IT, LOAD COL COUNT - DEC A ; SET TO LAST COL NUM -ANSI_CUP4: - LD E,A ; COMMIT COL NUMBER TO E +ANSI_IL1: + LD B,A ; SET LOOP COUNTER + LD DE,(ANSI_DIM) ; GET SCREEN DIMENSIONS + DEC D ; POINT TO LAST ROW + LD E,0 ; FIRST CHAR OF ROW +; +ANSI_IL2: + PUSH BC ; PRESERVE LOOP COUNTER + PUSH DE ; PRESERVE STARTING POSTION + CALL ANSI_IL3 ; DO AN ITERATION + POP DE ; RECOVER STARTING POSITION + POP BC ; RECOVER LOOP COUNTER + DJNZ ANSI_IL2 ; LOOP AS NEEDED +; + ; RESTORE CURSOR POSTION AND RETURN + JP ANSI_XY +; +ANSI_IL3: + ; SET CURSOR POSITION TO DEST + PUSH DE ; PRESERVE DE + LD B,BF_VDASCP ; FUNC = SET CURSOR POS + CALL EMU_VDADISP ; DO IT + POP DE ; RECOVER DE + ; SET HL TO LENGTH + LD HL,(ANSI_DIM) ; GET DIMENSIONS + LD H,0 ; ZERO MSB, SO COPY LEN IS COL COUNT + ; CHECK ROW, GET OUT IF WORKING ROW IS CURRENT ROW + LD A,(ANSI_ROW) ; GET CURRENT ROW + CP D ; COMPARE TO WORKING ROW NUM + JR Z,ANSI_IL4 ; IF EQUAL WE ARE DONE + ; SET DE TO SOURCE POS + DEC D ; DE NOW POINTS TO PRIOR ROW + ; DO THE COPY + PUSH DE ; PRESERVE DE + LD B,BF_VDACPY ; FUNCTION = COPY + CALL EMU_VDADISP ; COPY THE LINE + POP DE ; RECOVER DE + JR ANSI_IL3 ; LOOP +; +ANSI_IL4: ;CLEAR INSERTED LINE + LD E,' ' ; FILL WITH BLANK + LD B,BF_VDAFIL ; FUNCTION = FILL + JP EMU_VDADISP ; DO IT +; +; +; +ANSI_DL: + LD A,(ANSI_PARLST) ; GET PARM + OR A ; SET FLAGS + JR NZ,ANSI_DL1 ; GOT IT CONTINUE + INC A ; NO PARM, DEFAULT TO 1 +; +ANSI_DL1: + LD B,A ; SET LOOP COUNTER + LD DE,(ANSI_POS) ; GET CURSOR POS + LD E,0 ; COL := 0, START OF ROW ; - ; COMMIT THE NEW CURSOR POSITION AND RETURN - LD (ANSI_POS),DE ; SAVE IT - JP ANSI_XY ; UPDATE CURSOR AND RETURN +ANSI_DL2: + PUSH BC ; PRESERVE LOOP COUNTER + PUSH DE ; PRESERVE STARTING POSTION + CALL ANSI_DL3 ; DO AN ITERATION + POP DE ; RECOVER STARTING POSITION + POP BC ; RECOVER LOOP COUNTER + DJNZ ANSI_DL2 ; LOOP AS NEEDED +; + ; RESTORE CURSOR POSTION AND RETURN + JP ANSI_XY +; +ANSI_DL3: + ; SET CURSOR TO START OF DEST ROW + PUSH DE ; PRESERVE DE + LD B,BF_VDASCP ; FUNC = SET CURSOR POS + CALL EMU_VDADISP ; DO IT + POP DE ; RECOVER DE + ; SET DE TO SOURCE POS + INC D ; NEXT ROW, DE NOW HAS SOURCE + ; SET HL TO LENGTH + LD HL,(ANSI_DIM) ; GET DIMENSIONS + LD H,0 ; ZERO MSB, SO COPY LEN IS COL COUNT + ; CHECK ROW, GET OUT IF WORKING ROW NUM PAST END + LD A,(ANSI_ROWS) ; GET ROW COUNT + CP D ; COMPARE TO WORKING ROW NUM + JR Z,ANSI_DL4 ; IF EQUAL WE ARE DONE + ; DO THE COPY + PUSH DE ; PRESERVE DE + LD B,BF_VDACPY ; FUNCTION = COPY + CALL EMU_VDADISP ; COPY THE LINE + POP DE ; RECOVER DE + JR ANSI_DL3 ; LOOP +; +ANSI_DL4: ;CLEAR BOTTOM LINE + LD E,' ' ; FILL WITH BLANK + LD B,BF_VDAFIL ; FUNCTION = FILL + JP EMU_VDADISP ; DO IT ; ; ; @@ -576,6 +1089,8 @@ ANSI_SGR2: ; HANDLE THE REQUEST CODE JR Z,ANSI_SGR_BOLD ; DO IT CP 4 ; UNDERLINE JR Z,ANSI_SGR_UL ; DO IT + CP 5 ; BLINK + JR Z,ANSI_SGR_BLINK ; DO IT CP 7 ; REVERSE JR Z,ANSI_SGR_REV ; DO IT CP 30 ; START OF FOREGROUND @@ -589,10 +1104,10 @@ ANSI_SGR2: ; HANDLE THE REQUEST CODE RET ; OTHERWISE OUT OF RANGE ; ANSI_SGR_OFF: - XOR A ; ZERO ACCUM - LD (ANSI_ATTR),A ; CLEAR ATTRIBUTES - LD A,7 ; WHITE ON BLACK - LD (ANSI_COLOR),A ; RESET COLOR + LD A,ANSI_DEFATTR ; DEFAULT ATTRIBUTE + LD (ANSI_ATTR),A ; CLEAR ATTRIBUTES + LD A,ANSI_DEFCOLOR ; DEFAULT COLOR + LD (ANSI_COLOR),A ; RESET COLOR RET ; ANSI_SGR_BOLD: @@ -607,6 +1122,12 @@ ANSI_SGR_UL: LD (ANSI_ATTR),A ; SAVE IT RET ; +ANSI_SGR_BLINK: + LD A,(ANSI_ATTR) ; LOAD CURRENT ATTRIBUTE + OR %00000001 ; SET BLINK BIT + LD (ANSI_ATTR),A ; SAVE IT + RET +; ANSI_SGR_REV: LD A,(ANSI_ATTR) ; LOAD CURRENT ATTRIBUTE OR %00000100 ; SET REVERSE BIT @@ -634,13 +1155,137 @@ ANSI_SGR_BG: OR E LD (ANSI_COLOR),A RET - +; +; +; +ANSI_DECALN: ; DEC SCREEN ALIGNMENT TEST + LD DE,0 ; PREPARE TO HOME CURSOR + LD (ANSI_POS),DE ; SAVE NEW CURSOR POSITION + CALL ANSI_XY ; EXECUTE + LD DE,(ANSI_DIM) ; GET SCREEN DIMENSIONS + LD H,D ; SET UP TO MULTIPLY ROWS BY COLS + CALL MULT8 ; HL := H * E TO GET TOTAL SCREEN POSITIONS + LD E,'E' ; FILL SCREEN WITH BLANKS + LD B,BF_VDAFIL ; SET FUNCTION TO FILL + CALL EMU_VDADISP ; PERFORM FILL + JP ANSI_XY ; HOME CURSOR AND RETURN +; +;================================================================================================== +; ANSI PROTOCOL KEYBOARD DISPATCHING +;================================================================================================== +; +; HANDLE SPECIAL KEYBOARD CHARACTERS BY FILLING QUEUE WITH DATA +; +ANSI_KDISP: + ; RESET THE QUEUE POINTER + LD HL,ANSI_QUEUE + LD (ANSI_QPTR),HL +; + ; HANDLE FUNCTION KEYS + LD B,'P' + CP $E0 ; F1 + JR Z,ANSI_KDISP_FN + LD B,'Q' + CP $E1 ; F2 + JR Z,ANSI_KDISP_FN + LD B,'R' + CP $E2 ; F3 + JR Z,ANSI_KDISP_FN + LD B,'S' + CP $E3 ; F4 + JR Z,ANSI_KDISP_FN +; + ; HANDLE EDIT KEYS + LD B,'2' + CP $F0 ; INSERT + JR Z,ANSI_KDISP_ED + LD B,'3' + CP $F1 ; DELETE + JR Z,ANSI_KDISP_ED + LD B,'1' + CP $F2 ; HOME + JR Z,ANSI_KDISP_ED + LD B,'4' + CP $F3 ; END + JR Z,ANSI_KDISP_ED + LD B,'5' + CP $F4 ; PAGEUP + JR Z,ANSI_KDISP_ED + LD B,'6' + CP $F5 ; PAGEDOWN + JR Z,ANSI_KDISP_ED +; + ; HANDLE DIRECTION KEYS + LD B,'A' + CP $F6 ; UP + JR Z,ANSI_KDISP_DIR + LD B,'B' + CP $F7 ; DOWN + JR Z,ANSI_KDISP_DIR + LD B,'D' + CP $F8 ; LEFT + JR Z,ANSI_KDISP_DIR + LD B,'C' + CP $F9 ; RIGHT + JR Z,ANSI_KDISP_DIR +; + RET ; NO MATCH, DONE +; +ANSI_KDISP_FN: ; ADD FUNCTION KEY SEQUENCE TO QUEUE + LD A,$1B + LD (HL),A + INC HL + LD A,'O' + LD (HL),A + INC HL + LD A,B + LD (HL),A + LD A,3 + LD (ANSI_QLEN),A + RET +; +ANSI_KDISP_ED: ; ADD EDIT KEY SEQUENCE TO QUEUE + LD A,$1B + LD (HL),A + INC HL + LD A,'[' + LD (HL),A + INC HL + LD A,B + LD (HL),A + INC HL + LD A,'~' + LD (HL),A + LD A,4 + LD (ANSI_QLEN),A + RET +; +ANSI_KDISP_DIR: ; ADD DIRECTION KEY SEQUENCE TO QUEUE +; + ; SPECIAL CASE FOR CURSOR KEY MODE + LD A,(ANSI_CKM) + OR A + JR NZ,ANSI_KDISP_FN ; HANDLE LIKE FUNCTION KEY +; + LD A,$1B + LD (HL),A + INC HL + LD A,'[' + LD (HL),A + INC HL + LD A,B + LD (HL),A + LD A,3 + LD (ANSI_QLEN),A + RET ; ;================================================================================================== ; SUPPORT FUNCTIONS ;================================================================================================== ; ANSI_XY: + XOR A ; ZERO ACCUM + LD (ANSI_WRAP),A ; CLEAR THE WRAP FLAG LD DE,(ANSI_POS) ; GET THE DESIRED CURSOR POSITION LD B,BF_VDASCP ; SET FUNCTION TO SET CURSOR POSITION JP EMU_VDADISP ; REPOSITION CURSOR @@ -648,7 +1293,7 @@ ANSI_XY: ; CONVERT XY COORDINATES IN DE INTO LINEAR INDEX IN HL ; D=ROW, E=COL ; -ANSI_POS2IDX: +ANSI_XY2IDX: PUSH DE LD HL,(ANSI_DIM) ; GET DIMENSIONS LD H,L ; COLS -> H @@ -671,14 +1316,22 @@ ANSI_DIM: ANSI_COLS .DB 80 ; NUMBER OF COLUMNS ON SCREEN ANSI_ROWS .DB 24 ; NUMBER OF ROWS ON SCREEN ; -ANSI_STATE .DW PANIC ; CURRENT FUNCTION FOR STATE MACHINE +ANSI_STATE .DW PANIC ; CURRENT FUNCTION FOR STATE MACHINE +ANSI_ATTR .DB ANSI_DEFATTR ; CURRENT CHARACTER ATTRIBUTE +ANSI_COLOR .DB ANSI_DEFCOLOR ; CURRENT CHARACTER COLOR; +ANSI_WRAP .DB 0 ; WRAP PENDING FLAG +ANSI_TABS .FILL 32,0 ; TAB STOP BIT MAP (256 BITS) +ANSI_LNM .DB 0 ; LINE FEED NEW LINE MODE FLAG +ANSI_CKM .DB 0 ; DEC CURSOR KEY MODE FLAG +ANSI_AWM .DB 0 ; DEC AUTOWRAP MODE FLAG +ANSI_QLEN .DB 0 ; INPUT QUEUE LENGTH +ANSI_QPTR .DW 0 ; CURRENT QUEUE POINTER +ANSI_QUEUE .FILL 16,0 ; 16 BYTE QUEUE BUFFER ; ANSI_VARS: ANSI_PRI .DB 0 ; PRIVATE CHARACTER RECORDED HERE ANSI_INT .DB 0 ; INTERMEDIATE CHARACTER RECORDED HERE +ANSI_FINAL .DB 0 ; FINAL CHARACTER RECORDED HERE ANSI_PARIDX .DB 0 ; NUMBER OF PARAMETERS RECORDED ANSI_PARLST .FILL 16,0 ; PARAMETER VALUE LIST (UP TO 16 BYTE VALUES) ANSI_VARLEN .EQU $ - ANSI_VARS -; -ANSI_ATTR .DB 0 ; CURRENT CHARACTER ATTRIBUTE -ANSI_COLOR .DB 7 ; CURRENT CHARACTER COLOR \ No newline at end of file diff --git a/branches/wbw/Source/config_n8_2312.asm b/branches/wbw/Source/config_n8_2312.asm index f225a5a3..13104efd 100644 --- a/branches/wbw/Source/config_n8_2312.asm +++ b/branches/wbw/Source/config_n8_2312.asm @@ -84,6 +84,7 @@ KBDTRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF KBDENABLE ; TTYENABLE .EQU TRUE ; INCLUDE TTY EMULATION SUPPORT ANSIENABLE .EQU TRUE ; INCLUDE ANSI EMULATION SUPPORT +ANSITRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF ANSIENABLE = TRUE) ; BOOTTYPE .EQU BT_MENU ; BT_MENU (WAIT FOR KEYPRESS), BT_AUTO (BOOT_DEFAULT AFTER BOOT_TIMEOUT SECS) BOOT_TIMEOUT .EQU 20 ; APPROX TIMEOUT IN SECONDS FOR AUTOBOOT, 0 FOR IMMEDIATE diff --git a/branches/wbw/Source/config_n8_2511.asm b/branches/wbw/Source/config_n8_2511.asm index a4a0bc8c..44f2a34a 100644 --- a/branches/wbw/Source/config_n8_2511.asm +++ b/branches/wbw/Source/config_n8_2511.asm @@ -84,6 +84,7 @@ KBDTRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF KBDENABLE ; TTYENABLE .EQU TRUE ; INCLUDE TTY EMULATION SUPPORT ANSIENABLE .EQU TRUE ; INCLUDE ANSI EMULATION SUPPORT +ANSITRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF ANSIENABLE = TRUE) ; BOOTTYPE .EQU BT_MENU ; BT_MENU (WAIT FOR KEYPRESS), BT_AUTO (BOOT_DEFAULT AFTER BOOT_TIMEOUT SECS) BOOT_TIMEOUT .EQU 20 ; APPROX TIMEOUT IN SECONDS FOR AUTOBOOT, 0 FOR IMMEDIATE diff --git a/branches/wbw/Source/config_n8vem_cvdu.asm b/branches/wbw/Source/config_n8vem_cvdu.asm index 7b7fce80..99a99b86 100644 --- a/branches/wbw/Source/config_n8vem_cvdu.asm +++ b/branches/wbw/Source/config_n8vem_cvdu.asm @@ -46,7 +46,7 @@ IDETRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF IDEENABLE IDE8BIT .EQU FALSE ; USE IDE 8BIT TRANSFERS (PROBABLY ONLY WORKS FOR CF CARDS!) IDECAPACITY .EQU 64 ; CAPACITY OF DEVICE (IN MB) ; -PPIDEENABLE .EQU FALSE ; TRUE FOR PPIDE SUPPORT (DO NOT COMBINE WITH DSKYENABLE) +PPIDEENABLE .EQU TRUE ; TRUE FOR PPIDE SUPPORT (DO NOT COMBINE WITH DSKYENABLE) PPIDEMODE .EQU PPIDEMODE_STD ; PPIDEMODE_STD, PPIDEMODE_DIO3 PPIDETRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF PPIDEENABLE = TRUE) PPIDE8BIT .EQU FALSE ; USE IDE 8BIT TRANSFERS (PROBABLY ONLY WORKS FOR CF CARDS!) @@ -84,6 +84,7 @@ KBDTRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF KBDENABLE ; TTYENABLE .EQU TRUE ; INCLUDE TTY EMULATION SUPPORT ANSIENABLE .EQU TRUE ; INCLUDE ANSI EMULATION SUPPORT +ANSITRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF ANSIENABLE = TRUE) ; BOOTTYPE .EQU BT_MENU ; BT_MENU (WAIT FOR KEYPRESS), BT_AUTO (BOOT_DEFAULT AFTER BOOT_TIMEOUT SECS) BOOT_TIMEOUT .EQU 20 ; APPROX TIMEOUT IN SECONDS FOR AUTOBOOT, 0 FOR IMMEDIATE diff --git a/branches/wbw/Source/config_n8vem_dide.asm b/branches/wbw/Source/config_n8vem_dide.asm index 72cea522..0eb33d08 100644 --- a/branches/wbw/Source/config_n8vem_dide.asm +++ b/branches/wbw/Source/config_n8vem_dide.asm @@ -84,6 +84,7 @@ KBDTRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF KBDENABLE ; TTYENABLE .EQU FALSE ; INCLUDE TTY EMULATION SUPPORT ANSIENABLE .EQU FALSE ; INCLUDE ANSI EMULATION SUPPORT +ANSITRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF ANSIENABLE = TRUE) ; BOOTTYPE .EQU BT_MENU ; BT_MENU (WAIT FOR KEYPRESS), BT_AUTO (BOOT_DEFAULT AFTER BOOT_TIMEOUT SECS) BOOT_TIMEOUT .EQU 20 ; APPROX TIMEOUT IN SECONDS FOR AUTOBOOT, 0 FOR IMMEDIATE diff --git a/branches/wbw/Source/config_n8vem_diskio.asm b/branches/wbw/Source/config_n8vem_diskio.asm index b8062cc8..2c3fc748 100644 --- a/branches/wbw/Source/config_n8vem_diskio.asm +++ b/branches/wbw/Source/config_n8vem_diskio.asm @@ -84,6 +84,7 @@ KBDTRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF KBDENABLE ; TTYENABLE .EQU FALSE ; INCLUDE TTY EMULATION SUPPORT ANSIENABLE .EQU FALSE ; INCLUDE ANSI EMULATION SUPPORT +ANSITRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF ANSIENABLE = TRUE) ; BOOTTYPE .EQU BT_MENU ; BT_MENU (WAIT FOR KEYPRESS), BT_AUTO (BOOT_DEFAULT AFTER BOOT_TIMEOUT SECS) BOOT_TIMEOUT .EQU 20 ; APPROX TIMEOUT IN SECONDS FOR AUTOBOOT, 0 FOR IMMEDIATE diff --git a/branches/wbw/Source/config_n8vem_diskio3.asm b/branches/wbw/Source/config_n8vem_diskio3.asm index cb7a0827..ae3014bc 100644 --- a/branches/wbw/Source/config_n8vem_diskio3.asm +++ b/branches/wbw/Source/config_n8vem_diskio3.asm @@ -84,6 +84,7 @@ KBDTRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF KBDENABLE ; TTYENABLE .EQU FALSE ; INCLUDE TTY EMULATION SUPPORT ANSIENABLE .EQU FALSE ; INCLUDE ANSI EMULATION SUPPORT +ANSITRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF ANSIENABLE = TRUE) ; BOOTTYPE .EQU BT_MENU ; BT_MENU (WAIT FOR KEYPRESS), BT_AUTO (BOOT_DEFAULT AFTER BOOT_TIMEOUT SECS) BOOT_TIMEOUT .EQU 20 ; APPROX TIMEOUT IN SECONDS FOR AUTOBOOT, 0 FOR IMMEDIATE diff --git a/branches/wbw/Source/config_n8vem_ppide.asm b/branches/wbw/Source/config_n8vem_ppide.asm index d77b654c..f2ad1ccb 100644 --- a/branches/wbw/Source/config_n8vem_ppide.asm +++ b/branches/wbw/Source/config_n8vem_ppide.asm @@ -84,6 +84,7 @@ KBDTRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF KBDENABLE ; TTYENABLE .EQU FALSE ; INCLUDE TTY EMULATION SUPPORT ANSIENABLE .EQU FALSE ; INCLUDE ANSI EMULATION SUPPORT +ANSITRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF ANSIENABLE = TRUE) ; BOOTTYPE .EQU BT_MENU ; BT_MENU (WAIT FOR KEYPRESS), BT_AUTO (BOOT_DEFAULT AFTER BOOT_TIMEOUT SECS) BOOT_TIMEOUT .EQU 20 ; APPROX TIMEOUT IN SECONDS FOR AUTOBOOT, 0 FOR IMMEDIATE diff --git a/branches/wbw/Source/config_n8vem_ppisd.asm b/branches/wbw/Source/config_n8vem_ppisd.asm index 40f6fca0..180fa3b5 100644 --- a/branches/wbw/Source/config_n8vem_ppisd.asm +++ b/branches/wbw/Source/config_n8vem_ppisd.asm @@ -84,6 +84,7 @@ KBDTRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF KBDENABLE ; TTYENABLE .EQU FALSE ; INCLUDE TTY EMULATION SUPPORT ANSIENABLE .EQU FALSE ; INCLUDE ANSI EMULATION SUPPORT +ANSITRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF ANSIENABLE = TRUE) ; BOOTTYPE .EQU BT_MENU ; BT_MENU (WAIT FOR KEYPRESS), BT_AUTO (BOOT_DEFAULT AFTER BOOT_TIMEOUT SECS) BOOT_TIMEOUT .EQU 20 ; APPROX TIMEOUT IN SECONDS FOR AUTOBOOT, 0 FOR IMMEDIATE diff --git a/branches/wbw/Source/config_n8vem_propio.asm b/branches/wbw/Source/config_n8vem_propio.asm index 21abc10f..ce30d22f 100644 --- a/branches/wbw/Source/config_n8vem_propio.asm +++ b/branches/wbw/Source/config_n8vem_propio.asm @@ -84,6 +84,7 @@ KBDTRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF KBDENABLE ; TTYENABLE .EQU FALSE ; INCLUDE TTY EMULATION SUPPORT ANSIENABLE .EQU FALSE ; INCLUDE ANSI EMULATION SUPPORT +ANSITRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF ANSIENABLE = TRUE) ; BOOTTYPE .EQU BT_MENU ; BT_MENU (WAIT FOR KEYPRESS), BT_AUTO (BOOT_DEFAULT AFTER BOOT_TIMEOUT SECS) BOOT_TIMEOUT .EQU 20 ; APPROX TIMEOUT IN SECONDS FOR AUTOBOOT, 0 FOR IMMEDIATE diff --git a/branches/wbw/Source/config_n8vem_simh.asm b/branches/wbw/Source/config_n8vem_simh.asm index 95672166..57ec9929 100644 --- a/branches/wbw/Source/config_n8vem_simh.asm +++ b/branches/wbw/Source/config_n8vem_simh.asm @@ -84,6 +84,7 @@ KBDTRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF KBDENABLE ; TTYENABLE .EQU FALSE ; INCLUDE TTY EMULATION SUPPORT ANSIENABLE .EQU FALSE ; INCLUDE ANSI EMULATION SUPPORT +ANSITRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF ANSIENABLE = TRUE) ; BOOTTYPE .EQU BT_MENU ; BT_MENU (WAIT FOR KEYPRESS), BT_AUTO (BOOT_DEFAULT AFTER BOOT_TIMEOUT SECS) BOOT_TIMEOUT .EQU 20 ; APPROX TIMEOUT IN SECONDS FOR AUTOBOOT, 0 FOR IMMEDIATE diff --git a/branches/wbw/Source/config_n8vem_std.asm b/branches/wbw/Source/config_n8vem_std.asm index 1c689e0e..609a9cf3 100644 --- a/branches/wbw/Source/config_n8vem_std.asm +++ b/branches/wbw/Source/config_n8vem_std.asm @@ -84,6 +84,7 @@ KBDTRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF KBDENABLE ; TTYENABLE .EQU FALSE ; INCLUDE TTY EMULATION SUPPORT ANSIENABLE .EQU FALSE ; INCLUDE ANSI EMULATION SUPPORT +ANSITRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF ANSIENABLE = TRUE) ; BOOTTYPE .EQU BT_MENU ; BT_MENU (WAIT FOR KEYPRESS), BT_AUTO (BOOT_DEFAULT AFTER BOOT_TIMEOUT SECS) BOOT_TIMEOUT .EQU 20 ; APPROX TIMEOUT IN SECONDS FOR AUTOBOOT, 0 FOR IMMEDIATE diff --git a/branches/wbw/Source/config_n8vem_vdu.asm b/branches/wbw/Source/config_n8vem_vdu.asm index 9685d582..77a1b9d1 100644 --- a/branches/wbw/Source/config_n8vem_vdu.asm +++ b/branches/wbw/Source/config_n8vem_vdu.asm @@ -10,7 +10,7 @@ CPUFREQ .EQU 8 ; IN MHZ, USED TO COMPUTE DELAY FACTORS DEFCON .EQU CIODEV_UART ; DEFAULT CONSOLE DEVICE (LOADER AND MONITOR): CIODEV_UART, CIODEV_VDU, DIODEV_PRPCON ALTCON .EQU DEFCON ; ALT CONSOLE DEVICE (USED WHEN CONFIG JUMPER SHORTED) DEFVDA .EQU VDADEV_VDU ; DEFAULT VDA (VDADEV_NONE, VDADEV_VDU, VDADEV_CVDU, VDADEV_UPD7220, VDADEV_N8V) -DEFEMU .EQU EMUTYP_TTY ; DEFAULT EMULATION TYPE (EMUTYP_TTY, EMUTYP_ANSI, ...) +DEFEMU .EQU EMUTYP_ANSI ; DEFAULT EMULATION TYPE (EMUTYP_TTY, EMUTYP_ANSI, ...) ; RAMSIZE .EQU 512 ; SIZE OF RAM IN KB, MUST MATCH YOUR HARDWARE!!! CLRRAMDISK .EQU CLR_AUTO ; CLR_ALWAYS, CLR_NEVER, CLR_AUTO (CLEAR IF INVALID DIR AREA) @@ -46,8 +46,8 @@ IDETRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF IDEENABLE IDE8BIT .EQU FALSE ; USE IDE 8BIT TRANSFERS (PROBABLY ONLY WORKS FOR CF CARDS!) IDECAPACITY .EQU 64 ; CAPACITY OF DEVICE (IN MB) ; -PPIDEENABLE .EQU FALSE ; TRUE FOR PPIDE SUPPORT (DO NOT COMBINE WITH DSKYENABLE) -PPIDEMODE .EQU PPIDEMODE_STD ; PPIDEMODE_STD, PPIDEMODE_DIO3 +PPIDEENABLE .EQU TRUE ; TRUE FOR PPIDE SUPPORT (DO NOT COMBINE WITH DSKYENABLE) +PPIDEMODE .EQU PPIDEMODE_DIO3 ; PPIDEMODE_STD, PPIDEMODE_DIO3 PPIDETRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF PPIDEENABLE = TRUE) PPIDE8BIT .EQU FALSE ; USE IDE 8BIT TRANSFERS (PROBABLY ONLY WORKS FOR CF CARDS!) PPIDECAPACITY .EQU 64 ; CAPACITY OF DEVICE (IN MB) @@ -84,6 +84,7 @@ KBDTRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF KBDENABLE ; TTYENABLE .EQU TRUE ; INCLUDE TTY EMULATION SUPPORT ANSIENABLE .EQU TRUE ; INCLUDE ANSI EMULATION SUPPORT +ANSITRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF ANSIENABLE = TRUE) ; BOOTTYPE .EQU BT_MENU ; BT_MENU (WAIT FOR KEYPRESS), BT_AUTO (BOOT_DEFAULT AFTER BOOT_TIMEOUT SECS) BOOT_TIMEOUT .EQU 20 ; APPROX TIMEOUT IN SECONDS FOR AUTOBOOT, 0 FOR IMMEDIATE diff --git a/branches/wbw/Source/config_s100_std.asm b/branches/wbw/Source/config_s100_std.asm index a5415028..7428e1de 100644 --- a/branches/wbw/Source/config_s100_std.asm +++ b/branches/wbw/Source/config_s100_std.asm @@ -89,6 +89,7 @@ KBDTRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF KBDENABLE ; TTYENABLE .EQU TRUE ; INCLUDE TTY EMULATION SUPPORT ANSIENABLE .EQU TRUE ; INCLUDE ANSI EMULATION SUPPORT +ANSITRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF ANSIENABLE = TRUE) ; BOOTTYPE .EQU BT_MENU ; BT_MENU (WAIT FOR KEYPRESS), BT_AUTO (BOOT_DEFAULT AFTER BOOT_TIMEOUT SECS) BOOT_TIMEOUT .EQU 20 ; APPROX TIMEOUT IN SECONDS FOR AUTOBOOT, 0 FOR IMMEDIATE diff --git a/branches/wbw/Source/config_zeta_ppp.asm b/branches/wbw/Source/config_zeta_ppp.asm index ce32bb17..0660067c 100644 --- a/branches/wbw/Source/config_zeta_ppp.asm +++ b/branches/wbw/Source/config_zeta_ppp.asm @@ -84,6 +84,7 @@ KBDTRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF KBDENABLE ; TTYENABLE .EQU FALSE ; INCLUDE TTY EMULATION SUPPORT ANSIENABLE .EQU FALSE ; INCLUDE ANSI EMULATION SUPPORT +ANSITRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF ANSIENABLE = TRUE) ; BOOTTYPE .EQU BT_MENU ; BT_MENU (WAIT FOR KEYPRESS), BT_AUTO (BOOT_DEFAULT AFTER BOOT_TIMEOUT SECS) BOOT_TIMEOUT .EQU 20 ; APPROX TIMEOUT IN SECONDS FOR AUTOBOOT, 0 FOR IMMEDIATE diff --git a/branches/wbw/Source/config_zeta_std.asm b/branches/wbw/Source/config_zeta_std.asm index 9391f4a1..6c051e5f 100644 --- a/branches/wbw/Source/config_zeta_std.asm +++ b/branches/wbw/Source/config_zeta_std.asm @@ -84,6 +84,7 @@ KBDTRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF KBDENABLE ; TTYENABLE .EQU FALSE ; INCLUDE TTY EMULATION SUPPORT ANSIENABLE .EQU FALSE ; INCLUDE ANSI EMULATION SUPPORT +ANSITRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF ANSIENABLE = TRUE) ; BOOTTYPE .EQU BT_MENU ; BT_MENU (WAIT FOR KEYPRESS), BT_AUTO (BOOT_DEFAULT AFTER BOOT_TIMEOUT SECS) BOOT_TIMEOUT .EQU 20 ; APPROX TIMEOUT IN SECONDS FOR AUTOBOOT, 0 FOR IMMEDIATE diff --git a/branches/wbw/Source/cvdu.asm b/branches/wbw/Source/cvdu.asm index d2963992..6a24057a 100644 --- a/branches/wbw/Source/cvdu.asm +++ b/branches/wbw/Source/cvdu.asm @@ -38,7 +38,9 @@ CVDU_RESET: LD A,$0E ; ATTRIBUTE IS STANDARD WHITE ON BLACK LD (CVDU_ATTR),A ; SAVE IT - LD A,'#' ; BLANK THE SCREEN + LD DE,0 ; ROW = 0, COL = 0 + CALL CVDU_XY ; SEND CURSOR TO TOP LEFT + LD A,' ' ; BLANK THE SCREEN LD DE,$800 ; FILL ENTIRE BUFFER CALL CVDU_FILL ; DO IT LD DE,0 ; ROW = 0, COL = 0 @@ -103,21 +105,22 @@ CVDU_DISPVDA: DEC A JR Z,CVDU_VDAFIL ; $48 DEC A - JR Z,CVDU_VDASCR ; $49 + JR Z,CVDU_VDACPY ; $49 + DEC A + JR Z,CVDU_VDASCR ; $4A DEC A - JP Z,KBD_STAT ; $4A + JP Z,KBD_STAT ; $4B DEC A - JP Z,KBD_FLUSH ; $4B + JP Z,KBD_FLUSH ; $4C DEC A - JP Z,KBD_READ ; $4C + JP Z,KBD_READ ; $4D CALL PANIC CVDU_VDAINI: - JR CVDU_INIT ; INITIALIZE + JP CVDU_INIT ; INITIALIZE CVDU_VDAQRY: LD C,$00 ; MODE ZERO IS ALL WE KNOW -; LD DE,$1950 ; 25 ROWS ($19), 80 COLS ($50) LD D,CVDU_ROWS ; ROWS LD E,CVDU_COLS ; COLS LD HL,0 ; EXTRACTION OF CURRENT BITMAP DATA NOT SUPPORTED YET @@ -181,6 +184,15 @@ CVDU_VDAFIL: CALL CVDU_FILL ; DO THE FILL XOR A ; SIGNAL SUCCESS RET + +CVDU_VDACPY: + ; LENGTH IN HL, SOURCE ROW/COL IN DE, DEST IS CVDU_POS + ; BLKCPY USES: HL=SOURCE, DE=DEST, BC=COUNT + PUSH HL ; SAVE LENGTH + CALL CVDU_XY2IDX ; ROW/COL IN DE -> SOURCE ADR IN HL + POP BC ; RECOVER LENGTH IN BC + LD DE,(CVDU_POS) ; PUT DEST IN DE + JP CVDU_BLKCPY ; DO A BLOCK COPY CVDU_VDASCR: LD A,E ; LOAD E INTO A @@ -295,18 +307,27 @@ CVDU_LOADFONT1: ;---------------------------------------------------------------------- ; CVDU_XY: + CALL CVDU_XY2IDX ; CONVERT ROW/COL TO BUF IDX + LD (CVDU_POS),HL ; SAVE THE RESULT (DISPLAY POSITION) + LD C,14 ; CURSOR POSITION REGISTER PAIR + JP CVDU_WRX ; DO IT AND RETURN +; +;---------------------------------------------------------------------- +; CONVERT XY COORDINATES IN DE INTO LINEAR INDEX IN HL +; D=ROW, E=COL +;---------------------------------------------------------------------- +; +CVDU_XY2IDX: LD A,E ; SAVE COLUMN NUMBER IN A LD H,D ; SET H TO ROW NUMBER LD E,CVDU_COLS ; SET E TO ROW LENGTH CALL MULT8 ; MULTIPLY TO GET ROW OFFSET LD E,A ; GET COLUMN BACK ADD HL,DE ; ADD IT IN - LD (CVDU_POS),HL ; SAVE THE RESULT (DISPLAY POSITION) - LD C,14 ; CURSOR POSITION REGISTER PAIR - JP CVDU_WRX ; DO IT AND RETURN + RET ; RETURN ; ;---------------------------------------------------------------------- -; WRITE VALULE IN A TO CURRENT VDU BUFFER POSTION, ADVANCE CURSOR +; WRITE VALUE IN A TO CURRENT VDU BUFFER POSTION, ADVANCE CURSOR ;---------------------------------------------------------------------- ; CVDU_PUTCHAR: @@ -452,13 +473,13 @@ CVDU_SCROLL2: AND $7F ; CLEAR BIT 7 FOR FILL MODE CALL CVDU_WR ; DO IT - ; SET CHARACTER TO WRITE + ; SET VALUE TO WRITE POP AF ; RESTORE THE FILL VALUE PASSED IN LD C,31 ; DATA REGISTER CALL CVDU_WR ; DO IT ; SET BLOCK WRITE COUNT (WILL EXECUTE THE WRITE) - LD A,80 - 1 ; SET WRITE COUNT TO LINE LENGTH - 1 (1 CHAR ALREADY WRITTEN) + LD A,CVDU_COLS - 1 ; SET WRITE COUNT TO LINE LENGTH - 1 (1 CHAR ALREADY WRITTEN) LD C,30 ; WORD COUNT REGISTER CALL CVDU_WR ; DO IT @@ -470,7 +491,7 @@ CVDU_SCROLL2: ; CVDU_RSCROLL: ; SCROLL THE CHARACTER BUFFER - LD A,'=' ; CHAR VALUE TO FILL NEW EXPOSED LINE + LD A,' ' ; CHAR VALUE TO FILL NEW EXPOSED LINE LD HL,$0 + ((CVDU_ROWS - 1) * CVDU_COLS) ; SOURCE ADDRESS OF CHARACER BUFFER CALL CVDU_RSCROLL1 ; SCROLL CHARACTER BUFFER @@ -512,13 +533,17 @@ CVDU_RSCROLL2: DJNZ CVDU_RSCROLL2 ; REPEAT FOR ALL LINES + ; SET FILL DESTINATION (USING HL PASSED IN) + LD C,18 ; UPDATE ADDRESS (DESTINATION) REGISTER + CALL CVDU_WRX ; DO IT + ; SET MODE TO BLOCK WRITE TO CLEAR NEW LINE EXPOSED BY SCROLL LD C,24 ; BLOCK MODE CONTROL REGISTER CALL CVDU_RD ; GET CURRENT VALUE AND $7F ; CLEAR BIT 7 FOR FILL MODE CALL CVDU_WR ; DO IT - ; SET CHARACTER TO WRITE + ; SET VALUE TO WRITE POP AF ; RESTORE THE FILL VALUE PASSED IN LD C,31 ; DATA REGISTER CALL CVDU_WR ; DO IT @@ -530,6 +555,51 @@ CVDU_RSCROLL2: RET ; +;---------------------------------------------------------------------- +; BLOCK COPY BC BYTES FROM HL TO DE +;---------------------------------------------------------------------- +; +CVDU_BLKCPY: + ; SETUP PARMS FOR FIRST PASS (CHARS) + PUSH BC ; LENGTH + PUSH HL ; SOURCE + PUSH DE ; DEST + ; PUT A RETURN ADDRESS ON THE STACK FOR SECOND PASS + PUSH HL ; PUT CURRENT HL ON STACK + LD HL,CVDU_BLKCPY1 ; NOW SET HL TO RETURN ADDRESS + EX (SP),HL ; GET ORIG HL BACK, AND PUT RET ADR ON STACK + ; SETUP PARMS FOR SECOND PASS (ATTRIBUTES) + PUSH BC ; LENGTH + LD BC,$800 ; USE BC TO ADD OFFSET TO ATTR BUF + ADD HL,BC ; ADD THE OFFSET TO HL + PUSH HL ; SAVE PARM (SOURCE ADR) + EX DE,HL ; GET DE INTO HL + ADD HL,BC ; ADD THE OFFSET + PUSH HL ; SAVE PARM (DESTINATION ADR) +; +CVDU_BLKCPY1: + ; SET MODE TO BLOCK COPY + LD C,24 ; BLOCK MODE CONTROL REGISTER + CALL CVDU_RD ; GET CURRENT VALUE + OR $80 ; SET BIT 7 FOR COPY MODE + CALL CVDU_WR ; DO IT +; + ; SET DESTINATION + POP HL ; RECOVER DESTINATION ADDRESS + LD C,18 ; REGISTER = UPDATE ADDRESS + CALL CVDU_WRX ; DO IT +; + ; SET SOURCE + POP HL ; RECOVER SOURCE ADDRESS + LD C,32 ; REGISTER = BLOCK START + CALL CVDU_WRX ; DO IT +; + ; SET LENGTH + POP HL ; RECOVER LENGTH + LD A,L ; BYTES TO COPY GOES IN A + LD C,30 ; REGSITER = WORD COUNT + JP CVDU_WR ; DO IT (COPY OCCURS HERE) AND RETURN +; ;================================================================================================== ; CVDU DRIVER - DATA ;================================================================================================== diff --git a/branches/wbw/Source/n8v.asm b/branches/wbw/Source/n8v.asm index 12adbb59..25edd5cc 100644 --- a/branches/wbw/Source/n8v.asm +++ b/branches/wbw/Source/n8v.asm @@ -341,6 +341,8 @@ N8V_DISPVDA: DEC A JP Z,N8V_VDAFIL DEC A + JP Z,N8V_VDACPY + DEC A JP Z,N8V_VDASCR DEC A JP Z,PPK_STAT @@ -548,6 +550,13 @@ N8V_VDAFIL: XOR A RET +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Video Display Processor Copy ; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +N8V_VDACPY: + XOR A + RET + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Video Display Processor Scroll ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/branches/wbw/Source/std.asm b/branches/wbw/Source/std.asm index 7920ef6c..cd14fe07 100644 --- a/branches/wbw/Source/std.asm +++ b/branches/wbw/Source/std.asm @@ -259,10 +259,11 @@ BF_VDASAT .EQU BF_VDA + 5 ; SET CHARACTER ATTRIBUTE BF_VDASCO .EQU BF_VDA + 6 ; SET CHARACTER COLOR BF_VDAWRC .EQU BF_VDA + 7 ; WRITE CHARACTER BF_VDAFIL .EQU BF_VDA + 8 ; FILL -BF_VDASCR .EQU BF_VDA + 9 ; SCROLL -BF_VDAKST .EQU BF_VDA + 10 ; GET KEYBOARD STATUS -BF_VDAKFL .EQU BF_VDA + 11 ; FLUSH KEYBOARD BUFFER -BF_VDAKRD .EQU BF_VDA + 12 ; READ KEYBOARD +BF_VDACPY .EQU BF_VDA + 9 ; COPY +BF_VDASCR .EQU BF_VDA + 10 ; SCROLL +BF_VDAKST .EQU BF_VDA + 11 ; GET KEYBOARD STATUS +BF_VDAKFL .EQU BF_VDA + 12 ; FLUSH KEYBOARD BUFFER +BF_VDAKRD .EQU BF_VDA + 13 ; READ KEYBOARD ; BF_SYS .EQU $F0 BF_SYSGETCFG .EQU BF_SYS + 0 ; GET CONFIGURATION DATA BLOCK diff --git a/branches/wbw/Source/tty.asm b/branches/wbw/Source/tty.asm index ab81897a..a4f348e1 100644 --- a/branches/wbw/Source/tty.asm +++ b/branches/wbw/Source/tty.asm @@ -96,9 +96,6 @@ TTY_DOCHAR: JR Z,TTY_LF CP 32 ; COMPARE TO SPACE (FIRST PRINTABLE CHARACTER) RET C ; SWALLOW OTHER CONTROL CHARACTERS - -;;; LD HL,(TTY_POS) ; physical driver needs pos data to write - LD B,BF_VDAWRC CALL EMU_VDADISP ; SPIT OUT THE RAW CHARACTER LD A,(TTY_COL) ; GET CUR COL @@ -123,39 +120,31 @@ TTY_FF: JR TTY_XY ; HOME CURSOR AND RETURN ; TTY_BS: - LD DE,(TTY_POS) ; GET CURRENT ROW/COL IN DE - LD A,E ; GET CURRENT COLUMN - CP 1 ; COMPARE TO COLUMN 1 - RET C ; LESS THAN 1, NOTHING TO DO - DEC E ; POINT TO PREVIOUS COLUMN - LD (TTY_POS),DE ; SAVE NEW COLUMN VALUE - CALL TTY_XY ; MOVE CURSOR TO NEW TARGET COLUMN - LD E,' ' ; LOAD A SPACE CHARACTER - LD B,BF_VDAWRC ; SET FUNCTION TO WRITE CHARACTER - CALL EMU_VDADISP ; OVERWRITE WITH A SPACE CHARACTER - JR TTY_XY ; NEED TO MOVE CURSOR BACK TO NEW TARGET COLUMN + LD A,(TTY_COL) ; GET CURRENT COLUMN + DEC A ; BACK IT UP BY ONE + RET C ; IF CARRY, MARGIN EXCEEDED, ABORT + LD (TTY_COL),A ; SAVE NEW COLUMN + JP TTY_XY ; UDPATE CUSROR AND RETURN ; TTY_CR: XOR A ; ZERO ACCUM LD (TTY_COL),A ; COL := 0 JR TTY_XY ; REPOSITION CURSOR AND RETURN ; -TTY_LF: +TTY_LF: ; LINEFEED (FORWARD INDEX) LD A,(TTY_ROW) ; GET CURRENT ROW - INC A ; BUMP TO NEXT - LD (TTY_ROW),A ; SAVE IT LD DE,(TTY_DIM) ; GET SCREEN DIMENSIONS - CP D ; COMPARE TO SCREEN ROWS - JR C,TTY_XY ; NOT PAST END, ALL DONE - DEC D ; D NOW HAS MAX ROW NUM (ROWS - 1) - SUB D ; A WILL NOW HAVE NUM LINES TO SCROLL - LD E,A ; LINES TO SCROLL -> E - LD B,BF_VDASCR ; SET FUNCTION TO SCROLL - CALL EMU_VDADISP ; DO THE SCROLLING - LD A,(TTY_ROWS) ; GET SCREEN ROW COUNT - DEC A ; A NOW HAS LAST ROW + DEC D ; D := MAX ROW NUM + CP D ; >= LAST ROW? + JR NC,TTY_LF1 ; IF SO, NEED TO SCROLL + INC A ; BUMP TO NEXT ROW LD (TTY_ROW),A ; SAVE IT - JR TTY_XY ; RESPOSITION CURSOR AND RETURN + JP TTY_XY ; UPDATE CURSOR AND RETURN +; +TTY_LF1: ; SCROLL + LD E,1 ; SCROLL FORWARD 1 LINE + LD B,BF_VDASCR ; SET FUNCTION TO SCROLL + JP EMU_VDADISP ; DO THE SCROLLING AND RETURN ; TTY_XY: LD DE,(TTY_POS) ; GET THE DESIRED CURSOR POSITION diff --git a/branches/wbw/Source/util.asm b/branches/wbw/Source/util.asm index a14d9a46..83a487ee 100644 --- a/branches/wbw/Source/util.asm +++ b/branches/wbw/Source/util.asm @@ -459,6 +459,53 @@ MULT8_LOOP: MULT8_NOADD: DJNZ MULT8_LOOP RET + + +; +; SET A BIT IN BYTE ARRAY AT HL, INDEX IN A +; +BITSET: + CALL BITLOC ; LOCATE THE BIT + OR (HL) ; SET THE SPECIFIED BIT + LD (HL),A ; SAVE IT + RET ; RETURN +; +; CLEAR A BIT IN BYTE ARRAY AT HL, INDEX IN A +; +BITCLR: + CALL BITLOC ; LOCATE THE BIT + CPL ; INVERT ALL BITS + AND (HL) ; CLEAR SPECIFIED BIT + LD (HL),A ; SAVE IT + RET ; RETURN +; +; GET VALUE OF A BIT IN BYTE ARRAY AT HL, INDEX IN A +; +BITTST: + CALL BITLOC ; LOCATE THE BIT + AND (HL) ; SET Z FLAG BASED ON BIT + RET ; RETURN +; +; LOCATE A BIT IN BYTE ARRAY AT HL, INDEX IN A +; RETURN WITH HL POINTING TO BYTE AND A WITH MASK FOR SPECIFIC BIT +; +BITLOC: + PUSH AF ; SAVE BIT INDEX + SRL A ; DIVIDE BY 8 TO GET BYTE INDEX + SRL A ; " + SRL A ; " + LD C,A ; MOVE TO BC + LD B,0 ; " + ADD HL,BC ; HL NOW POINTS TO BYTE CONTAINING BIT + POP AF ; RECOVER A (INDEX) + AND $07 ; ISOLATE REMAINDER, Z SET IF ZERO + LD B,A ; SETUP SHIFT COUNTER + LD A,1 ; SETUP A WITH MASK + RET Z ; DONE IF ZERO +BITLOC1: + SLA A ; SHIFT + DJNZ BITLOC1 ; LOOP AS NEEDED + RET ; DONE ; ; PRINT VALUE OF HL IN DECIMAL WITH LEADING ZERO SUPPRESSION ; diff --git a/branches/wbw/Source/vdu.asm b/branches/wbw/Source/vdu.asm index abfc5eb9..ebd7aab7 100644 --- a/branches/wbw/Source/vdu.asm +++ b/branches/wbw/Source/vdu.asm @@ -100,13 +100,15 @@ VDU_DISPVDA: DEC A JR Z,VDU_VDAFIL ; $48 DEC A - JR Z,VDU_VDASCR ; $49 + JR Z,VDU_VDACPY ; $49 DEC A - JP Z,PPK_STAT ; $4A + JR Z,VDU_VDASCR ; $4A DEC A - JP Z,PPK_FLUSH ; $4B + JP Z,PPK_STAT ; $4B DEC A - JP Z,PPK_READ ; $4C + JP Z,PPK_FLUSH ; $4C + DEC A + JP Z,PPK_READ ; $4D CALL PANIC VDU_VDAINI: @@ -150,6 +152,16 @@ VDU_VDAFIL: CALL VDU_FILL ; DO THE FILL XOR A ; SIGNAL SUCCESS RET + +VDU_VDACPY: + ; LENGTH IN HL, SOURCE ROW/COL IN DE, DEST IS CVDU_POS + PUSH HL ; SAVE LENGTH + CALL VDU_XY2IDX ; ROW/COL IN DE -> SOURCE ADR IN HL + POP BC ; RECOVER LENGTH IN BC + LD DE,(VDU_POS) ; PUT DEST IN DE + JP VDU_BLKCPY ; DO A BLOCK COPY + + RET VDU_VDASCR: LD A,E ; LOAD E INTO A @@ -240,6 +252,20 @@ VDU_CRTINIT1: RET ; ;---------------------------------------------------------------------- +; CONVERT XY COORDINATES IN DE INTO LINEAR INDEX IN HL +; D=ROW, E=COL +;---------------------------------------------------------------------- +; +VDU_XY2IDX: + LD A,E ; SAVE COLUMN NUMBER IN A + LD H,D ; SET H TO ROW NUMBER + LD E,80 ; SET E TO ROW LENGTH + CALL MULT8 ; MULTIPLY TO GET ROW OFFSET + LD E,A ; GET COLUMN BACK + ADD HL,DE ; ADD IT IN + RET ; RETURN +; +;---------------------------------------------------------------------- ; SET CURSOR POSITION TO ROW IN D AND COLUMN IN E ;---------------------------------------------------------------------- ; @@ -316,6 +342,64 @@ VDU_FILL1: JR VDU_FILL1 ; LOOP ; ;---------------------------------------------------------------------- +; COPY A BLOCK (UP TO 255 BYTES) FROM HL TO FRAME BUFFER POSITION +; BC: NUMBER OF BYTES TO COPY +; HL: SOURCE POSITION +; DE: DESTINATION POSITION +;---------------------------------------------------------------------- +; +VDU_BLKCPY: + ; SETUP TO COPY FROM VDU SOURCE TO WORK BUFFER + PUSH DE ; SAVE VDU DESTINATION ADR + PUSH HL ; SAVE VDU SOURCE ADDRESS + LD HL,(VDU_OFFSET) ; GET THE CURRENT OFFSET + POP DE ; RECOVER SOURCE ADDRESS + ADD HL,DE ; HL HAS TRUE SOURCE ADR OF VIDEO BUF W/ OFFSET + LD DE,VDU_BUF ; POINT DE TO WORK BUFFER + PUSH BC ; SAVE COPY LENGTH FOR LATER + LD B,C ; NOW USE B FOR LENGTH (MAX COPY IS 255) + LD C,18 ; SET SOURCE ADDRESS IN VDU (HL) + CALL VDU_WRREGX ; DO IT + LD A,31 ; PREP VDU FOR DATA R/W + OUT (VDU_REG),A ; DO IT + LD HL,VDU_BUF ; HL POINTS TO WORK BUFFER +; LD C,VDU_RAMWR ; LOAD C WITH VDU WRITE REGISTER + +VDU_BLKCPY1: ; VIDEO RAM -> BUFFER COPY LOOP + CALL VDU_WAITRDY ; WAIT FOR VDU +;;;;;;;;;;;;;;;;; +; INI IS NOT WORKING FOR ME, GARBAGE DATA READS, NO IDEA WHY +; INI ; READ BYTE, DEC B, INC HL +; IN A,(VDU_DATA) ; BOGUS READ TO INCREMENT VDU RAM ADDRESS!!! +; JR NZ,VDU_BLKCPY1 ; LOOP TILL DONE +;;;;;;;;;;;;;;;;; + IN A,(VDU_RAMRD) ; READ DATA BYTE + LD (HL),A ; SAVE IN BUFFER + INC HL ; BUMP SOURCE ADDRESS + IN A,(VDU_DATA) ; BOGUS READ TO INCREMENT VDU RAM ADDRESS!!! + DJNZ VDU_BLKCPY1 ; LOOP TILL DONE + + ; SETUP TO COPY FROM WORK BUFFER TO VDU DEST + POP BC ; RECOVER THE COPY LENGTH + LD HL,(VDU_OFFSET) ; GET THE CURRENT VDU OFFSET + POP DE ; RECOVER THE DEST ADDRESS + ADD HL,DE ; HL HAS TRUE DEST ADR OF VIDEO BUF W/ OFFSET + LD B,C ; NOW USE B FOR LENGTH (MAX COPY IS 255) + LD C,18 ; SET DEST ADDRESS IN VDU (HL) + CALL VDU_WRREGX ; DO IT + LD A,31 ; PREP VDU FOR DATA R/W + OUT (VDU_REG),A ; DO IT + LD HL,VDU_BUF ; HL POINTS TO WORK BUFFER + LD C,VDU_RAMWR ; LOAD C WITH VDU WRITE REGISTER + +VDU_BLKCPY2: ; BUFFER -> VIDEO RAM COPY LOOP + CALL VDU_WAITRDY ; WAIT FOR VDU + OUTI ; WRITE BYTE, DEC B, INC HL + JR NZ,VDU_BLKCPY2 ; LOOP TILL DONE +; + RET ; RETURN +; +;---------------------------------------------------------------------- ; SCROLL ENTIRE SCREEN FORWARD BY ONE LINE (CURSOR POSITION UNCHANGED) ;---------------------------------------------------------------------- ; @@ -339,7 +423,7 @@ VDU_SCROLL: POP HL LD (VDU_POS),HL - ; ADJUST CURSOR POSITION + ; ADJUST CURSOR POSITION AND RETURN LD HL,(VDU_OFFSET) LD DE,(VDU_POS) ADD HL,DE @@ -351,7 +435,31 @@ VDU_SCROLL: ;---------------------------------------------------------------------- ; VDU_RSCROLL: - RET + ; SCROLL BACKWARD BY SUBTRACTING ONE ROW FROM DISPLAY START ADDRESS + LD HL,(VDU_OFFSET) + LD DE,-80 + ADD HL,DE + LD (VDU_OFFSET),HL + LD C,12 + CALL VDU_WRREGX + + ; FILL EXPOSED LINE + LD HL,(VDU_POS) + PUSH HL + LD HL,0 + LD (VDU_POS),HL + LD DE,80 + LD A,' ' + CALL VDU_FILL + POP HL + LD (VDU_POS),HL + + ; ADJUST CURSOR POSITION AND RETURN + LD HL,(VDU_OFFSET) + LD DE,(VDU_POS) + ADD HL,DE + LD C,14 + JP VDU_WRREGX ; ;================================================================================================== ; VDU DRIVER - DATA @@ -359,6 +467,7 @@ VDU_RSCROLL: ; VDU_POS .DW 0 ; CURRENT DISPLAY POSITION VDU_OFFSET .DW 0 ; CURRENT DISPLAY POSITION +VDU_BUF .FILL 256,0 ; COPY BUFFER ; ;================================================================================================== ; VDU DRIVER - SY6845 REGISTER INITIALIZATION