Reply 80 of 187, by superfury
Looking at what the Turbo XT BIOS does:
mov dx, 61h
in al, dx ; Read machine flags
or al, 00110000b ; clear old parity error
out dx, al ; Write them back to reset
and al, 11001111b ; enable parity
out dx, al ; Write back, parity enabled
mov al, 80h ; allow NMI interrupts
out 0A0h, al
mov ax, 0000000000110000b ; Assume monochrome video
mov [ds:10h], ax ; card has been installed
int 10h ; initialize if present
mov ax,0000000000100000b ; Assume color/graphics video
mov [ds:10h], ax ; card has been installed
int 10h ; initialize if present
ifdef IBM_PC ; Read 5150 switch config
mov al, 0CCh
out dx, al ; Reset keyboard
in al, 60h ; Read config switches
mov ah, al
else ; Read 5160 switch config
in al, 62h ; Get memory size (64K bytes)
and al, 00001111b ; in bits 2,3 low nibble
mov ah, al ; Save memory size nibble
mov al, 10101101b
out dx, al
in al, 62h ; Get number of floppies (0-3)
endif
mov cl, 4 ; and init video mode
shl al, cl ; shift in hi nibble
or al, ah
mov ah, 0
mov [ds:10h], ax ; Start building Equipment Flag
and al, 00110000b ; if video card, mode set
jnz @@video_found ; found video interface
mov ax, offset dummy_int ; No hardware, dummy_int becomes
mov [es:40h], ax ; int_10 video service
jmp short @@skip_video
@@video_found:
call video_init ; Setup video
@@skip_video:
mov al, 00001000b ; Read low switches
out dx, al
It seems writes to port 61h somehow affect the values of port 62h to respond with different values giving information about the machine?
Edit: Looking at the ioports.lst of Bochs does indeed reveal something about it:
0061 w PPI Programmable Peripheral Interface 8255 (XT only)
system control port
bit 7 = 1 clear keyboard
bit 6 = 0 hold keyboard clock low
bit 5 = 0 I/O check enable
bit 4 = 0 RAM parity check enable
bit 3 = 0 read low switches
bit 2 reserved, often used as turbo switch
bit 1 = 1 speaker data enable
bit 0 = 1 timer 2 gate to speaker enable
It seems bit 3 toggles something to let port 62h return different values (low/high switches)?
Edit: It looks like I was right, although setting up for two floppy disk drives wasn't so simple as I thought:
byte readPPI62()
{
byte result=0;
//Setup PPI62 as defined by System Control Port B!
if (EMULATED_CPU<=CPU_80186) //XT machine?
{
if (SystemControlPortB&8) //Read high switches?
{
if (((getActiveVGA()->registers->specialCGAflags&0x81)==1)) //Pure CGA mode?
{
result |= 2; //First bit set: 80x25 CGA!
}
else if (((getActiveVGA()->registers->specialMDAflags&0x81)==1)) //Pure MDA mode?
{
result |= 3; //Both bits set: 80x25 MDA!
}
else //VGA?
{
//Leave PPI62 at zero for VGA: we're in need of auto detection!
}
result |= 4; //Two floppy drives installed!
}
else //Read low switches?
{
result |= 1; //Two floppy drives installed!
}
}
else
{
return PPI62; //Give the normal value!
}
return result; //Give the switches requested, if any!
}
byte PPI_readIO(word port, byte *result)
{
switch (port) //Special register: System control port B!
{
case 0x61: //System control port B?
*result = SystemControlPortB; //Read the value!
return 1;
break;
case 0x62: //PPI62?
*result = readPPI62(); //Read the value!
return 1;
break;
case 0x63: //PPI63?
*result = PPI63; //Read the value!
return 1;
break;
case 0x92: //System control port A?
*result = SystemControlPortA; //Read the value!
return 1;
break;
default: //unknown port?
break;
}
return 0; //No PPI!
}
byte PPI_writeIO(word port, byte value)
{
switch (port)
{
case 0x61: //System control port B?
SystemControlPortB = (value&0x7F); //Set the port, highest bit isn't ours!
return 1;
break;
case 0x62: //PPI62?
//PPI62 = value; //Set the value!
return 1;
break;
case 0x63: //PPI63?
PPI63 = value; //Set the value!
return 1;
break;
case 0x92: //System control port A?
MMU_setA20(1,value&2); //Fast A20!
if (value&1) //Fast reset?
{
doneCPU();
resetCPU(); //Reset the CPU!
}
SystemControlPortA = (value&(~1)); //Set the port!
return 1;
break;
default: //unknown port?
break;
}
return 0; //No PPI!
}
void initPPI()
{
SystemControlPortB = 0x7F; //Reset system control port B!
PPI63 = 0x00; //Set the default switches!
register_PORTIN(&PPI_readIO);
register_PORTOUT(&PPI_writeIO);
}
Bits 0-1 of the high switches seem to select the video adapter installed (according to the ioports.lst's values).
Bit 0 of the low switches sets 1 floppy disk when set without bit 2 of the high switches.
If bit 0 of the low switches and bit 2 of the high switches are both set, it sets 2 floppy disks it seems.
Any other combination seems to set no floppy disks at all it seems.
Anyone can confirm this or add information to this?
Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io