There is only one problem left (I think), and this is where I'd welcome any help or suggestion.
I have not been able to understand what the expected behaviour of the original M24 keyboard is upon reset (remember, I do not currently have access to my own original M24 keyboard). As a consequence, in the BIOS POST routine the emulator is not recognized as a "deluxe" (Type 2) keyboard and the system defaults to the 82-key, "Type 1" keyboard. This means that some scancodes are misinterpreted by the BIOS. This is not a huge deal, as they two types are pretty similar. Also, the keyboard type flag can be corrected in software later on rather easily (bit 0 of the byte at 0040:0018 controls the keyboard type).
Similarly, the CUSTOMER.EXE program fails to recognize that there's a keyboard attached. Using SYSTEM.EXE you can force to run keyboard tests anyway but the output is a bit weird, which bring me to my first actual question (btw thanks for reading so far!):
- what should the "keyboard test" section of CUSTOMER.EXE / SYSTEM.EXE look like when connected to a real Type 2 keyboard? Can someone post a screenshot? Mine looks like this:
View attachment 1024964
I dug into the BIOS listing and this is the relevant code (see page 416 of the System Programmer's Guide) - this is executed just after the "beep" (ie after the RAM test and the "RT Clock Pass" message):
Code:
mov dx,p_kctrl ; dx = p_kctrl
mov al,40h ; remove keyboard reset
out dx, al
mov ah,1 ; enable self test
call kb_cmd_send
mov word ptr ds:[reset_flag],cx ;; cx is zero here
xor cx, cx
loop $ ; delay
; Flush any keyboard scan code and store AAh if we get it.
kb_flush:
in al,kb_status ; get 8041 status
test al,1 ; test output buffer bit
ja kb_flush_back ; jump if no character pending
in al,p_kscan ; get scan code from data port
cmp al,0AAh ; verify keyboard present
jne kb_flush
mov word ptr ds : [reset_flag],ax ; keyboard present
kb_flush_back:
loop kb_flush ; loop If zero
xor cx, cx ; delay
loop $
;; other memory variables init stuff
; Assume first not Deluxe Keyboard
and byte ptr ds:[kb_flag_1],(not dlx_kb)
; Send command to request ID code from keyboard.
mov ah,05H ; Read keyboard type
call kb_cmd_send ; -- send command.
xor cx, cx ; set up timeout count
kb_type_wait:
in al,kb_status ; get port status
test al,l ; data byte available?
jnz kb_type_read ; If so, go read it . .
loop kb_type_wait ; else wait awhile longer.
jmp kb_not_dlx ; timeout, default to non-dlx
kb_type_read:
in al,p_kscan ; read ID byte..
test al,01H ; deluxe kbd. bit set?
jz kb_not_dlx
; 01H bit set, so initialize to Deluxe Keyboard.
or byte ptr ds:[kb_flag_1],dlx_kb
kb_not_dlx:
(single semicolon comments are the original ones. Double semicolon ones are mine)
For reference,
Code:
p_kscan equ 060h
p_kctrl equ 061h
kb_status equ 064h
So there are three distinct parts:
a) "remove keyboard reset", ie release the clock line which, until that point, had been kept low (logic 0). Presumably this is what kept the keyboard LEDs blinking on the original keyboard (the Theory of Operation manual says that clock low for longer than 50ms triggers a reset).
b) "enable self test". This makes the keyboard controller send 0x10 (not 0x01!) to the keyboard. It then waits for 0xAA, which the emulator dutifully sends as soon as it spots the 0x10 from the M24. So far so good (I think).
c) "read keyboard type". This is where things go wrong. The code sends 0x05 to the data port of the keyboard controller (p_kscan), but nothing happens: nothing is sent to the keyboard itself. So the emulator does not know when to send its reply. The next IN operation always returns 0, and the keyboard is assumed to be non-deluxe.
This is where I'm stuck. I have tried several things (eg send another byte after 0xAA), but it made no difference. Incidentally CUSTOMER.EXE / SYSTEM.EXE seem to do the same thing - ie reset via the clock line & send 0x10, several times actually - but I can't get them to recognize that a keyboard is present (let alone which type).
I have now bitten the bullet and bought an AT&T keyboard off eBay so I can try and sniff the exchange, however it's not a "deluxe" type so it may not help me (and it hasn't arrived yet).
Any ideas?
Attached for your reference is the schematic I'm using (dip switches and M24 "sniffer" keyboard connector not implemented yet) and the source code. As always, if you want to experiment, use at your own risk...