; VIDEO DISPLAY SOFTWARE ROM-1 VERSION 3.01 06-05-83 ; ;COPYRIGHT (c) by ;The SIMPLIWAY PRODUCTS CO. ;all rights reserved ; ;BY ROGER VILMUR ; ; DEFINED PARAMETERS ; ; DEFINED USE OF REGISTERS ; ; For transfer of data to screen ; ; A = transfer of data ; B = temperary storage C = cursor line ; D = zero E = cursor column ; HL = screen address pointer ; ; For transfer of data from keyboard ; ; A = transfer of data ; HL = buffer address pointer ; IX = buffer counter address pointer ; ; For transfer of data to CRT controler ; ; DE' = start address of transfer ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; USER MODIFIABLE AREA ; ; ; ; To reconfigure an attribute to the code ; ; desired place the ASCII code after the EQU. ; ; Control codes may only be place in the ; ; control character area. Attributes maybe ; ; disabled by placing a 00H after the EQU. ; ; ; ; SCREEN ATTRIBUTES USING CONTROL CHARACTERS ; ; ; CHOME EQU 0CH ;HOME ; CSTCUR EQU 14H ;SET CURSOR POSTION ; CCURUP EQU 1AH ;CURSOR UP ; CCURDN EQU 0BH ;CURSOR DOWN ; CCURRT EQU 18H ;CURSOR RIGHT ; CCURLT EQU 08H ;CURSOR LEFT ; CEOL EQU 1EH ;ERASE TO END OF LINE ; CEOS EQU 1FH ;ERASE TO END OF SCREEN ; CHOMUP EQU 1DH ;HOME UP ; CBELL EQU 07H ;BELL ; CHLITE EQU 0EH ;HIGHLITE ; CREVID EQU 00H ;REVERSE VIDEO ; CBLINK EQU 00H ;CBLINK ; CUNLIN EQU 00H ;UNDERLINE ; ŠCLPEN EQU 00H ;LIGHT PEN POSTION ; CMEM EQU 00H ;MEMORY MAP MODE ; CMEMO EQU 00H ;MEMORY MAP OFF ; CRDCUR EQU 05H ;READ CURSOR POSITION ; CSCLWT EQU 00H ;CHANGE SCROLL SPEED ; CALTCH EQU 00H ;CHANGE CHARACTER ROM ; CDELLN EQU 00H ;DELETE A LINE ; CINLN EQU 00H ;INSERT A LINE ; CATOFF EQU 00H ;YURNS ALL ATTRIBUTES OFF ; ; ; ; SCREEN ATTRIBUTES USING ESCAPE CHARACTER CODES ; ; ; EHOME EQU 00H ;HOME ; ESTCUR EQU 00H ;SET CURSOR POSTION ; ECURUP EQU 00H ;CURSOR UP ; ECURDN EQU 00H ;CURSOR DOWN ; ECURRT EQU 00H ;CURSOR RIGHT ; ECURLT EQU 00H ;CURSOR LEFT ; EEOL EQU 00H ;ERASE TO END OF LINE ; EEOS EQU 00H ;ERASE TO END OF SCREEN ; EHOMUP EQU 00H ;HOME UP ; EBELL EQU 00H ;BELL ; EHLITE EQU 'H' ;HIGHLIGHT ; EREVID EQU 'R' ;REVERSE VIDEO ; EBLINK EQU 'B' ;BLINK ; EUNLIN EQU 'U' ;UNDERLINE ; ELPEN EQU 'L' ;LIGHT PEN POSITION ; EMEM EQU 'M' ;MEMORY MAP MODE ; EMEMO EQU 'O' ;MEMORY MAP OFF ; ERDCUR EQU 00H ;READ CURSOR POSTION ; ESCLWT EQU 'S' ;CHANGE SCROLL SPEED ; EALTCH EQU 'C' ;CHANGE CHARACTER ROM ; EDELLN EQU 'D' ;DELETE A LINE ; EINLN EQU 'I' ;INSERT A LINE ; EATOFF EQU 'Q' ;TURNS ALL ATTRIBUTES OFF ; ; ; ; MEMORY MAP DIMENSIONS ; ; ; MMLINE EQU 24 ;NUMBER OF SCREEN LINES ; MMCOL EQU 80 ;NUMBER OF COLUMNS ; ; ; ; NUMBER OF ATTRIBUTES ; ; ; ATTCTR EQU 23 ;ATTRIBUTE TABLE COUNTER ; ; ; ; CURSOR OFFSET ; ; ; OFFSET EQU 00H ;SOME TERMINALS USE IT ; ; ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; INTERNAL BUSS PORT ASSIGNMENTS ; ; This is a list of I/O ports used on the ; internal buss Š; CRTC EQU 41H ;CRTC COMMAND/STATUS CRTD EQU 40H ;CRTC DATA DMARST EQU 30H ;DMA INTERRUPT RESET SPEAK EQU 50H ;SPEAKER KYS100 EQU 20H ;KEYBOARD TO S100 S100ST EQU 00H ;S100 PORT STATUS VDS100 EQU 10H ;S100 TO VIDIO DISPLAY KEYBRD EQU 60H ;KEYBOARD TO DISPLAY BOARD MMH EQU 70H ;MEM MAP HI ADDR MML EQU 71H ;MEM MAP LO ADDR MMD EQU 72H ;MEM MAP DATA MMEN EQU 73H ;MEM MAP ENABLE MMS EQU 74H ;MEM MAP STATUS ; ; COMMONLY USED PARAMETERS ; ; This is a list of commonly used values ; HCR EQU 4FH ;SCREEN CONTROL PARAMETERS VVVR EQU 57H ;SEE INTEL 8275 DATA SHEET ULL EQU 0BBH ;FOR USE MFCH EQU 9BH LITP EQU 60H ;LIGHT PEN COMMAND CRTEI EQU 0A0H ;ENABLE CRT INTERRUPT STRSCR EQU 23H ;START SCREEN COMMAND CURPOS EQU 80H ;LOAD CURSOR COMMAND CR EQU 0DH ;CARRAGE RETURN LF EQU 0AH ;LINE FEED NULL EQU 00H ;NULL ESC EQU 1BH ;ESCAPE CODE SPACE EQU 20H ;SPACE ENDDMA EQU 0F1H ;STOP LINE DMA COMMAND STPDMA EQU 0F3H ;STOP SCREEN DMA COMMAND ; ; ABSOLUTE ADDRESSES ; ; This is a list of common addresses used ; by the program ; TOPSCR EQU 800H ;TOP OF DISPLAY MEMORY TOPSC8 EQU TOPSCR+8000H ;DISPLAY ADDR WITH DMA BIT STACK EQU 13A0H ;TOP OF STACK TOPKEY EQU 1150H ;TOP OF KEYBOARD BUFFER BOTKEY EQU 008FH ;MAX KEYBD BUFFER COUNT WTCTR EQU 11D1H ;SCROLL DELAY NUMBER BCTR EQU 11D2H ;KEYBOARD BUFFER COUNTER KYINA EQU 11D3H ;HOLDS ADDRESS OF KEYBOARD BUFFER IN PTR KYOTA EQU 11D5H ;HOLDS ADDRESS OF KEYBOARD BUFFER OUT PTR MMSTUS EQU 11D7H ;I/O OR MEMORY MAP FLAG ATTBUF EQU 11D8H ;CURRENT ATTRIBUTE BYTE REGISTER ATTFLG EQU 11D9H ;NEW ATTRIBUTE REQUEST FLAG TEMP EQU 11DAH ;TEMPORARY STORAGE TEMP2 EQU 11DBH ;TEMPORARY ADDRESS STORAGE ŠSCRTBL EQU 1200H ;CRT LINE TRANSFER TABLE TEMPLN EQU 1250H ;TEMORARY LINE BUFFER FOR ATT CHANGES DUMMY EQU 0000H ;DUMMY ADDRESS NAME ; ; START OF PROGRAM ; ORG 0000H ; ; This begining of the program initializes all ; hardware, sets the stack, initializes the RAM ; and sets interrupts ; NOP ;RESET STACK RETURN ADDRESS NOP LD SP,STACK ;SET STACK IM1 ;SET INTERRUPT MODE LD A,CRTEI ;ENABLE CRT INTERRUPT OUT (CRTC),A LD HL,TOPKEY ;INITIALIZE KEYBD BUFFER POINTERS LD (KYINA),HL LD (KYOTA),HL LD IX,BCTR ;SET KEYBD BUFFER COUNTER XOR A ;ZERO A REG LD (MMSTUS),A ;ZERO FLAG TO I/O LD (BCTR),A ;ZERO BUFFER COUNTER LD (WTCTR),A ;ZERO SCREEN SPEED CTR LD (ATTFLG),A ;ZERO ATTRIBUTE FLAG CALL INTCRT ;INITIALIZE CRT CONTROLLER IN A,(VDS100) ;CLEAR PORTS IN A,(KEYBRD) OUT (DMARST),A ;RESET DMA INTERRUPT LD A,STRSCR ;START DISPLAY OUT (CRTC),A EI ;ENABLE INTERRUPTS JP BDSTAT ;JMP TO PORT STATUS ROUTINE ; ; KEYBOARD SERVICE ROUTINE ; ; This routine reads the keyboard port and places the ; data in the keyboard buffer where the data is held ; until the host computer is ready for it. ; ORG 38H ; PUSH HL ;SAVE REGISTERS PUSH AF LD HL,(KYINA) ;GET ADDRESS POINTER LD A,L ;CHECK TO SEE IF AT END OF BUFFER CP BOTKEY JR NZ,NOBOT LD HL,TOPKEY ;LOAD POINTER TO TOP NOBOT: IN A,(KEYBRD) ;GET DATA FROM PORT LD (HL),A ;SAVE DATA IN BUFFER INC HL ;INC POINTER INC (IX+0) ;INC COUNTER Š LD (KYINA),HL ;SAVE ADDRESS POINTER POP AF ;RESTORE REGISTERS POP HL EI ;ENABLE KEYBOARD INTERRUPT RET ;RETURN FROM INTERRUPT ; ; SCREEN REFRESH SERVICE ROUTINE ; ; This routine transfers the characters from memory ; and loads them into the CRT controller. This is ; done by placing the start of the line in the stack ; and "poping" the data onto the buss. The CRT con- ; troller latches the data when address 15 is high. ; To decrease overhead the characters are periodicly ; checked for end of line codes. ; ORG 66H ; EX AF,AF' ;USE ALT A EXX ;USE ALT REGISTERS LD E,(IY+0) ;LOAD DE' WITH NEXT LINE LD D,(IY+1) LD HL,00 ;ZERO HL ADD HL,SP ;SAVE SP EX DE,HL LD SP,HL ;LOAD LINE ADDR IN SP POP AF ;TRANSFER TO CRTC POP AF POP AF POP AF POP AF POP AF POP AF POP AF CP ENDDMA ;END OF LINE? JR Z,NOMORE POP AF POP AF POP AF POP AF POP AF POP AF POP AF POP AF CP ENDDMA ;END OF LINE? JR Z,NOMORE POP AF POP AF POP AF POP AF POP AF POP AF POP AF POP AF CP ENDDMA ;END OF LINE? Š JR Z,NOMORE POP AF POP AF POP AF POP AF POP AF POP AF POP AF POP AF CP ENDDMA ;END OF LINE? JR Z,NOMORE POP AF POP AF POP AF POP AF POP AF POP AF POP AF POP AF CP ENDDMA ;END OF LINE? JR Z,NOMORE POP AF POP AF POP AF POP AF POP AF POP AF POP AF POP AF POP AF NOMORE: EX DE,HL LD SP,HL ;RESTORE SP XOR A ;CLEAR A INC IY ;POINT TO NEXT LINE INC IY CP (IY+1) ;IS IY AT TABLE BOTTOM JR NZ,CONT1 LD IY,SCRTBL ;YES - POINT TO TOP OF TABLE CONT1: OUT (DMARST),A ;RESET INTERRUPT EXX ;RETURN REGISTERS EX AF,AF' RETN ; ; TERMINAL STATUS ROUTINE ; ; For I/O mode ; BDSTAT: CALL STATUS ;GET STATUS CALL VIDEO ;SERVICE HOST JR BDSTAT ;LOOP ; ; I/O PORT STATUS ROUTINE ; ; This routine scans the S100 I/O port for ; video characters or commands and checks the Š; keyboard buffer counter for new keystrokes. ; STATUS: IN A,(S100ST) ;DATA FROM S100? RRA RET C ;SERVICE HOST LD A,(BCTR) ;LOAD KEYBD BUFFER COUNT CP 0 ;KEY BUFFER EQ ZERO? CALL NZ,KEYOUT ;SEND CHARACTER TO HOST JR STATUS ;LOOP ; ; SCREEN SERVICE ROUTINE ; ; This routine reads the video character or ; command and takes the appropriate action. ; It also update the cursor and address pointers ; and places attributes if changed. ; VIDEO: IN A,(VDS100) ;GET CHARACTER AND 7FH ;MASK BIT 7 CP NULL ;IGNORE NULL RET Z CP CR ;CHECK FOR CARRAGE RETURN JR Z,CRLF CP LF ;CHECK FOR LINE FEED JR Z,LIFD CP ESC ;CHECK FOR ESCAPE CODE JR Z,ESCAPE CP ' ' ;CHECK FOR CONTROL CHARACTERS JR C,CTRAP PLCHAR: LD B,A ;SAVE CHARATER LD A,(ATTFLG) ;IS NEW ATTRIBUTE REQUESTED CP 1 CALL Z,PRATT ;YES - PUT ON SCREEN LD A,(HL) ;GET CURRENT CHARACTER CP 0F0H ;AT EOL? JP Z,WRAP ;YES - WRAP TO NEXT LINE AND 0C0H ;STRIP LOW BITS CP 80H ;IS IT AND ATTRIBUTE CALL Z,ADJSCR ;YES ADJUST SCREEN LD A,B ;GET CHARACTER LD (HL),A ;STORE CHARACTER LD A,E ;LOAD CURSOR COLUMN CP 79 ;CURSOR EQ 80? JP Z,WRAP ;WRAP CURSOR TO NEXT LINE INC E ;UPDATE CURSOR INC HL ;UPDATE POINTER ADDRESS CALL CURSOR ;UPDATE CURSOR POSITION RET ; ; CONTROL CHARACTER TRAP ROUTINE ; ; This routine determine which control code ; has been called and jump to its service routine. ; It ignores control codes not implemented. ; ŠCTRAP: PUSH HL ;SAVE REGISTERS PUSH DE PUSH BC LD HL,CTLTBL ;LOAD TOP OF CONTROL TABLE FDMAT: LD BC,ATTCTR+1 ;LOAD CONTROL TABLE COUNTER CPIR ;FIND A MATCH JP PO,NOMAT ;RETURN IF NO MATCH DEC C ;SUBTRACT OFFSET RLC C ;MULT COUNT X2 LD HL,ATTTBL ;LOAD CONTROL JMP TABLE ADD HL,BC ;ADD OFFSET LD E,(HL) ;GET JUMP ADDRESS INC HL LD D,(HL) EX DE,HL ;PUT ADDRESS IN HL POP BC ;RESTORE REGISTERS POP DE JP (HL) ;EXECUTE CTL CHARACTER NOMAT: POP BC ;RESTORE REGISTERS POP DE POP HL RET ; ; ESCAPE TRAP ROUTINE ; ; This routine looks for a ASCII character after ; an ESCAPE and determines the service routine ; requested. It ignores any unused codes. ; ESCAPE: PUSH HL ;SAVE REGISTERS PUSH DE PUSH BC CALL STATUS ;GET NEXT CHARACTER IN A,(VDS100) ;GET CHARACTER AND 7FH ;STRIP PARITY LD HL,ESCTBL ;LOAD TOP ESC TABLE JR FDMAT ;FIND THE MATCH ; ; WRAP TO NEXT LINE ROUTINE ; ; This routine puts the cursor on the next ; line in column zero. ; WRAP: CALL CRLF ;DO CARRAGE RETURN JR LIFD ;DO A LINE FEED ; ; CARRAGE RETURN ROUTINE ; ; This routine puts the cursor in column zero ; on the same line. ; CRLF: LD E,0 ;SET CURSOR COLUMN TO ZERO CALL CURSOR ;UPDATE CURSOR CALL LNADD ;CALC NEW LINE ADDRESS LD A,1 ;SET ATTRIBUTE REQUEST FLAG Š LD (ATTFLG),A RET ; ; LINE FEED ROUTINE ; ; This routine moves the cursor to the next line ; in the same column. ; LIFD: LD A,C ;BOTTOM OF SCREEN? CP 23 CALL Z,SCROLL ;YES THEN SCROLL SCREEN INC C ;ADD LINE TO CURSOR CALLN: CALL LNADD ;CALC NEW LINE ADDRESS CALL FILL ;REMOVE ENDDMA IN FRONT OF CURSOR ADD HL,DE ;ADD COLUMN NUMBER CALL PRATT ;CHECK ATTRIBUTES CALL CURSOR ;MOVE CURSOR RET ; ; SCROLL ROUTINE ; ; This routine moves the screen up one line ; and blanks the last line. ; SCROLL: LD A,(WTCTR) ;START OF WAIT LOOP CHECK: CP 0 ;IF ZERO NO WAIT JR Z,NOWAIT LD B,0 CHI: EX (SP),HL ;WASTE TIME EX (SP),HL DJNZ CHI ;LOOP TILL DONE DEC A ;DEC WAIT COUNT JR CHECK NOWAIT: PUSH BC ;SAVE REGISTERS PUSH DE PUSH HL DI ;DISABLE KEYBOARD IN A,(CRTC) ;CLEAR IRQ BIT CRTWT: IN A,(CRTC) ;WAIT TILL VERT RETRACE AND 20H ;MASK IRQ BIT JR Z,CRTWT LD HL,(SCRTBL) PUSH HL LD HL,SCRTBL+2 ;LOAD TOP OF TABLE +2 LD DE,SCRTBL ;LOAD TOP OF TABLE LD BC,46 ;LOAD COUNTER LDIR POP HL ;STORE OLD TOP LD (SCRTBL+46),HL ;STORE IT RES 7,H ;MASK DMA BIT LD A,(MMSTUS) ;CHECK I/O MEM MAP FLAG CP 0 ;IF 0 THEN I/O JR Z,DMAFIL LD B,80 ;LOAD COUNTER WITH 80 SPALP: LD (HL),' ' ;PUT SPACES IN LAST LINE Š INC HL ;ADVANCE POINTER DJNZ SPALP ;LOOP TILL DONE LD B,16 ;LOAD COUNTER FOR ENDDMA JR BLKLP DMAFIL: LD B,96 ;LOAD COUNTER FOR ENDDMA BLKLP: LD (HL),ENDDMA ;PUT ENDDMA IN LAST LINE INC HL ;ADVANCE POINTER DJNZ BLKLP ;LOOP TILL LINE FILLED EI ;ENABLE INTERRUPTS POP HL ;RESTORE REGISTERS POP DE POP BC DEC C ;PRESET CURSOR LINE RET ; ; CALCULATES NEW LINE ADDRESS ; ; This routine calculates the refresh memory ; address of the first character in the line ; designated in register C ; LNADD: PUSH BC ;SAVE REGISTER PUSH DE LD B,0 ;CLEAR B FOR DOUBLE ADD RLC C ;MULTIPLY X2 LD HL,SCRTBL ;LOAD TOP OF TABLE ADD HL,BC ;ADD OFFSET LD E,(HL) ;GET POINTER ADDR INC HL LD D,(HL) EX DE,HL ;PUT ADDR IN HL RES 7,H ;REMOVE CRTC CONTROL BIT POP DE ;RESTORE REGISTER POP BC RET ; ; FILL ROUTINE ; ; This routine removes all of the end of line ; code from in front of the cursor. This is done ; so that new characters will be visable on that ; line. This routine also counts the invisable ; attributes and adjusts the pointer address. ; FILL: PUSH DE ;SAVE REGISTERS PUSH HL LD B,0 ;ZERO ATTRIBUTE COUNTER FLOOP: LD A,(HL) ;GET CHARATER AND 0C0H ;STRIP 4 LSB CP 0C0H ;IS IT A DMA CONTROL JR NZ,NODMA LD (HL),' ' ;YES - PUT SPACE NODMA: DEC E ;DEC COUNTER JP M,NOFILL ;IF NEG ALL DONE CP 80H ;IS IT AN ATTRIBUTE Š JR NZ,NOTATT INC B ;INC ATTRIBUTE COUNTER INC E ;INC CHARACTER COUNTER NOTATT: INC HL ;ADVANCE POINTER JR FLOOP ;ANY MORE? NOFILL: POP HL ;RESTORE HL LD E,B ;MOVE COUNTER FOR ADD ADD HL,DE ;ADD ATTRIBUTE OFFSET POP DE ;RESTORE DE RET ; ; INTIALIZE ALL CRT FIRMWARE ; ; This routine sets-up the CRT controller ; prepares the RAM area and initializes the ; cursor. ; INTCRT: OUT (CRTC),A ;RESET CRTC ; LD C,CRTD ;LOAD C WITH CRTC ADDR LD B,4 LD HL,PARTBL ;LOAD SREEEN PARAMETER TABLE OTIR ;OUTPUT TO CRTC ; LD BC,-98*24 ;LOAD COUNTER LD HL,TOPSCR ;LOAD TOP A INTLP: LD (HL),ENDDMA ;FILL MEMORY WITH END DMA INC HL INC BC ;COUNTER EQ ZERO? BIT 7,B JR NZ,INTLP LD B,24 ;LOAD COUNTER LD HL,TOPSCR+96 ;POINT AT END OF LINE LD DE,98 ;LOAD OFFSET PER LINE ATTLOP: LD (HL),0F0H ;DENOTES END OF LINE ADD HL,DE ;ADD OFFSET FOR NEXT LINE DJNZ ATTLOP ;LOOP TILL 24 LINES DONE LD A,(MMSTUS) ;IF MEM MAP ON FILL SPACES CP 0 CALL NZ,MEMINT ;YES - PUT SPACES ; LD HL,TOPSCR+98*23 LD (HL),STPDMA ;WILL SYNC SCREEN WITH Z80 LD BC,DLEND-ISCTBL ;INITIALIZE SCRTBL LD DE,SCRTBL LD HL,ISCTBL LDIR ;MOVE IT TO RAM ; LD C,0 ;INITIALIZE REGISTERS LD D,C LD E,D CALL CURSOR ;INITIALIZE CURSOR ; LD IY,SCRTBL ;LOAD TOP OF TABLE LD L,(IY+0) ;LOAD POINTER INTO HL Š LD H,(IY+1) RES 7,H ;RESET DMA BIT LD A,80H ;CLEAR ATTRIBUTE BYTE LD (ATTBUF),A RET ; PARTBL: DEFB HCR ;SCREEN CONTROL PARAMETERS DEFB VVVR DEFB ULL DEFB MFCH ; ISCTBL: DEFW TOPSC8 ;LINE TABLE FOR SC8EEN REFRESH DEFW TOPSC8+98 DEFW TOPSC8+98*2 DEFW TOPSC8+98*3 DEFW TOPSC8+98*4 DEFW TOPSC8+98*5 DEFW TOPSC8+98*6 DEFW TOPSC8+98*7 DEFW TOPSC8+98*8 DEFW TOPSC8+98*9 DEFW TOPSC8+98*10 DEFW TOPSC8+98*11 DEFW TOPSC8+98*12 DEFW TOPSC8+98*13 DEFW TOPSC8+98*14 DEFW TOPSC8+98*15 DEFW TOPSC8+98*16 DEFW TOPSC8+98*17 DEFW TOPSC8+98*18 DEFW TOPSC8+98*19 DEFW TOPSC8+98*20 DEFW TOPSC8+98*21 DEFW TOPSC8+98*22 DEFW TOPSC8+98*23 DEFW 0000 WDMOVE: LD (DUMMY),HL ;SWAP LINES IN TABLE RET ; TO PREVENT FLASHING DLEND: RWDMOV EQU WDMOVE-ISCTBL+SCRTBL ;ADDRESS OF WORD LOAD ; ; MOVE CURSOR ROUTINE ; ; This routine moves the cursor on the srceen ; based on the data in registers C & E. ; CURSOR: LD A,CURPOS ;SEND CONTROL CHAR OUT (CRTC),A LD A,E ;SEND COLUMN OUT (CRTD),A LD A,C ;SEND LINE OUT (CRTD),A RET ; ; KEYBOARD BUFFER TO S100 SERVICE ROUTINE Š; ; This routine checks the S100 keyboard port ; status and return if busy or loads the port ; with the next character in the keyboard ; buffer. ; KEYOUT: IN A,(KYS100) ;CHECK STATUS RRA ;NOT READY RETURN RET C PUSH HL ;SAVE HL LD HL,(KYOTA) ;GET OUTPUT BUFFER ADDR DEC (IX+0) ;DEC COUNTER LD A,L ;CHECK ADDR AT BOTTOM CP BOTKEY JR NZ,NOBOT1 ;NO THEN SKIP LD HL,TOPKEY ;POINT TO TOP NOBOT1: LD A,(HL) ;GET CHARACTER OUT (KYS100),A ;SEND TO HOST INC HL ;INC POINTER LD (KYOTA),HL ;SAVE POINTER POP HL ;RESTORE HL RET ; ; ATTRIBUTE CONTROL ROUTINES ; ; ; HOME ROUTINE ; ; This routine clears the screen and puts the ; cursor at the home postion. ; HOME: POP HL ;RESTORE REGISTER XOR A ;CLEAR A CALL INTCRT ;CLEAR SCREEN LD A,STRSCR ;RESTART CRTC OUT (CRTC),A RET ; ; SET CURSOR POSITION ROUTINE ; ; This routine takes the next two byte from the ; S100 video port and moves the cursor according ; to the values. ; STCUR: POP HL ;RESTORE REGISTER CALL STATUS ;WAIT FOR CURSOR LINE IN A,(VDS100) ;GET CURSOR LINE SUB OFFSET ;REMOVE OFFSET CP 24 ;IF > MAX, MAKE MAX LD C,23 JP P,CURNXT LD C,A ;STORE IN C CURNXT: CALL STATUS ;WAIT FOR CURSOR COLUMN IN A,(VDS100) ;GET CURSOR COLUMN SUB OFFSET ;REMOVE OFFSET Š CP 80 ;IF > MAX MAKE MAX LD E,79 JP P,PLCUR LD E,A ;STORE IN E PLCUR: CALL LNADD ;CALC LINE ADDRESS CALL FILL ;REMOVE DMA CONTROLS ADD HL,DE ;ADD COLUMN TO ADDRESS LD A,1 ;SET ATTRIBUTE REQUEST FLAG LD (ATTFLG),A CALL CURSOR ;MOVE CURSOR RET ; ; CURSOR UP ROUTINE ; ; This routine moves the cursor up one line. ; if the line is more than the minimum value. ; CURUP: POP HL ;RESTORE REGISTER LD A,C ;AT FIRST LINE? CP 0 RET Z ;YES - DO NOTHING DEC C ;SUBTRACT ONE FROM LINE JR PLCUR ;PLACE CURSOR ; ; CURSOR DOWN ROUTINE ; ; This routine moves the cursor down one line ; if the line is less than maximum value. ; CURDN: POP HL ;RESTORE REGISTER LD A,C ;AT BOTTOM LINE CP 23 RET Z ;YES - DO NOTHING INC C ;ADD ONE TO LINE JR PLCUR ;PLACE CURSOR ; ; CURSOR RIGHT ROUTINE ; ; This routine moves the cursor right one ; column if the column is less than the ; maximum value. ; CURRT: POP HL ;RESTORE REGISTER LD A,E ;AT END OF LINE? CP 79 RET Z ;YES - DO NOTHING INC E ;ADD ONE TO COLUMN JR PLCUR ;PLACE CURSOR ; ; CURSOR LEFT ROUTINE ; ; This routine move the cursor left one column ; if the column is greater than the minimum value. ; CURLT: POP HL ;RESTORE REGISTER Š LD A,E ;AT BEGINING OF LINE? CP 0 RET Z ;YES DO NOTHING DEC E ;SUBTRACT ONE FROM COLUMN JR PLCUR ;PLACE CURSOR ; ; ERASE TO END OF LINE ROUTINE ; ; This routine erases the line from the cursor postion ; to the end of the line. ; EOL: POP HL ;RESTORE REGISTER EOL1: PUSH HL ;SAVE REGISTERS PUSH DE CALL PRVATT ;FIND PREVIOUS ATTRIBUTE LD B,A ;TEMP STORE LD A,(HL) ;GET CHARACTER CP 0F0H ;AT EOL? JR Z,EOLEND ;YES - DO NOTHING CP 80H ;OFF ATTRIBUTE BYTE JR NZ,EOLATT ;NO - PUT SPACE INC HL ;ADVANCE POINTER LD A,(HL) ;GET CHARACTER CP 0F0H ;AT EOL? JR Z,EOLEND ;YES - DO NOTHING LD (HL),' ' ;PUT SPACE JR EOLLP ;ERASE REST OF LINE EOLATT: LD (HL),' ' ;PUT SPACE INC HL ;ADVANCE POINTER LD A,(HL) ;GET CHARACTER CP 0F0H ;AT EOL? JR Z,EOLEND ;YES - DO NOTHING LD A,80H ;LOAD OFF ATTRIBUTE BYTE CP B ;SAME AS PREVIOUS ATTRIBUTE JR NZ,EOLSP ;NO - PUT OFF BYTE LD A,ENDDMA EOLSP: LD (HL),A ;PUT ON SCREEN INC HL ;ADVANCE POINTER CP 0F0H ;AT EOL? JR Z,EOLEND ;YES - DO NOTHING LD (HL),' ' ;PUT SPACE EOLLP: INC HL ;ADVANCE POINTER LD A,(HL) ;GET CHARACTER CP 0F0H ;END OF LINE? JR Z,EOLEND ;YES - STOP EOLOVR: LD (HL),ENDDMA ;PUT DMA CODE JR EOLLP ;NEXT CHARACTER EOLEND: LD A,(MMSTUS) ;IF MEM MAP ON FILL WITH SPACES CP 0 CALL NZ,MMFILL ;YES - PUT SPACES POP DE ;RESTORE REGISTERS POP HL RET ; ; ERASE TO END OF SCREEN ROUTINE Š; ; This routine erases the screen from the ; current cursor position. ; EOS: POP HL ;RESTORE REGISTER CALL EOL1 ;ERASE TO END OF LINE PUSH HL ;SAVE REGISTERS PUSH DE PUSH BC ENL: LD B,96 ;LOAD LINE COUNT INC C ;ADVANCE LINE CALL LNADD ;FIND START OF LINE EOSLP: LD (HL),ENDDMA ;STORE CONTROL CHARACTER INC HL ;INC ADDRESS DJNZ EOSLP ;LOOP TILL DONE LD A,23 ;LAST LINE? CP C JR NZ,ENL LD A,(MMSTUS) ;IF MEM MAP ON FILL WITH SPACES CP 0 POP BC ;GET REGISTER FOR MOVE PUSH BC ;RESAVE CALL NZ,MMFILL ;YES - PUT SPACES POP BC ;RESTORE REGISTERS POP DE POP HL RET ; ; DELETE LINE ; ; this routine deletes the line the cursor is on ; and scrolls all the remaining line under it up one ; DELLN: POP HL ;RESTORE REGISTER PUSH BC ;SAVE REGISTERS PUSH DE PUSH HL LD A,(TOPSCR+98*23) ;REMOVE SYNC BYTE CP STPDMA JR NZ,OVRSTP LD A,ENDDMA LD (TOPSCR+98*23),A OVRSTP: LD HL,SCRTBL ;LOAD TOP OF TABLE LD B,0 ;CLEAR B FOR ADD RLC C ;MULTIPLY LINE # BY 2 ADD HL,BC ;ADD OFFSET LD E,L ;MOVE TO DE LD D,H LD A,(HL) ;GET ADDRES OF DELETED LINE LD (TEMP2),A ;STORE IT INC HL LD A,(HL) ;GET SECOND BYTE LD (TEMP2+1),A INC HL LD A,46 ;CALCULATE COUNT Š SUB C ;SUBSTRACT CURRENT LINE JR Z,DNOMOV ;IF ZERO DON'T MOVE LD C,A ;MOVE TO C ; IN A,(CRTC) ;LOOK FOR END OF FRAME DCRTWT: IN A,(CRTC) ;GET IRQ BIT AND 20H ;MASK FOR IRQ BIT JR Z,DCRTWT ;NO - WAIT FOR IT ; LDIR ;MOVE TABLE DNOMOV: LD HL,(TEMP2) LD (SCRTBL+46),HL ;PUT THIS ADDRESS AT BOTTOM LNFIL: RES 7,H ;MASK DMA BIT LD A,(MMSTUS) ;CHECK I/O MEM MAP FLAG CP 0 JR Z,DFIL ;IF I/O FILL WITH DMA LD B,80 ;LOAD COUNT DSPLP: LD (HL),' ' ;PUT SPACE ON SCREEN INC HL ;ADVANCE POINTER DJNZ DSPLP ;LOOP TILL DONE LD B,16 ;LOAD CTR FOR DMA BYTES JR DBLKLP DFIL: LD B,96 ;LOAD LINE COUNT DBLKLP: LD (HL),ENDDMA ;PUT DMA ON SCREEN INC HL ;ADVANCE POINTER DJNZ DBLKLP ;LOOP TILL DONE POP HL POP DE POP BC JP CALLN ; ; INSERT LINE ; ; This routine inserts a line at the cursar position ; and moves the lines below down one. ; INLN: POP HL ;RESTORE REGISTER PUSH BC ;SAVE REGISTERS PUSH DE PUSH HL LD HL,SCRTBL ;LOAD TOP OF TABLE LD B,0 ;CLEAR B FOR ADD RLC C ;MULTIPLY LINE # BY 2 ADD HL,BC ;ADD OFFSET PUSH HL ;SAVE ADDRESS LD HL,(SCRTBL+46) ;LOAD BOTTOM OF TABLE PUSH HL ;SAVE ADDRESS LD A,46 ;LOAD TOTAL COUNT SUB C ;GET OFFSET JR Z,NOMOVE ;IF ZERO DON'T MOVE LINES LD C,A ;LOAD COUNT LD HL,SCRTBL+45 ;LOAD ADRESSES FOR MOVE LD DE,SCRTBL+47 ; IN A,(CRTC) ;LOOK FOR END OF FRAME ŠICRTWT: IN A,(CRTC) ;GET IRQ BIT AND 20H ;MASK FOR IRQ BIT JR Z,ICRTWT ;NO - WAIT FOR IT ; LDDR ;MOVE TABLE NOMOVE: POP DE ;GET ADDRESSES POP HL LD (HL),E ;PUT BACK IN TABLE INC HL LD (HL),D EX DE,HL ;GET ADDRESS IN HL JR LNFIL ;FILL IN BLANKED LINE ; ; HOME UP ; ; This routine puts the cursor in the home ; postion leaving the screen unchanged. ; HOMUP: POP HL ;RESTORE REGISTER LD C,0 ;ZERO POSITIONS LD E,C JP PLCUR ;PLACE CURSOR ; ; BELL ROUTINE ; ; This routine activates the bell circuits. ; BELL: POP HL ;RESTORE REGISTER OUT (SPEAK),A ;RING BELL RET ; ; INTEL 8275 ATTRIBUTE ROUTINES ; ; The 8275 use a byte (10UR0CBH) to control ; screen attribute functions, where U is ; underline, R is reverse video, C is the alternate ; character generator, B is blink, and H is highlight. ; The routines below toggle the function bits when ; called. There can be only 16 attribute bytes per ; line, but consecutive functions are stored in the same ; byte. ; ; ALL ATTRIBUTES OFF ; ATOFF: POP HL ;RESTORE REGISTER LD A,80H ;TURN OFF ATTRIBUTES JR ATTFSH ;PLACE ATTRIBUTE ; ; HIGHLITE ROUTINE ; HLITE: POP HL ;RESTORE REGISTER LD A,(ATTBUF) ;GET ATTRIBUTE STATE BIT 0,A ;TEST BIT JR NZ,RESETH SET 0,A ;SET BIT Š JR ATTFSH ;PLACE ATTRIBUTE RESETH: RES 0,A ;RESET BIT JR ATTFSH ;PLACE ATTRIBUTE ; ; REVERSE VIDEO ROUTINE ; REVID: POP HL ;RESTORE REGISTER LD A,(ATTBUF) ;GET ATTRIBUTE STATE BIT 4,A ;TEST BIT JR NZ,RESETR SET 4,A ;SET BITS SET 5,A JR ATTFSH ;PLACE ATTRIBUTE RESETR: RES 4,A ;RESET BITS RES 5,A JR ATTFSH ;PLACE ATTRIBUTE ; ; UNDERLINE ROUTINE ; UNLIN: POP HL ;RESTORE REGISTER LD A,(ATTBUF) ;GET ATTRIBUTE STATE BIT 5,A ;TEST BIT JR NZ,RESETU SET 5,A ;SET BIT JR ATTFSH ;PLACE ATTRIBUTE RESETU: RES 5,A ;RESET BIT JR ATTFSH ;PLACE ATTRIBUTE ; ; BLINK ROUTINE ; BLINK: POP HL ;RESTORE REGISTER LD A,(ATTBUF) ;GET ATTRIBUTE STATE BIT 1,A ;TEST BIT JR NZ,RESETB SET 1,A ;SET BIT JR ATTFSH ;PLACE ATTRIBUTE RESETB: RES 1,A ;RESET BIT JR ATTFSH ;PLACE ATTRIBUTE ; ; CHANGE CHARACTER GENERATOR ROM ; ALTCH: POP HL ;RESTORE REGISTER LD A,(ATTBUF) ;GET ATTRIBUTE STATE BIT 2,A ;TEST BIT JR NZ,RESETA SET 2,A ;SET BIT JR ATTFSH ;PLACE ATTRIBUTE RESETA: RES 2,A ;RESET BIT ATTFSH: LD (ATTBUF),A ;SAVE CURRENT ATTRIBUTE LD A,1 LD (ATTFLG),A ;SET ATTRIBUTE REQUEST FLAG RET ; ; PLACE ATTRIBUTE ROUTINE ; Š; This routine places the attribute byte in ; refresh memory, but merges it with the last ; character if it was an attribute. ; Plus alot of house cleaning. ; PRATT: XOR A ;CLEAR A LD (ATTFLG),A ;ZERO ATTRIBUTE REQUEST FLAG ; CALL PRVATT ;GET OLD ATTRIBUTE LD (TEMP),A ;STORE IT ; PUSH BC ;SAVE REGISTER PUSH DE CALL TMPSCN ;SWAP LINE ADDRESS ; DEC HL ;CHECK TO SEE IF LAST LD A,(HL) ;GET CHARACTER AND 0C0H ;MASK BYTE CP 80H ;ATTRIBUTE? JR Z,MERGE ;YES - WRITE OVER INC HL LD A,(HL) ;GET CHARACTER CP 0F0H ;AT EOL? JP Z,ATDONE ;YES - DO NOTHING AND 0C0H ;STRIP LOW BITS CP 0C0H ;DMA CHARACTER? JR Z,ATTSP ;YES - WRITE OVER CP 80H ;ATTRIBUTE BYTE? JR Z,MERGE ;YES - WRITE OVER LD A,(TEMP) ;GET OLD ATTRIBUTE LD B,A ;PUT IN B LD A,(ATTBUF) ;IF SAME AS OLD ATTRIBUTE CP B ; DO NOTHING JR Z,ATDONE CALL MVCHRT ;IS CHARACTER ADJUST SCREEN RIGHT LD A,(ATTBUF) ;STORE ATTRIBUTE ON SCREEN LD (HL),A ; ATTBCK: INC HL ;POINT AT RIGHT SIDE OF CHARACTER LD A,(HL) ;AT EOL? CP 0F0H JR Z,ATDONE ;YES - STOP INC HL LD A,(HL) ;GET CHARACTER CP 0F0H ;AT EOL? JR Z,ATONE ;YES - STOP AND 0C0H ;STRIP LOW BITS CP 80H ;ATTRIBUTE BYTE? JR Z,ATTSAM CP 0C0H ;DMA BYTE? JR Z,DMA1 CALL MVCHRT ;MOVE LINE RIGHT LD A,B ;GET OLD ATTRIBUTE LD (HL),A ;PUT ON SCREEN ATONE: DEC HL ;POINT AT CHARACTER Š JR ATDONE ; MERGE: LD A,(HL) ;GET OLD ATTRIBUTE LD B,A ;PUT IN B LD A,(ATTBUF) ;GET NEW ATRIBUTE CP B ;SAME AS OLD? JR Z,NOCHG LD (HL),A ;WRITE OVER OLD ATTRIBUTE JR ATTBCK ;LOOK AT BACK SIDE OF CHARACTER NOCHG: INC HL ;POINT TO NEXT CHARACTER JR ATDONE ; DMA1: LD (HL),80H ;WRITE OVER DMA INC HL ;PLACE SPACE LD A,(HL) ;GET CHARACTER CP 0F0H ;AT EOL? JR Z,DMAOVR ;YES - STOP LD (HL),' ' ; ON SCREEN DMAOVR: DEC HL ;POINT TO CHARACTER DEC HL JR ATDONE ; ATTSAM: LD A,(HL) ;GET ATTRIBUTE LD B,A ;PUT IN B LD A,(ATTBUF) ;GET NEW ATTRIBUTE CP B ;IS IT THE SAME? JR NZ,ATTNMT ;NO - DO NOTHING INC HL ;SET POINTER FOR MOVE CALL MOVSCR ;MOVE LINE LEFT JR ATDONE ATTNMT: DEC HL ;POINT TO CHARACTER JR ATDONE ; ATTSP: LD A,(TEMP) ;GET OLD ATTRIBUTE LD B,A ;PUT IN B LD A,(ATTBUF) ;GET NEW ATTRIBUTE CP B ;IF SAME AS OLD ATTRIBUTE JR Z,ATDONE ; DO NOTHING LD (HL),A ;PUT NEW ATTRIBUTE ON SCREEN INC HL ;MOVE POINTER LD A,(HL) ;GET CHARACTER CP 0F0H ;AT EOL? JR Z,ATDONE ;YES - STOP LD (HL),' ' ;WRITE OVER DMA BYTE LD A,(ATTBUF) ;GET NEW ATTRIBUTE CP 80H ;IF NEW ATT TURNS ALL OFF JR Z,ATDONE ; STOP INC HL ;MOVE POINTER LD A,(HL) ;GET CHARACTER CP 0F0H ;AT EOL? JR Z,SPOVR ;YES - STOP LD (HL),80H ;PUT NO ATT BYTE ON SCREEN INC HL ;MOVE POINTER LD A,(HL) ;GET CHARACTER CP 0F0H ;AT END OF LINE? Š JR Z,OVRSP ;YES - THEN STOP LD (HL),' ' ;OR PUT SPACE BEHIND ATTRIBUTE OVRSP: DEC HL ;POINT AT NEXT CHARACTER SPOVR: DEC HL ; ATDONE: PUSH HL LD HL,(TEMP2) ;GET LINE ADDRESS CALL RWDMOV ;SWAP SCAN LINE IN TABLE POP HL ;RESTORE REGISTERS ATTFIN: POP DE POP BC RET ; ; ADJUST SCREEN ; This routine prevents the over write of attributes ; already placed on the screen or removes unnecessary ; attributes. ; ADJSCR: LD A,(ATTBUF) ;GET LATEST ATTRIBUTE CP (HL) ;SAME AS PRESENT? JR NZ,NOTSAM ;NO - CONTINUE INC HL ;SET POINTER CALL TMPSCN ;DO TEMP SCAN CALL MOVSCR ;WRITE OVER ATTRIBUTE INC HL ;RESET POINTER JR EDSCN ;END TEMP SCAN NOTSAM: INC HL ;POINT TO NEXT POSSIBLE ATTRIBUTE LD A,(HL) ;GET CHARACTER CP 0F0H ;AT EOL? JR NZ,ADJOVR ;NO - CONTINUE DEC HL ;RETURN POINTER RET ADJOVR: INC HL LD A,(HL) ;GET CHARACTER CP 0F0H ;AT EOL? JR Z,ATTONE ;YES - ALL DONE AND 0C0H ;STRIP LOW BITS CP 0C0H ;IS IT DMA CODE? JR NZ,NOADJ ;NO CHECK FOR ATTRIBUTE LD (HL),' ' ;WRITE OVER DMA CODE JR ATTONE NOADJ: CP 80H ;IS IT AN ATTRIBUTE? JR NZ,ATTONE ;YES MOVE SCREEN CALL TMPSCN ;MOVE LINE FOR TEMP SCAN CALL MOVSCR LD (HL),' ' ;COVER OLD ATTRIBUTE INC HL ;LOOK AT ATTRIBUTE LD A,(ATTBUF) ;GET CURRENT ATTRIBUTE CP (HL) ;COMPARE DEC HL ;RESET POINTER JR NZ,EDSCN ;NO - FINISH INC HL ;SET POINTER CALL MOVSCR ;MOVE LEFT ONE INC HL ;RESET POINTER LD (HL),' ' ;COVER ATTRIBUTE W/SPACE ŠEDSCN: PUSH HL ;SAVE REGISTER LD HL,(TEMP2) ;GET LINE ADDRESS CALL RWDMOV POP HL ;RESTORE REGISTER RET ATTONE: DEC HL ;PLACE ATTRIBUTE OVER ONE DEC HL LD A,(HL) ;GET ATTRIBUTE LD (RWDMOV+1),HL ;SET UP FOR WORD MOVE PUSH HL ;SAVE ADDRESS LD H,A ;MOVE ATTRIBUTE LD L,' ' ;LOAD SPACE IN H CALL RWDMOV ;PUT SPACE ATTRIBUTE ON SCREEN POP HL ;RESTORE ADDRESS RET ; MOVSCR: PUSH HL ;SAVE REGISTERS PUSH DE PUSH BC LD E,L ;MOVE HL TO DE LD D,H DEC HL ;POINT FIRST CHARACTER NXTMOV: LD A,(DE) ;GET CHARACTER TO BE MOVED CP 0F0H ;AT END OF LINE? JR NZ,OVRMOV ;NO - MOVE CHARACTER LD (HL),' ' ;PUT SPACE JR MOVEND ;STOP OVRMOV: LD (HL),A ;MOVE CHARACTER CP 0F1H ;WAS IT A DMA CODE? JR Z,MOVEND ;YES - STOP INC HL ;MOVE ON TO NEXT CHARACTER INC DE JR NXTMOV MOVEND: POP BC ;RESTORE REGISTERS POP DE POP HL DEC HL ;MOVE BACK DEC HL RET ; ; MOVE LINE RIGHT ; This routine moves a line of characters to the right ; one position to make room for an attribute byte. ; MVCHRT: PUSH HL ;SAVE REGISTERS PUSH DE PUSH BC LD E,L ;DESTINATION ADDR IN DE LD D,H INC DE ;INC TO RIGHT LD A,(HL) ;GET CHARACTER LD C,A ;TEMP STORE MOVRGT: LD A,(DE) ;GET CHARACTER LD B,A ;TEMP STORE CP 0F0H Š JR Z,MOVDON ;YES - MOVE DONE LD A,C ;GET TEMP CHAR LD (DE),A ;MOVE IT LD C,B ;MOVE OVER LD A,C ;CHECK FOR DMA BYTE AND 0F0H CP 0F0H INC HL ;INC POINTERS INC DE JR NZ,MOVRGT ;NEXT CHARACTER MOVDON: POP BC ;RESTORE REGISTERS POP DE POP HL RET ; ; TEMPORARY SCAN ROUTINE ; ; This routine move the current line to a ; temporary buffer. The temporary buffer ; address is then placed in the refresh ; address table. This prevents flashing on ; the screen during attribute updates. ; The original address is returned to the ; table after the update. ; TMPSCN: PUSH BC ;SAVE REGISTERS PUSH DE PUSH HL LD B,0 ;CLEAR B FOR ADD RLC C ;MULTIPLY C X2 LD HL,SCRTBL ;LOAD SCREEN ADDRESS TABLE ADD HL,BC ;ADD LINE OFFSET LD (RWDMOV+1),HL ;SAVE TABLE ADDRESS LD E,(HL) ;GET LINE ADDRESS INC HL LD D,(HL) LD (TEMP2),DE ;SAVE LINE ADDRESS ; EX DE,HL ;GET LINE ADDRESS RES 7,H ;CLEAR DMA BIT LD DE,TEMPLN ;GET TEMPORARY LINE ADDRESS LD BC,96 ;GET LINE COUNT LDIR ;MOVE LINE TO TEMPORARY LD HL,TEMPLN ;GET TEMPORARY LINE ADDRESS SET 7,H ;SET DMA BIT CALL RWDMOV ;SWAP LINE IN TABLE POP HL ;RESTORE REGISTERS POP DE POP BC RET ; ; FIND PREVIOUS ATTRIBUTE CODE ; ; This routine finds the last attribute ; placed in front of the cursor so the Š; proper bit may be toggled without dis- ; turbing any previously toggled bits. ; PRVATT: PUSH HL ;SAVE REGISTERS PUSH DE PUSH BC NOFDAT: EX DE,HL ;PUT CURRENT POINTER IN DE CALL LNADD ;GET BEGINING OF LINE EX DE,HL ;PUT ADDRESS IN DE NXTATT: OR A ;CLEAR CARRY PUSH HL ;SAVE ADDRESS SBC HL,DE ;AT FRONT OF LINE YET? POP HL ;RESTORE ADDRESS JP M,FDONE ;NO ATTRIBUTES FOUND LD A,(HL) ;GET CHARACTER AND 0C0H ;MASK LSB CP 80H ;ATTRIBUTE? LD A,(HL) ;RESTORE CHARACTER JR Z,FINDAT ;YES STOP DEC HL ;DEC POINTER JP NXTATT FDONE: LD A,80H ;BLANK ATTRIBUTE CODE FINDAT: POP BC POP DE POP HL RET ; ; LIGHT PEN ROUTINE ; ; This routine reads the light pen registers ; after being set by a light pen. The data ; is then sent to the keyboard port in two ; bytes with the column first. Note - due to ; delays in the light pen the column position ; may have to be corrected in the host computer ; software. ; LPEN: POP HL ;RESTORE REGISTER LPLP: IN A,(CRTC) ;GET STATUS AND 10H ;MASK BITS JR Z,LPLP ;LOOP TILL READY LD A,LITP ;GET DATA OUT (CRTC),A IN A,(CRTD) ;GET COLUMN LD B,A CALL DTAOUT ;SEND IT IN A,(CRTD) ;GET LINE LD B,A CALL DTAOUT ;SEND IT RET ; ; READ CURSOR POSTION ; ; This routine sends the cursor postion ; to the keyboard port in two bytes with Š; the line first. ; RDCUR: POP HL ;RESTORE REGISTER LD B,C ;GET LINE CALL DTAOUT ;SEND DATA LD B,E ;GET COLUMN CALL DTAOUT ;SEND DATA RET ; ; CHANGE SCROLL SPEED ROUTINE ; ; This routine allows the user to control the ; scroll speed of the screen. 0 is the fastest ; (default) and 9 is the slowest. ; SCLWT: POP HL ;RESTORE REGISTER CALL STATUS ;GET NUMBER IN A,(VDS100) AND 0FH ;STRIP ASCII CP 10 ;IF > 9 MAKE 9 JP M,NOT9 LD A,9 ;MAKE NINE NOT9: RLCA ;MULT X4 RLCA LD (WTCTR),A ;STORE IT RET ; ; SEND DATA TO HOST COMPUTER ; ; This routine send data to the host computer ; via the keyboard port. ; DTAOUT: IN A,(KYS100) ;CHECK STATUS RRA JR C,DTAOUT LD A,B ;GET DATA OUT (KYS100),A ;SEND IT RET ; ; MEMORY MAP SOFTWARE ; ; ; INITIALIZE SCREEN FOR MEMORY MAP ; ; This routine removes all end of line codes ; from the screen memory so any poked characters ; will be seen immediately. It also enables ; the memory map circuits. ; MEMINT: PUSH BC ;SAVE REGISTERS PUSH DE PUSH HL LD C,0 ;LOAD LINE ZERO CALL MMFILL ;FILL MEMORY WITH SPACES IN A,(MMEN) ;ENABLE MEMORY MAP CKTS Š LD A,1 ;SET I/O MEM MAP FLAG LD (MMSTUS),A POP HL ;RESTORE REGISTERS POP DE POP BC RET ; ; MEMORY MAP FILL ROUTINE ; ; This routine fills the display memory with ; spaces. ; MMFILL: PUSH BC ;SAVE REGISTERS PUSH DE PUSH HL LD E,79 ;LOAD LAST COLUMN SPCLP: CALL LNADD ;CALC LINE ADDRESS CALL FILL ;FILL WITH SPACES INC C ;INC LINE LD A,MMLINE ;LOAD MAX LINE CP C ;AT BOTTOM YET? JR NZ,SPCLP POP HL ;RESTORE REGISTERS POP DE POP BC RET ; ; MEMORY MAP STATUS ROUTINE ; ; This routine checks the status of the video ; I/O port the memory map latches and the keyboard ; buffer. If any are true they are serviced. ; MEM: POP HL ;RESTORE REGISTER CALL MEMINT ;INITIALIZE SCREEN MMSTAT: IN A,(S100ST) ;CHECK OUT STAUS RRA CALL C,VIDEO ;YES, PUT CHARACTER ON SCREEN LD A,(BCTR) ;CHECK KEYBOARD BUFFER CP 0 CALL NZ,KEYOUT ;SEND CHARACTER TO HOST IN A,(MMS) ;GET MEMORY MAP STATUS RRA CALL NC,MMVIDE ;YES PUT CHARACTER ON SREEEN JR MMSTAT ;LOOP AGAIN ; ; MEMORY MAP SERVICE ROUTINE ; ; This routine takes the address latched in the memory ; map latches and calculates the position on the screen. ; The it takes the data from the latches and places it ; in refresh memory. ; MMVIDE: PUSH BC ;SAVE REGISTERS PUSH DE Š PUSH HL IN A,(MMH) ;GET ADDRESS LD H,A IN A,(MML) LD L,A AND 0FH ;STRIP HIGH BITS PUSH AF ;SAVE OFFSET SRL H ;ROTATE HL LEFT FOUR TIMES RR L SRL H RR L SRL H RR L SRL H RR L LD B,5 ;LOAD DIVIDE COUNTER LD D,MMCOL ;LOAD MAX COLUMN LD C,0 ;ZERO C LD A,L ;MOVE NUMBER TO A MMDIV: SUB D ;SUB DIVISOR JP P,MMPOS ;POSITIVE NUMBER CONTINUE ADD A,D ;RESTORE NUMBER JR MMCONT MMPOS: SET 0,C ;SET BIT MMCONT: SLA C ;ROTATE REGISTERS TO DIVIDE SLA A DJNZ MMDIV ;CONTINUE SRL C ;RESTORE POSITION SRL A POP DE ;GET REMAINDER ADD A,D ;ADD TO OFFSET LD D,0 ;READY FOR ADD LD E,A LD A,MMLINE-1 ;CHECK IF OVER MAX LINE CP C JP M,MMEND ;YES - DO NOTHING CALL LNADD ;CALC LINE ADDRESS ADD HL,DE ;ADD COLUMN NUMBER IN A,(MMD) ;GET DATA LD (HL),A ;PUT ON SCREEN JR MMEND1 MMEND: IN A,(MMD) ;WASTE DATA & RESET FLAG MMEND1: POP HL ;RESTORE REGISTERS POP DE POP BC RET ; ; MEMORY MAP OFF ; ; This routine turns the memory map circuits off ; and returns to I/O map only mode. ; MEMO: POP HL ;RESTORE REGISTER IN A,(MMEN) ;RESET MEMORY MAP CKTS XOR A ;RESET I/O MEM MAP FLAG Š LD (MMSTUS),A POP AF ;WASTE CALL JP BDSTAT ;RETURN TO STATUS ROUTINE ; ; CONTROL CHARACTER TRAP TABLE ; CTLTBL: DEFB CHOME DEFB CSTCUR DEFB CCURUP DEFB CCURDN DEFB CCURRT DEFB CCURLT DEFB CEOL DEFB CEOS DEFB CHOMUP DEFB CBELL DEFB CHLITE DEFB CREVID DEFB CBLINK DEFB CUNLIN DEFB CLPEN DEFB CMEM DEFB CMEMO DEFB CRDCUR DEFB CSCLWT DEFB CALTCH DEFB CDELLN DEFB CINLN DEFB CATOFF DEFB 00 ; ; ESCAPE CHARACTER TRAP TABLE ; ESCTBL: DEFB EHOME DEFB ESTCUR DEFB ECURUP DEFB ECURDN DEFB ECURRT DEFB ECURLT DEFB EEOL DEFB EEOS DEFB EHOMUP DEFB EBELL DEFB EHLITE DEFB EREVID DEFB EBLINK DEFB EUNLIN DEFB ELPEN DEFB EMEM DEFB EMEMO DEFB ERDCUR DEFB ESCLWT DEFB EALTCH DEFB EDELLN DEFB EINLN Š DEFB EATOFF DEFB 00 ; ; ATTRIBUTE JUMP TABLE ; ATTTBL: DEFW ATOFF DEFW INLN DEFW DELLN DEFW ALTCH DEFW SCLWT DEFW RDCUR DEFW MEMO DEFW MEM DEFW LPEN DEFW UNLIN DEFW BLINK DEFW REVID DEFW HLITE DEFW BELL DEFW HOMUP DEFW EOS DEFW EOL DEFW CURLT DEFW CURRT DEFW CURDN DEFW CURUP DEFW STCUR DEFW HOME THEEND: END