per
Veteran Member
I am currently working on dissasembling the firmware of the IBM PGC. Recently, I have made some small progress now and then, but just now I made a BIG leap. I am now able to state how the card obtain it's input.
Just some basic information first (optional). The card has an 8088-2 CPU running at 8MHz. It got 64KB Firmware stored in ROM, 2KB SRAM shared with the hosting computer, and 320KB of DRAM (framebuffer and stored command lists). I know so far that the Firmware ROM appear at least twice in the memory map; at segment F000 and segment 0000. The SRAM appears at segment 2800 (C600 for the hosting computer), and is used for internal variables, the stack, and communication buffers. This SRAM is actually faster to comunicate with than the DRAM, because of the DRAM is accessed in nibbles (due to that memory is being shared with the video logics). There is being done reads and writes to various other spots in the memory map at initalizion, but I'm unsure what purpose it does this for.
When the card boots, it first checks the CPU. Then it checks the Firmware ROM, the DRAM, and finally it sets the internal variables. The last thing that happens is that it enters an endless loop. This loop contains a call to a routine that eventually forwards controll to the input routine by a jump. the input routine is terminated with a "ret", and controll will be returned to the endless loop instead of the routine called by the endless loop (at least in HEX mode, I believe it does some translation if ASCII mode is active).
If a byte is returned in AL, it will multiply AX with two, and call [CS:AX]. CS is 0025, and IP is F80F after the call instruction.
What happens is that the new IP depends on the input byte. The input byte does in fact points to a word-sized offset in a 512-byte table located at 0250. Each of therse offsets leads to the routine for the command corresponding to the input byte. The absolute location of the routine to be called is 0025ffset
Here is the table:
You clearly see that most of them contains the value 026E. Those leads directly to a "ret" instruction at absolute location 004BE, and all the commands pointing tho those can be treated as "not used".
I may start disassembling some of the smaller routines as soon I have tidying in the code. Maybe I could figure some of the internal variables.
There is also a similar list at 3060, but it does contain a lot of similar valuse for some of the "used" commands. I guess that table may be some kind of lookup about what kind of data should follow the command.
Just some basic information first (optional). The card has an 8088-2 CPU running at 8MHz. It got 64KB Firmware stored in ROM, 2KB SRAM shared with the hosting computer, and 320KB of DRAM (framebuffer and stored command lists). I know so far that the Firmware ROM appear at least twice in the memory map; at segment F000 and segment 0000. The SRAM appears at segment 2800 (C600 for the hosting computer), and is used for internal variables, the stack, and communication buffers. This SRAM is actually faster to comunicate with than the DRAM, because of the DRAM is accessed in nibbles (due to that memory is being shared with the video logics). There is being done reads and writes to various other spots in the memory map at initalizion, but I'm unsure what purpose it does this for.
When the card boots, it first checks the CPU. Then it checks the Firmware ROM, the DRAM, and finally it sets the internal variables. The last thing that happens is that it enters an endless loop. This loop contains a call to a routine that eventually forwards controll to the input routine by a jump. the input routine is terminated with a "ret", and controll will be returned to the endless loop instead of the routine called by the endless loop (at least in HEX mode, I believe it does some translation if ASCII mode is active).
If a byte is returned in AL, it will multiply AX with two, and call [CS:AX]. CS is 0025, and IP is F80F after the call instruction.
What happens is that the new IP depends on the input byte. The input byte does in fact points to a word-sized offset in a 512-byte table located at 0250. Each of therse offsets leads to the routine for the command corresponding to the input byte. The absolute location of the routine to be called is 0025ffset
Here is the table:
Code:
6E 02 6E 02 6E 02 6E 02 7D F6 10 D7 F0 48 20 4D 10 A1 40 A1 6E 02 6E 02 6E 02 6E 02 6E 02 B8 4D
30 71 B8 71 7A 71 13 72 6E 02 6E 02 6E 02 6E 02 6E 02 6E 02 6E 02 6E 02 6E 02 6E 02 6E 02 6E 02
6E 02 6E 02 6E 02 6E 02 6E 02 6E 02 6E 02 6E 02 90 33 10 34 71 34 D2 34 6E 02 6E 02 6E 02 6E 02
B0 A1 38 A2 0E A3 2A A3 60 72 74 72 6E 02 6E 02 90 0A 17 0B 6E 02 6E 02 AA 0E 29 11 6E 02 6E 02
6E 02 6E 02 6E 02 11 49 6E 02 6E 02 6E 02 6E 02 6E 02 6E 02 6E 02 6E 02 6E 02 6E 02 6E 02 A2 4C
92 84 A8 49 76 DE 6E 02 6E 02 6E 02 6E 02 6E 02 6E 02 6E 02 6E 02 28 02 6E 02 6E 02 6E 02 00 02
6E 02 6E 02 6E 02 11 49 6E 02 6E 02 6E 02 6E 02 6E 02 6E 02 6E 02 6E 02 6E 02 6E 02 6E 02 6E 02
A8 28 6E 02 48 2A 62 2A F1 29 62 2B 6E 02 6E 02 6E 02 6E 02 6E 02 6E 02 6E 02 6E 02 6E 02 6E 02
75 B4 9F B0 C6 B1 90 C3 80 C6 46 B4 6E 02 6E 02 6E 02 6E 02 6E 02 6E 02 6E 02 6E 02 6E 02 6E 02
41 DE 14 DF B7 DF 64 E0 D5 E0 46 E1 45 DF C4 DE 6E 02 6E 02 6E 02 6E 02 6E 02 6E 02 6E 02 6E 02
4A DE A7 E1 6E 02 EF E1 61 E2 E4 E2 6E 02 CC DE CD DD F1 DD 81 48 A6 48 6E 02 6E 02 6E 02 48 DD
6E E6 85 49 66 DA 4B D9 6E 02 6E 02 6E 02 6E 02 6E 02 6E 02 6E 02 6E 02 6E 02 6E 02 6E 02 6E 02
70 02 E7 02 6E 02 6E 02 6E 02 6E 02 6E 02 6E 02 6E 02 6E 02 6E 02 6E 02 6E 02 6E 02 6E 02 6E 02
3C 49 34 49 38 49 6E 02 6E 02 6E 02 6E 02 6E 02 F0 80 4B 81 6E 02 6E 02 6E 02 6E 02 6E 02 6E 02
6E 02 6E 02 6E 02 6E 02 6E 02 6E 02 6E 02 50 48 F7 4B 88 4C DB 4B A3 4B EB 84 D3 84 20 84 9A 49
6E 02 6E 02 6E 02 6E 02 6E 02 6E 02 6E 02 6E 02 6E 02 6E 02 6E 02 6E 02 6E 02 6E 02 6E 02 6E 02
You clearly see that most of them contains the value 026E. Those leads directly to a "ret" instruction at absolute location 004BE, and all the commands pointing tho those can be treated as "not used".
I may start disassembling some of the smaller routines as soon I have tidying in the code. Maybe I could figure some of the internal variables.
There is also a similar list at 3060, but it does contain a lot of similar valuse for some of the "used" commands. I guess that table may be some kind of lookup about what kind of data should follow the command.