; "VBIOS"; Rev 0; Written by Ben L Gee; Dec 9, 1979 ; Modified by Dan Fischler on August 21, 1980 ; VBIOS is a driver for the SSM VB3 video board. VBIOS contains ; only enough code to run CP/M and some CP/M programs. If a more ; intelligent driver is required then you should consider ICRT. ; ; DEFINE SOME SYSTEM EQUATES. ROM EQU 0E000H ;Beginning of ROMmable code FALSE EQU 0 TRUE EQU NOT FALSE ; DEFINE THE VB3 PARAMETERS VIDEO EQU 0C000H ;Address of video memory OFFSET EQU 01000H ;Relative offset to attribute field VTAC EQU 0D0H ;I/O address of the CRT controller KSTAT EQU 0E0H ;Keyboard Status/Board Enable Port KDATA EQU 0E1H ;Keyboard Data/Board Disable Port NCOLS EQU 80 ;Number of Columns NROWS EQU 24 ;Number of Rows SKEW EQU 0 SCANF EQU 525 ;Scans per frame SCANR EQU 11 ;Scans per data row HCOUNT EQU 113 ;Character times in 1 horiz scan line INTERL EQU TRUE ;Display is interlaced CODE EQU 5 ;80 columns NORMAL EQU 3 ;Set alphanumeric mode ; DEFINE SOME ASCII VALUES BS EQU 08H LF EQU 0AH CR EQU 0DH ; VIDEO DRIVER SUBROUTINES ; ; ENTRIES POINTS ARE: ; ; VBINIT - To initialize the hardware and software ; VBIN - To get a keystroke from the keyboard ; VBOUT - To output a character to the display ; VBSTAT - To check the keyboard status ; ; CALLING SEQUENCES: ; ; CALL VBINIT ; ; CALL VBIN ; STA KEYSTROKE ;Result in Register A ; ; LDA DATA ;Output character in Register C ; MOV C,A ; CALL VBOUT ; ; CALL VBSTAT ;Returns Register A=0 if ; ;No keystroke is available, else ; ;Returns Register A=0FFH ; ORG ROM JMP VBINIT JMP VBIN JMP VBOUT JMP VBSTAT VBINIT: OUT KSTAT ;Enable the VB3 board LXI H,0 CALL EEOS ;Clear the screen CALL CURON ;Put the cursor on the screen ; INITALIZE ALL OF THE CONTROL REGISTERS OUT VTAC+14 OUT VTAC+10 ;Reset the VTAC MVI A,HCOUNT-1 OUT VTAC+0 IF NOT INTERL MVI A,03CH ENDIF IF INTERL MVI A,0BCH ENDIF OUT VTAC+1 IF NOT INTERL MVI A,(SCANR-1)*8+CODE ENDIF IF INTERL MVI A,(SCANR-2)*8+CODE ENDIF OUT VTAC+2 MVI A,SKEW*64+NROWS-1 OUT VTAC+3 IF INTERL MVI A,(SCANF-513)/2 ENDIF IF NOT INTERL MVI A,(SCANF-256)/2 ENDIF OUT VTAC+4 MVI A,(SCANF-NROWS*SCANR)/4+8 OUT VTAC+5 ;Try to center the data on the screen MVI A,NROWS-1 OUT VTAC+6 OUT VTAC+14 ;Start the timing chain OUT KDATA ;Disable the VB3 board RET VBSTAT: IN KSTAT ;Check keyboard status CMA ANI 1 RZ ;Return a zero if no data is available MVI A,0FFH RET ;Else return a 0FFH VBIN: CALL VBSTAT ;Return the next key from the keyboard JZ VBIN ;Wait until one is available IN KDATA ;Get it RET ;And return ; VBOUT IS THE MAIN DISPLAY DRIVER FOR THE VB3 BOARD VBOUT: PUSH H ;First, save all registers PUSH D PUSH B OUT KSTAT ;And enable the VB3 board CALL CUROFF ;Then, turn off the cursor CALL PROCES ;And process the character CALL CURON ;Now, turn the cursor back on, OUT KDATA ;disable the VB3 board, POP B ;and restore the registers POP D POP H RET ; ON ENTRY, REG HL = LOGICAL CURSOR ADDRESS AND REG C = DATA. PROCES: MOV A,C ;Move the data to Register A ANI 7FH ;Strip parity and set flags RZ ;Skip nulls CPI CR ;Check for control characters JZ DOCR ;If match, then do control character CPI LF JZ DOLF CPI BS JZ DOBS ; MUST BE A DATA CHARACTER. PUSH H ;Save the logical cursor address CALL GETBA ;Get the physical cursor address MOV M,C ;Put the data there LXI D,OFFSET DAD D ;Compute the address of the governing attribute POP H ;Get the logical cursor address back CALL RIGHT ;Move the cursor right RNZ ;Done if the cursor didn't wrap around ; PUT THE CURSOR ON COLUMN 1 OF THE CURRENT LINE. DOCR: MVI L,0 ;Put the cursor on Col 1 of the next line RET ; PUT THE CURSOR ON THE NEXT LINE, BLANK THE LINE. DOLF: CALL DOWN ;Move the cursor down one line PUSH H ;Save the cursor address MVI L,0 ;Put the cursor on column 1 CALL EEOL ;Erase to the end of the line POP H ;Restore the cursor address RET ;Return to caller ; ERASE FROM THE CURSOR TO THE END OF THE CURRENT LINE. EEOL: MVI A,NCOLS SUB L MOV B,A MVI C,1 ; ERASE THE SCREEN BEGINNING AT THE CURSOR POSITION.THE NUMBER OF CHARACTERS ; TO ERASE IS IN REG BC. ERASE: PUSH H ERASE1: PUSH H CALL GETBA LXI D,OFFSET XCHG DAD D XCHG MVI A,NORMAL ;Use the normal attribute ERASE2: MVI M,' ' STAX D INX H INX D DCR B JNZ ERASE2 POP H MVI L,0 CALL DOWN MVI B,NCOLS DCR C JNZ ERASE1 POP H RET ; BACK THE CURSOR BY ONE POSITION. DOBS: CALL LEFT RNZ ; MOVE THE CURSOR UP. UP: MOV A,H DCR H ORA A RNZ MVI H,NROWS-1 RET ; MOVE THE CURSOR DOWN. DOWN: INR H MVI A,NROWS CMP H RNZ MVI H,0 RET ; MOVE THE CURSOR LEFT. LEFT: MOV A,L DCR L ORA A RNZ MVI L,NCOLS-1 RET ; MOVE THE CURSOR RIGHT. RIGHT: INR L MVI A,NCOLS CMP L RNZ MVI L,0 RET ; ERASE FROM THE CURSOR POSITION TO THE END OF THE SCREEN. EEOS: MVI A,NCOLS SUB L MOV B,A MVI A,NROWS SUB H MOV C,A JMP ERASE ; TURN THE CURSOR ON. ; THE LOGICAL ADDRESS OF THE CURSOR MUST BE IN REG HL. CURON: MOV A,L OUT VTAC+12 MOV A,H OUT VTAC+13 OUT VTAC+6 ;Make sure the cursor is on the bottom RET ; TURN THE CURSOR OFF. ; THE LOGICAL ADDRESS OF THE CURSOR IS RETURNED IN REG HL. CUROFF: IN VTAC+9 ;Read the column register MOV L,A ;To Register L IN VTAC+8 ;Read the row register MOV H,A ;To Register H MVI A,0FFH ;Move the cursor off the screen OUT VTAC+12 RET ; CONVERT A LOGICAL ADDRESS TO A PHYSICAL ADDRESS. ; ON ENTRY, HL CONTAINS THE LOGICAL ADDRESS. ; ON EXIT, HL CONTAINS THE PHYSICAL ADDRESS. ; A LOGICAL ADDRESS IS IN THE FORM (ROW, COLUMN) WITH ROW IN REG H AND COLUMN ; IN REG L. ROW MUST BE IN THE RANGE OF 0 TO NROWS-1 AND COLUMN MUST BE IN ; THE RANGE OF 0 TO NCOLS-1. ; A PHYSICAL ADDRESS IS THE ACTUAL MEMORY ADDRESS IN THE VIDEO MEMORY. GETBA: PUSH D PUSH B XCHG INR D LXI H,-NCOLS LXI B,NCOLS GETBA2: DAD B DCR D JNZ GETBA2 DAD D LXI D,VIDEO DAD D POP B POP D RET END