.Z80 SIZE EQU 000H TITLE VIDEO DISPLAY SOFTWARE ROM-1 ; ; COPYRIGHT (C) BY ; THE SIMPLIWAY PRODUCTS CO. ; ALL RIGHTS RESERVED ; ; VERSION 1.1 03-18-82 ; ; 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 PLACED IN THE CONTROL CHARACTER; ; AREA. ATTRIBUTES MAYBE DISABLED BY PLACING A ; ; 00H AFTER THE EQU. ; ; ; ; SCREEN ATTRIBUTES USING CONTROL CHARACTERS ; ; ; CHOME EQU 0CH ; HOME FF ; CSTCUR EQU 14H ; SET CURSOR POSITION ; CCURUP EQU 1AH ; CURSOR UP ; CCURDN EQU 0BH ; CURSOUR 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 ; HIGHTLITE ; CREVID EQU 00H ; REVERSE VIDEO ; CBLINK EQU 00H ; CBLINK ; CUNLIN EQU 00H ; UNDERLINE ; CLPEN EQU 00H ; LIGHT PEN POSITION ; 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 CHARACTRER ROM ; ; ; ; SCREEN ATTRIBUTES USING ESCAPE CHARACTER CODES ; ; ; EHOME EQU 00H ; HOME ; ESTCUR EQU 00H ; SET CURSOR POSITION ; 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 47H ; BELL ; EHLITE EQU 'H' ; HIGHTLITE ; EREVID EQU 'R' ; REVSERSE 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 POSITION ; ESCLWT EQU 'S' ; CHANGE SCROLL SPEED ; EALTCH EQU 'C' ; CHANGE CHARACTER ROM ; ; ; ; MEMORY MAP DIMENSIONS ; ; ; MMLINE EQU 24 ; NUMBER OF SCREEN LINES ; MMCOL EQU 80 ; NUMBER OF COLUMNS ; ; ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; 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 VIDEO 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 ATTCTR EQU 20 ; ATTRIBUTE TABLE COUNTER ; ; 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 BOTSCR EQU TOPSCR+96*23 ; BOTTOM OF DISPLAY MEMORY STACK EQU 13A0H ; TOP OF STACK TOPKEY EQU 1150H ; TOP OF KEYBOARD BUFFER BOTKEY EQU 008FH ; BOTTOM OF KEYBOARD BUFFER - 1100H 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 SCRTBL EQU 1200H ; CRT LINE TRANSFER TABLE ; ; START OF PROGRAM ; ASEG ; ; THIS BEGINING OF THE PROGRAM INITIALIZES ALL ; HARDWARE, SETS THE STACK, INITIALIZES THE RAM ; AND SETS INTERRUPTS ; IM 1 ; SET INTERRUPT MODE LD A,CRTEI ; ENABLE CRT INTERRUPT OUT (CRTC),A LD SP,STACK ; SET STACK LD HL,TOPKEY ; INIT KEYBD BUFFER PTR 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 CALL INTCRT ; INIT 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 ; JUMP TO PORT STUTUS 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 SIZE+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 CHARACTWRS ARE PERIODICLY ; CHECKED FOR END OF LINE CODES. ; ORG SIZE+66H EX AF,AF' ; USE ALT A EXX ; USE ALT REGISTERS LD HL,0000 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 NOMORE: EX DE,HL LD SP,HL ; RESTORE SP XOR A ; CLEAR A LD L,A ; CLEAR HL LD H,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: LD E,(IY+0) ; LOAD DE' WITH NEXT LINE LD D,(IY+1) 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) ; ZERO A FLAG CP 0 ; KEY BUFFER EQU 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. ; VIDEO: IN A,(VDS100) ; GET CHARACTER AND 7FH ; MASK BIT 7 CP NULL ; IGNORE NULL RET Z CP CR ; CHECK FOR CR JR Z,CRLF CP LF ; CHECK FOR LF JR Z,LIFD CP ESC ; CHECK FOR ESCAPE CODE JR Z,ESCAPE CP SPACE ; CHECK FOR CONTROL CHARACTER JR C,CTRAP PLCHAR: LD (HL),A ; STORE CHARACTER LD A,E ; LOAD CURSOR COLUMN CP 79 ; CURSOR EQ 80? JR 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 CALL AND JUMP TO ITS SERVICE ROUTINE ; IT IGNORE 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 CHARACTWR 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 ; AND 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 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 CALL LNADD ; CALC NEW LINE ADDR CALL FILL ; REMOVE ENDDMA IN FROM OF CURSOR ADD HL,DE ; ADD COLUMN NUMBER 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 REGISTER PUSH DE PUSH HL DI ; DISABLE KEYBOARD IN A,(CRTC) ; WAIT IF VERT RETRACE 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 EXX ; CHANGE REGISTERS LD E,(IY+0) ; LOAD NEW TOP OF SCREEN LD D,(IY+1) EXX 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),SPACE ; 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 REGISTERS 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 REGISTERS 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 CHARACTER AND 0C0H ; STRIP 4 LSB CP 80H ; IS IT AN ATTRIBUTE JR NZ,NOTATT INC B ; INC ATTRIBUTE COUNTER NOTATT: CP 0C0H ; IS IT A DMA CONTROL JR NZ,NODMA LD (HL),SPACE ; YES - PUT SPACE NODMA: INC HL ; ADVANCE POINTER DEC E ; DEC COUNTER JP P,FLOOP ; NOT DONE YET POP HL ; RESTORE HL LD E,B ; MOVE COUNTER FOR ADD ADD HL,DE ; ADD ATTRIBUTE OFFSET POP DE ; RESTORE DE RET ; ; INITIALIZE ALL CRT FIRMWARE ; ; THIS ROUTINE SETS-UP THE CRT CONTROLER ; PREPARES THE RAM AREA AND INITIALIZES THE ; CURSOR. ; INTCRT: OUT (CRTC),A ; RESET CRTC LD BC,96*24 ; LOAD COUNTER LD HL,TOPSCR ; LOADD TOP A INTLP: LD (HL),ENDDMA ; FILL MEMORY WITH END DMA INC HL DEC C ; COUNTER EQ ZERO? JR NZ,INTLP DEC B JR NZ,INTLP LD HL,TOPSCR+96*23 LD (HL),STPDMA ; WILL SYNC SCREEN TO Z80 LD C,CRTD ; LOAD C WITH CRTC ADDR LD B,4 LD HL,PARTBL ; LOAD SCREEN PARAMETER TABLE OTIR ; OUTPUT TO CRTC LD BC,50 ; 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 EXX LD IY,SCRTBL ; LOAD TOP OF TABLE LD E,(IY+0) ; LOAD POINTER INTO DE' LD D,(IY+1) PUSH DE ; SAVE FOR HL EXX POP HL ; GET START OF POINTER ADDRESS RE[ 7,H ; RESET DMA BIT RET PARTBL: DEFB HCR ; SCREEN CONTROL PARAMETERS DEFB VVVR DEFB ULL DEFB MFCH ISCTBL: DEFW TOPSC8 ; LINE TABLE FOR SCREEN REFRESH DEFW TOPSC8+96 DEFW TOPSC8+96*2 DEFW TOPSC8+96*3 DEFW TOPSC8+96*4 DEFW TOPSC8+96*5 DEFW TOPSC8+96*6 DEFW TOPSC8+96*7 DEFW TOPSC8+96*8 DEFW TOPSC8+96*9 DEFW TOPSC8+96*10 DEFW TOPSC8+96*11 DEFW TOPSC8+96*12 DEFW TOPSC8+96*13 DEFW TOPSC8+96*14 DEFW TOPSC8+96*15 DEFW TOPSC8+96*16 DEFW TOPSC8+96*17 DEFW TOPSC8+96*18 DEFW TOPSC8+96*19 DEFW TOPSC8+96*20 DEFW TOPSC8+96*21 DEFW TOPSC8+96*22 DEFW TOPSC8+96*23 DEFW 0000 ; ; MOVE CURSOR ROUTINE ; ; THIS ROUTINE MOVES THE CURSOR ON THE SCREEN ; 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 S100 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 POSITION. ; HOME: POP HL ; RESTORE REGISTER CALL INTCRT ; CLEAR SCREEN LD A,STRSCR ; RESTART CRTC OUT (CRTC),A RET ; ; SET CURSOR POSITION ROUTINE ; ; THIS ROUTINE TAKES THE NEXT TWO BYTES FROM THE ; S100 VIDEO PORT AND MOVES THE CURSOR ACCORD TO ; THE VALUES. ; STCUR: POP HL ; RESTORE REGISTER CALL STATUS ; WAIT FOR CURSOR LINE IN A,(VDS100) ; GET CURSOR LINE 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 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 CALL CURSOR ; MOVE CURSOR RET ; ; CURSOR UP ROUTINE ; ; THIS ROUTINE MOVES THE CURSOR UP ON 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 MOVES THE CURSOR LEFT ONE COLUMN ; IF THE COLUMN IS GREATER THAAN 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 POSITION ; TO THE END OF THE LINE. ; EOL: POP HL ; RESTORE REGISTER EOL1: PUSH HL ; SAVE REGISTERS PUSH DE LD (HL),' ' INC HL LD A,95 ; LOAD MAX LINE LENGTH SUB E ; SUBTRACT CURSOR POSITION LD E,A ; MOVE COUNT TO E DLLP: LD (HL),ENDDMA ; FILL REST OF LINE WITH ENDDMA INC HL ; ADVANCE POINTER DEC E ; DEC COUNTER JR NZ,DLLP ; LOOP TILL DONE 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 BC ; SAVE REGISTERS PUSH DE PUSH HL 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 POP HL ; RESTORE REGISTERS POP DE POP BC RET ; ; HOME UP ; ; THIS ROUTINE PUTS THE CURSOR IN THE HOME ; POSITION LEAVING THE SCREEN UNCHANGED. ; HOMUP: POP HL ; RESTORE REGISTER LD C,0 ; ZERO POSITION 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 USES 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. ; ; HIGHLITE ROUTINE ; HLITE: POP HL ; RESTORE REGISTER CALL PRVATT ; FIND PREVIOUS ATTRIBUTE 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 CALL PRVATT ; FIND PREVIOUS ATTRIBUTE 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 CALL PRVATT ; FIND PREVIOUS ATTRIBUTE 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 CALL PRVATT ; FIND PREVIOUS ATTRIBUTE 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 CALL PRVATT ; FIND PREVIOUS ATTRIBUTE BIT 2,A ; TEST BIT JR NZ,RESETA SET 2,A ; SET BIT JR ATTFSH ; PLACE ATTRIBUTE RESETA: RES 2,A ; RESET BIT ; ; PLACE ATTRIBUTE ROUTINE ; ; THIS ROUTINE PLACES THE ATTRIBUTE BYTE IN ; REFRESH MEMORY, BUT MERGES IT WITH THE LAST ; CHARACTER IF IT WAS AN ATTRIBUTE. ; ATTFSH: DEC HL ; CHECK TO SEE IF LAST LD B,A ; CHARACTER IS AN ATTRIBUTE LD A,(HL) ; GET CHARACTER AND 0C0H ; MASK BYTE CP 80H ; ATTRIBUTE? JR Z,PLATT ; YES - WRITE OVER INC HL PLATT: LD A,B ; GET ATTRIBUTE LD (HL),A ; STORE IT INC HL ; ADVANCE POINTER LD A,(HL) ;; CHECK IF NEXT CHAR IS ENDDMA AND 0F0H ; STRIP LSB CP 0F0H RET NZ ; NO RETURN LD (HL),SPACE 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 BEGINNING 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,ROSCR ; GO TO NEXT LINE 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 ; ROSCR: LD A,0 ; CHECK LINE POSITION CP C ; IF ZERO SCREEN DONE JR Z,FDONE DEC C ; DEC LINE COUNT LD DE,95 ; SET COUNT CALL LNADD ; GET BEGINNING OF LINE EX DE,HL ; PUT ADDRESS IN DE ADD HL,DE ; ADD CURSOR COLUMN 95 JP NXTATT ; SEARCH NEXT LINE ; 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 POSITION ; ; THIS ROUTINE SENDS THE CURSOR POSITION ; 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 ; GWT COLUMN CALL DTAOUT ; SEND CATA 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 SENDS DATA TO THE HOST COMPUTER ; VIA THE KEYBOARD PORT. ; DTAOU~: IN A,(KYS100) ; CHECK STATUS RRA JR C,DTAOUT LD A,B ; GET DATA OUT (KYS100),A ; SEND IT RET ; ; MEMORY MAP SOFTWARE ; ; 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. ; MEM: POP HL ; RESTORE REGISTER PUSH BC ; SAVE REGISTERS PUSH DE PUSH HL LD C,0 ; LOAD LINE ZERO 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 IN A,(MMEN) ; ENABLE MEMORY MAPcCKTS LD A,1 ; SET I/O MEM MAP FLAG LD (MMSTUS),A POP HL ; RESTORE REGISTERS POP DE POP BC ; ; 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. ; MMSTAT: IN A,(S100ST) ; CHECK OUT STATUS 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 SCREEN 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 ; THEN 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 LD DE,MMCOL ; LOAD MAX COLUMN NUMBER LD C,0 ; ZERO COUNTER MMLP: XOR A ; CLEAR CARRY SBC HL,DE ; FIND SCREEN LINE JP M,MMPUT ; IF MINUS LINE FOUND INC C ; INC LINE COUNTER LD A,C ; OVER MAX LINE? CP MMLINE JR Z,MMEND ; YES DO NOTHING JR MMLP ; MMPUT: ADD HL,DE ; RESTORE REMAINDER PUSH HL ; SAVE IT CALL LNADD ; CALC LINE ADDRESS EX DE,HL ; ADD REMAINDER POP HL ADD HL,DE 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 MAAP 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 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 00 ; ; ATTRIBUTE JUMP TABLE ; ATTTBL: 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 THENEND: END