; ; Test program for Z80 KBDMSE on Retrobrewcomputer.org (Load with CPM). ; ; V0.1 ;Original version 2/23/2014 by John Monahan ; V0.2 ;Update for Z80 KBDMSE with VT82C42 PS/2 Keyboard Controller by Andrew Lynch ; ; Based on works by John Monahan S100Computers.com ; for S100 MSDOS Support Board with HT6542B Keyboard Controller ; Thanks to John for generously posting this program for others to use and adapt ; ; This is a simple test program to work with the Z80 KBDMSE board. It is written so ; the only other hardware use is the CP/M Console Port -- typically serial port interface. ; Note the data is displayed in crude (bulk) form. A proper scancode to ASCII translation ; routine must be written for practical use. See the IBM PC BIOS or SKEY.Z80 docs ; PORT ASSIGNMENTS KEY_DATA .EQU 0E2H ;Port used to access keyboard & Mouse (also sometimes Controller itself) KEY_CTRL .EQU 0E3H ;Port for VT82C42 PS/2 Keyboard & Mouse Controller ESC .EQU 1BH CR .EQU 0DH LF .EQU 0AH TAB .EQU 09H BELL .EQU 07H .ORG 0100H START: LD SP,STACK LD HL,SIGNON ; Signon CALL PRINT_STRING LD C,0AAH ;Test PS/2 Controller CALL CMD_OUT CHK1: CALL KEY_IN_STATUS ;wait for feedback JR Z,CHK1 IN A,(KEY_DATA) CP 055H ;If not 55H then error JR NZ,INIT_ERR LD C,060H ; Set keyboard controller cmd byte CALL CMD_OUT LD C,$60 ; XLAT ENABLED, MOUSE DISABLED, NO INTS CALL KEY_OUT LD C,0AEH ;Enable 1st PS/2 port CALL CMD_OUT ;Send it JR DONE_INIT INIT_ERR: LD HL,INIT_ERR_STR ;Say error CALL PRINT_STRING HALT ;Just Halt! DONE_INIT: LD HL,INIT_OK ;Say all OK CALL PRINT_STRING LOOP: CALL KEY_IN_STATUS ;See if keyboard key available JR Z,LOOP IN A,(KEY_DATA) LD C,A ;Store in [C] LD HL,SCAN_MSG CALL PRINT_STRING ;No registers changed CALL A_HEXOUT ;Display Hex value of typed character + two spaces ;CP 0F0H ;Is it an UP key AND 080H ;Is it an UP key JR Z,DOWNKY ;Must be a down key stroke LD HL,UPKEY_MSG ;Say Up Key CALL PRINT_STRING CALL ZCRLF JR LOOP DOWNKY: CP 58H ;Is it CAPS Lock key ; CP 3AH ;Is it CAPS Lock key JR NZ,NOT_CAPSKEY LD HL,CAPS_MSG ;Say Caps lock key CALL PRINT_STRING CALL ZCRLF JR LOOP NOT_CAPSKEY: CP 12H ;Is it a SHIFT key ; CP 2AH ;Is it a SHIFT key JR Z,SHIFTKEY CP 59H ;Is it the other SHIFT key ; CP 36H ;Is it the other SHIFT key JR NZ,NOT_SHIFTKEY SHIFTKEY: LD HL,SHIFT_MSG ;Say Shift key CALL PRINT_STRING CALL ZCRLF JR LOOP NOT_SHIFTKEY: CP 14H ;Is it the CTRL key ; CP 1DH ;Is it the CTRL key JR NZ,NOT_CTRLKEY LD HL,CTRL_MSG ;Say CTRL key CALL PRINT_STRING CALL ZCRLF JR LOOP NOT_CTRLKEY: CP 77H ;Is it the NUM LOCK key ; CP 45H ;Is it the NUM LOCK key JR NZ,NOT_NUMKEY LD HL,NUM_MSG ;Say Number key CALL PRINT_STRING CALL ZCRLF JR LOOP NOT_NUMKEY: PUSH BC ;Save Character LD HL,IBM1_MSG ;Say Table 1 lookup CALL PRINT_STRING LD HL,IBM1TBL ;Point to lookup table for upper case CALL SHOW_CHAR POP BC ;Get back character LD HL,IBM2_MSG ;Say Table 2 lookup CALL PRINT_STRING LD HL,IBM2TBL ;Point to lookup table for upper case CALL SHOW_CHAR CALL ZCRLF JR LOOP SHOW_CHAR: LD D,0 LD E,C ADD HL,DE ;Add in offset LD C,(HL) LD A,C CP ESC RET Z ;ESC messes up the screen display CP CR RET Z ;CR messes up the screen display CP LF RET Z ;LF messes up the screen display CP TAB RET Z ;TAB messes up the screen display CALL ZCO ;Display on Screen RET KEY_IN_STATUS: ;Ret NZ if character is available IN A,(KEY_CTRL) AND 1 RET ;Ret NZ if character available CMD_OUT: ;Send a byte (in [C]) to Control port IN A,(KEY_CTRL) AND 2 JR NZ,CMD_OUT ;Chip is not ready yet to receive character LD A,C OUT (KEY_CTRL),A RET KEY_OUT: ;Send a byte (in [C]) to Data port IN A,(KEY_CTRL) AND 2 JR NZ,KEY_OUT ;Chip is not ready yet to receive character LD A,C OUT (KEY_DATA),A RET ; A_HEXOUT ;output the 2 hex digits in [A] A_HEXOUT: ;No registers altered push AF push BC push AF srl a srl a srl a srl a call hexdigout pop AF call hexdigout ;get upper nibble LD C,' ' call ZCO ;Space for easy reading call ZCO pop BC pop AF ret hexdigout: and 0fh ;convert nibble to ascii add a,90h daa adc a,40h daa LD c,a call ZCO ret ; Main console I/O routines ; ZCO: PUSH HL LD E,C LD C,02H ;BDOS Function 2 Write Console Byte CALL 0005H ;Call BDOS POP HL RET ZCI: LD C,0BH ;BDOS Function 11 Read Console Status CALL 0005H ;Call BDOS JP Z,ZCI LD C,01H ;BDOS Function 1 Read Console Byte CALL 0005H ;Call BDOS RET ; ; Send CR/LF to Console ; ZCRLF: PUSH AF PUSH BC LD C,CR CALL ZCO LD C,LF CALL ZCO POP BC POP AF RET PRINT_STRING: PUSH AF push BC print1: LD a,(HL) ;Point to start of string inc HL ;By using the CS over-ride we will always have CP '$' ;a valid pointer to messages at the end of this monitor JP z,print2 CP 0 ;Also terminate with 0's JP Z,print2 LD C,A call ZCO jp print1 print2: pop BC POP AF ret ;--------------------------------------------------------------------------------------------------- ; Black: ESC,[30m ; Red: ESC,[31m ; Green: ESC,[32m ; Yellow: ESC,[33m ; Blue: ESC,[34m ; Magenta: ESC,[35m ; Cyan: ESC,[36m ; White: ESC,[37m ; Reset: ESC,[0m SIGNON: .DB CR,LF,LF .DB ESC,"[33m","Test VT82C42 PC Keyboard & Mouse controller chip on Z80 KBDMSE Board." ; Yellow .DB CR,LF,"$" INIT_ERR_STR: .DB CR,LF,BELL .DB ESC,"[31m","Error: The 0xAA Test of Controller did nor return 0x55. Program Halted." ; Red .DB CR,LF,"$" INIT_OK: .DB CR,LF .DB ESC,"[32m","The 0xAA Test of Controller returned 0x55. Now enter keyboard keys." ; Green .DB CR,LF,LF,"$" SCAN_MSG: .DB ESC,"[34m","Scancode = $" ; Blue UPKEY_MSG: .DB "(Up Keystroke)$" CAPS_MSG: .DB "(Caps Lock)$" SHIFT_MSG: .DB "(Shift Key)$" CTRL_MSG: .DB "(CTRL Key)$" NUM_MSG: .DB "(NUM Key)$" IBM1_MSG: .DB ESC,"[36m","Table 1 lookup -> $" ; Cyan IBM2_MSG: .DB ESC,"[37m"," Table 2 lookup -> $" ; White IBM1TBL: ;The "Normal" table ;00, 01, 02, 03, 04, 05, 06, 07, 08, 09, 0a, 0b, 0c, 0d, 0e, 0f ; .DB 0,"*", 0,"*","*","*","*","*", 0,"*","*","*","*",09H,"`",00H .DB 000,027,"1","2","3","4","5","6","7","8","9","0","-","=",008,009 ;00-0F ;10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 1a, 1b, 1c, 1d, 1e, 1f ; .DB 0, 0, 0, 0, 0,"q","1", 0, 0, 0,"z","s","a","w","2",0 .DB "q","w","e","r","t","y","u","i","o","p","[","]",013,000,"a","s" ;10-1F ;20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 2a, 2b, 2c, 2d, 2e, 2f ; .DB 0,"c","x","d","e","4","3", 0, 0," ","v","f","t","r","5",0 .DB "d","f","g","h","j","k","l",";",27H,60H,000,092,"z","x","c","v" ;20-2F ;30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 3a, 3b, 3c, 3d, 3e, 3f ; .DB 0,"n","b","h","g","y","6", 0, 0, 0,"m","j","u","7","8",0 .DB "b","n","m",",",".","/",000,000,000," ",000,000,000,000,000,000 ;30-3F ;40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 4a, 4b, 4c, 4d, 4e, 4f ; .DB 0,",","k","i","o","0","9", 0, 0,".","/","l",";","p","-",0 .DB 000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000 ;40-4F ;50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 5a, 5b, 5c, 5d, 5e, 5f ; .DB 0, 0,27H, 0,"[","=", 0, 0, 0, 0,0DH,"]", 0,5CH, 0,0 .DB 000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000 ;50-5F ;60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 6a, 6b, 6c, 6d, 6e, 6f ; .DB 0, 0, 0, 0, 0, 0,08H, 0, 0,11H, 0,13H,10H, 0, 0, 0 .DB 000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000 ;60-6F ;70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 7a, 7b, 7c, 7d, 7e, 7f ; .DB 0BH,7FH,03H,15H,04H,05H,1BH,00H,"*",02H,18H,16H,0CH,17H,"*",0 .DB 000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000 ;70-7F ;80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 8a, 8b, 8c, 8d, 8e, 8f ; .DB 0, 0, 0,"*", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 .DB 000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000 ;80-8F IBM2TBL: ;If the SHIFT key or CAPS lock key is on ;00, 01, 02, 03, 04, 05, 06, 07, 08, 09, 0a, 0b, 0c, 0d, 0e, 0f ; .DB 0, "*", 0,"*","*","*","*","*", 0,"*","*","*","*",09H,"~",00H .DB 000,027,"!","@","#","$","%","^","&","*","(",")","_","+",008,009 ;00-0F ;10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 1a, 1b, 1c, 1d, 1e, 1f ; .DB 0, 0, 0, 0, 0,"Q","!", 0, 0, 0,"Z","S","A","W","@",0 .DB "Q","W","E","R","T","Y","U","I","O","P","{","}",013,000,"A","S" ;10-1F ;20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 2a, 2b, 2c, 2d, 2e, 2f ; .DB 0,"C","X","D","E","$","#", 0, 0," ","V","F","T","R","%",0 .DB "D","F","G","H","J","K","L",":",034,"~",000,"|","Z","X","C","V" ;20-2F ;30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 3a, 3b, 3c, 3d, 3e, 3f ; .DB 0,"N","B","H","G","Y","^", 0, 0, 0,"M","J","U","&","*",0 .DB "B","N","M","<",">","?",000,000,000," ",000,000,000,000,000,000 ;30-3F ;40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 4a, 4b, 4c, 4d, 4e, 4f ; .DB 0,"<","K","I","O",29H,"(", 0, 0,">","?","L",":","P", "_",0 .DB 000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000 ;40-4F ;50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 5a, 5b, 5c, 5d, 5e, 5f ; .DB 0, 0,22H, 0,"{","+", 0, 0, 0, 0,0DH,"}", 0,"|", 0,0 .DB 000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000 ;50-5F ;60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 6a, 6b, 6c, 6d, 6e, 6f ; .DB 0, 0, 0, 0, 0, 0,08H, 0, 0,11H, 0,13H,10H, 0, 0, 0 .DB 000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000 ;60-6F ;70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 7a, 7b, 7c, 7d, 7e, 7f ; .DB 0BH,7FH,03H,15H,04H,05H,1BH,00H,"*",02H,18H,16H,0CH,17H,"*",0 .DB 000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000 ;70-7F ;80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 8a, 8b, 8c, 8d, 8e, 8f ; .DB 0, 0, 0,"*", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 .DB 000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000 ;80-8F .FILL 040H,000H STACK: .DB 0H .FILL 19,000H .END