PDA

View Full Version : IBM PGC- RM callable driver, and probably why it never caught on...



BrianS
October 12th, 2013, 06:32 AM
"Back in the Day", the IBM Professional Graphics Controller was the high-end graphics card, offering 640x480 with 256 colors. It had it's own processor (8088 10MHz? I forget the exact version), memory, and communicated with the PC using shared memory arranged as queues. The shared memory was a problem for using the card in 80286 machines and faster- lots up problems with the values taking hold. I managed to get it working with a Compaq 385/25- but after that, I ended up turning a Zenith 241 into a dedicated PGC server, used the printer port for two-way communications between the faster computer and the card. I switched over to the Orchid Turbo-PGA, a 16-bit version that was command and interface compatible.

SO- here is the working driver for a 386 computer. I ended up doing many read/write/verify/retry operations to get a command to take. An error meant the Queue would be put of phase, and the controller would need to be restarted.

TITLE PGCWRT: RM FORTRAN PGC WRITE.
NAME PGCWRT
; SUBROUTINE PGCWRT( COMAND)
; DATE: SEPTEMBER 4, 1988
; THIS IS AN RM FORTRAN SUBROUTINE WHICH SENDS A COMMAND TO THE PGC
; CARD AT ADDRESS C600.
; COMAND IS A CHARACTER STRING. ES:BX POINTS TO THE CHARACTER DESCRIPTER
; ON ENTRY. THE DESCRIPTER IS IN THE FORM
; --------------------
; | LENGTH (2 BYTES) |
; ====================
; | CHARACTER |
; | ADDRESS (4 BYTES)|
; --------------------
;
;
;
;
DSCRPT EQU 0 ; OFFSET INTO ARGUMENT LIST OF CHARACTER DESCRIPTER.
FIFOSG EQU 0C600H ; PGC FIFO SEGMENT.
PNTRSG EQU 0C630H ; PGC POINTER SEGMENT.
SZFIFO EQU 0100H ; PGC FIFO SIZES.
OUTSEG EQU 0C600H ; OUTPUT FIFO SEGMENT (FOR WRITES TO THE PGC).
INPSEG EQU 0C610H ; INPUT FIFO SEGMENT (FOR READING FROM THE PGC).
ERRSEG EQU 0C620H ; ERROR FIFO SEGMENT.
MXFIFO EQU SZFIFO- 1 ; MAX FIFO ADDRESS.
; POINTERS OFFSETS ARE FROM THE BASE OF THE PGC, NOT FROM PNTRSG.
OWRPTR EQU 0300H ; OUTPUT WRITE POINTER. (WHERE TO WRITE DATA TO FIFO)
ORDPTR EQU 0301H ; OUTPUT READ POINTER. (WHERE THE PGC IS READING FROM)
IWRPTR EQU 0302H ; INPUT WRITE POINTER.
IRDPTR EQU 0303H ; INPUT READ POINTER.
EWRPTR EQU 0304H ; ERROR WRITE POINTER.
ERDPTR EQU 0305H ; ERROR READ POINTER.
CLDRST EQU 0306H ; COLD RESTART.
WRMRST EQU 0307H ; WARM RESTART.
ERNABL EQU 0308H ; ERROR ENABLE.
DATA SEGMENT
; 14 BYTES NEEDED FOR RM TRACEBACK.
DB 'PGCWRT ' ; 8 BYTES FOR ROUTINE NAME.
SPSAVE DW ? ; 2 BYTES FOR STACKPOINTER SAVE AREA.
DD PGCBGN ; 4 BYTE ADDRESS FOR BEGINNING OF CODE.
DD 0 ; DEBUG POINTER, FOR T OPTION.
; LOCAL DATA DECLARATIONS MAY GO HERE.
DATA ENDS
CODE SEGMENT
PGCBGN PROC FAR
ASSUME CS:CODE,DS: DATA,ES:NOTHING,SS:NOTHING
PUBLIC PGCWRT ; DECLARE PGCWRT AS PUBLIC, I.E. EXERNAL.
DW SEG DATA ; NEEDED FOR T OPTION.
PGCWRT LABEL FAR
; LOCAL TEMPS ARE NOT ALLOCATED FROM THE STACK. BRIEF PROLOG USED.
PUSH DS ; SAVE DATA SEGMENT.
MOV AX,DATA ; LOAD DATA SEGMENT WITH LOCAL DATA.
MOV DS,AX
MOV SPSAVE,SP ; SAVE THE STACK POINTER.
; ES:BX POINT TO THE ARGUMENT LIST.
; BODY OF ROUTINE.
; GET ADDRESS OF THE DESCRIPTER.
LES BX,DWORD PTR ES:[BX+DSCRPT] ; GET ADDRESS OF DESCRIPTER.
MOV CX,WORD PTR ES:[BX] ; LOAD LENGTH OF STRING.
; RETURN IF THE NULL STRING, LENGTH .LE. 0.
CMP CX,0
JG GOPGC
RET
GOPGC LABEL NEAR
LES SI,DWORD PTR ES:[BX+2] ; GET ADDRESS OF STRING TO ES:SI.
MOV AX,FIFOSG ; GET FIFO SEGMENT.
MOV DS,AX
REREAD LABEL NEAR
MOV AL,BYTE PTR DS:[OWRPTR] ; GET THE HEAD POINTER.
XOR AH,AH ; CLEAR AH
MOV DL,BYTE PTR DS:[OWRPTR] ; GET THE HEAD POINTER AGAIN
CMP DL,AL
JNE REREAD
MOV DL,BYTE PTR DS:[OWRPTR] ; GET THE HEAD POINTER AGAIN
CMP DL,AL
JNE REREAD
MOV DL,BYTE PTR DS:[OWRPTR] ; GET THE HEAD POINTER AGAIN
CMP DL,AL
JNE REREAD
MOV DL,BYTE PTR DS:[OWRPTR] ; GET THE HEAD POINTER AGAIN
CMP DL,AL
JNE REREAD
MOV DL,BYTE PTR DS:[OWRPTR] ; GET THE HEAD POINTER AGAIN
CMP DL,AL
JNE REREAD
MOV DL,BYTE PTR DS:[OWRPTR] ; GET THE HEAD POINTER AGAIN
CMP DL,AL
JNE REREAD
;
SENDTA LABEL NEAR
MOV DI,AX ; COPY HEAD TO DESTINATION INDEX.
INC AL ; HEAD= HEAD+ 1
XOR AH,AH ; CLEAR AH
RETRY LABEL NEAR
MOV DL,BYTE PTR DS:[ORDPTR] ; GET THE READ POINTER.
MOV DH,BYTE PTR DS:[ORDPTR] ; GET THE READ POINTER.
CMP DH,DL
JNE RETRY
; RETRY: CHECK FOR MEMORY READ PROBLEMS ON PGC.
MOV DH,BYTE PTR DS:[ORDPTR] ; GET THE READ POINTER.
CMP DH,DL
JNE RETRY
MOV DH,BYTE PTR DS:[ORDPTR] ; GET THE READ POINTER.
CMP DH,DL
JNE RETRY
MOV DH,BYTE PTR DS:[ORDPTR] ; GET THE READ POINTER.
CMP DH,DL
JNE RETRY
MOV DH,BYTE PTR DS:[ORDPTR] ; GET THE READ POINTER.
CMP DH,DL
JNE RETRY
MOV DH,BYTE PTR DS:[ORDPTR] ; GET THE READ POINTER.
CMP DH,DL
JNE RETRY
MOV DH,BYTE PTR DS:[ORDPTR] ; GET THE READ POINTER.
CMP DH,DL
JNE RETRY
CMP AL,DL ; IF HEAD+ 1=TAIL, LOOP.
JE RETRY
;
RESEND LABEL NEAR
MOV DH,BYTE PTR ES:[SI] ; GET NEXT BYTE OF CHARACTER.
MOV DS:[DI],DH ; SEND THE BYTE.
MOV DL,DS:[DI] ; CHECK THAT IT GOT THERE.
CMP DL,DH
JNE RESEND
MOV DL,DS:[DI] ; CHECK THAT IT GOT THERE.
CMP DL,DH
JNE RESEND
MOV DL,DS:[DI] ; CHECK THAT IT GOT THERE.
CMP DL,DH
JNE RESEND
MOV DL,DS:[DI] ; CHECK THAT IT GOT THERE.
CMP DL,DH
JNE RESEND
MOV DL,DS:[DI] ; CHECK THAT IT GOT THERE.
CMP DL,DH
JNE RESEND
MOV DL,DS:[DI] ; CHECK THAT IT GOT THERE.
CMP DL,DH
JNE RESEND
MOV DL,DS:[DI] ; CHECK THAT IT GOT THERE.
CMP DL,DH
JNE RESEND
RESND2 LABEL NEAR
MOV BYTE PTR DS:[OWRPTR],AL ; UPDATE WRITE POINTER.
MOV DL,BYTE PTR DS:[OWRPTR] ; CHECK WRITE POINTER.
CMP DL,AL
JNE RESND2
MOV DL,BYTE PTR DS:[OWRPTR] ; CHECK WRITE POINTER.
CMP DL,AL
JNE RESND2
MOV DL,BYTE PTR DS:[OWRPTR] ; CHECK WRITE POINTER.
CMP DL,AL
JNE RESND2
MOV DL,BYTE PTR DS:[OWRPTR] ; CHECK WRITE POINTER.
CMP DL,AL
JNE RESND2
MOV DL,BYTE PTR DS:[OWRPTR] ; CHECK WRITE POINTER.
CMP DL,AL
JNE RESND2
MOV DL,BYTE PTR DS:[OWRPTR] ; CHECK WRITE POINTER.
CMP DL,AL
JNE RESND2
MOV DL,BYTE PTR DS:[OWRPTR] ; CHECK WRITE POINTER.
CMP DL,AL
JNE RESND2
;
INC SI ; POINT TO NEXT BYTE.
DEC CX ; DEC BYTE COUNTER.
JZ ENDPGC
JMP SENDTA ; LOOP FOR NEXT BYTE.
;
; END ROUTINE
ENDPGC LABEL NEAR
POP DS
RET
PGCBGN ENDP
CODE ENDS
;
STACK SEGMENT WORD STACK 'STACK'
STAKSZ EQU 0
IF STAKSZ > 0
DB STAKSZ DUP (?)
ENDIF
STACK ENDS
END


Years of use and custom code, including a lot of animated computer models and image processing done with this card.

If you find one, it should work properly on an XT class machine without problem. Later computers- be aware of the issue. If anyone has one, and wants some graphics software for it- let me know. It's in RM FORTRAN and Assembly.

mikey99
October 12th, 2013, 07:25 AM
Hi, thanks for the great info on the PGC ! I have one of the IBM PGC/PGD setups , not currently hooked up but it was working last time
I used it. I'd like to get a copy of any software you have for this card. I worked in a PC lab many years ago and one of the engineers
purchased a PGC/PGD for the lab. I recall it had some included demo software that displayed hi-res images. I have the driver diskette
but have not been able to locate any of the demo diskettes. I think there was even a developers kit or something that included libraries
etc for writing software for the PGC.