home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Share Gallery 1
/
share_gal_1.zip
/
share_gal_1
/
UT
/
UT240.ZIP
/
GRAFWK51.ZIP
/
AMST1512.ASM
next >
Wrap
Assembly Source File
|
1991-01-14
|
19KB
|
499 lines
COMMENT %
GRAPHIC WORKSHOP AMSTRAD 1512 SCREEN DRIVER
COPYRIGHT (C) 1990 MARCEL WARD + ALCHEMY MINDWORKS INC.
VERSION 1.1
This is a driver for use as a Amstrad 1512 loadable driver
for Graphic Workshop.
To generate a driver from this file, it must be assembled
to a binary file.
Written with A86 in mind - should carry over to MASM without
too much adjustment though.
%
VERSION EQU 1
SUBVERSION EQU 1
_A0FF EQU 6 ;STACK OFFSET
AMST_WIDE EQU 640
AMST_DEEP EQU 200
AMST_BYTES EQU 80
AMST_SCREENSEG EQU 0B800H
;THIS MACRO SELECTS A COLOUR PLANE
COLOURPLANE MACRO ;#1 AS AN ARGUMENT
MOV AL,#1
MOV DX,03DDH ;WRITE PLANE ADDRESS
OUT DX,AL ;SET COLOUR PLANE
#EM ;CHANGE TO ENDM FOR MASM COMPAT.
;THIS MACRO SELECTS THE PLANE FROM WHICH SCREEN MEMORY READS ARE TAKEN
READPLANE MACRO
MOV AL,#1
MOV DX,03DEH
OUT DX,AL
#EM
CODE SEGMENT PARA PUBLIC 'CODE'
ASSUME CS:CODE
ORG 0000H
DB 'ALCHDRV2' ;SIGNATURE - DON'T CHANGE THIS
;THE FOLLOWING ARE THE POINTERS TO THE CALLABLE ROUTINES AND THE COMMON
;DATA. THE SEGMENTS ARE FILLED IN BY GWS.
DISPATCH PROC FAR
DW A1512_ON ;FAR PTR TO 16 COLOUR MODE SELECT
DW ?
DW TRY256_LINE ;FAR PTR TO 256 > 16 COLOUR LINE
DW ?
DW A1512_OFF ;FAR PTR TO 16 COLR MODE DESELECT
DW ?
DW NOT_USED ;FAR POINTER TO DUMMY PROC
DW ?
DW NOT_USED
DW ?
DW A1512_ON ;FAR POINTER TO 1512 MODE SELECT
DW ?
DW A1512_LINE ;FAR POINTER TO 1512 LINE DISPLAY
DW ?
DW A1512_OFF ;FAR POINTER TO 1512 MODE DESELECT
DW ?
DW A1512_PALETTE ;FAR POINTER TO NON-EXISTENT 1512
DW ? ;PALLETE SET!
DW HICGA_ON ;FAR POINTER TO CGA MODE SELECT
DW ?
DW HICGA_FRAME ;FAR POINTER TO CGA FRAME SELECT
DW ?
DW HICGA_LINE ;FAR POINTER TO CGA LINE DISPLAY
DW ?
DW HICGA_OFF ;FAR POINTER TO CGA MODE DESELECT
DW ?
DW 0,0 ;NULL ONE
DW 0,0 ;NULL TWO
DW 0,0 ;NULL THREE
DW 0,0 ;NULL FOUR
A_256WIDE DW AMST_WIDE
A_256DEEP DW AMST_DEEP
A_256SCRNSEG DW AMST_SCREENSEG
A_1512WIDE DW AMST_WIDE ;640
A_1512DEEP DW AMST_DEEP ;200
A_1512BYTES DW AMST_BYTES ;80
A_1512SCRNSEG DW AMST_SCREENSEG ;0b800
A_MONOWIDE DW AMST_WIDE
A_MONODEEP DW AMST_DEEP
A_MONOBYTES DW AMST_BYTES
A_MONOSCRNSEG DW AMST_SCREENSEG
;VERSION NUMBERS FOLLOW. YOU CAN CHANGE THE SUBVERSION NUMBER TO REFLECT
;CHANGES IN YOUR DRIVER ITSELF. THE VERSION VALUE MUST REMAIN UNCHANGED.
DW VERSION
DW SUBVERSION
;THE DESCRIPTION APPEARS IN THE F10 "ABOUT" BOX IN GRAPHIC WORKSHOP WHEN
;AN EXTERNAL DRIVER IS BEING USED. IT CAN'T EXCEED 24 CHARACTERS AND MUST
;BE NULL TERMINATED
DB 'Amstrad 16 col 640x200 ',0
DISPATCH ENDP
;THIS ROUTINE DISPLAYS A COLOUR-FUDGED 16 COLOUR LINE USING THE AMSTRAD
;SPECIFIC 16 COLOUR MODE FROM A 256 COLOUR LINE IN MEMORY. EXPECT TO SEE
;INCORRECT COLOURS APPEAR. SOME COLOURS WHICH APPEARED AS DARK COLOURS
;ON A 256 COLOUR SCREEN MAY NOT COME OUT AT ALL IN 16 COLOURS.
;A FULL SCREEN DISPLAYS IN ABOUT 10 SECONDS - THIS IS AS FAST AS I COULD
;GET IT BECAUSE OF THE ABSENCE OF USING COMMANDS SUCH AS REPNE MOVSB.
;AS I AM RELATIVELY NEW TO MACHINE CODE, HOWEVER, I DO NOT KNOW ALL OF
;THE COMMANDS AND WOULD WELCOME ANY ALTERATIONS TO A MORE EFFICIENT CODE.
;THE FIRST ARGUMENT ON THE STACK (2 WORDS) IS A FAR POINTER TO
;THE LINE. THE SECOND ARGUMENT IS THE LENGTH OF THE LINE IN PIXELS
TRY256_LINE PROC NEAR
PUSH BP
MOV BP,SP
PUSH DS
PUSH ES
MOV SI,[BP + _A0FF + 0] ;OFFSET OF SOURCE
MOV DS,[BP + _A0FF + 2] ;SEGMENT OF SOURCE
MOV BX,[BP + _A0FF + 6] ;GET LINE NUMBER
CMP BX,AMST_DEEP
JGE SHOW256X ;RESTORE REGISTERS AND EXIT
SHL BX,1
MOV DI,CS:[SCREENTABLE+BX]
CLD
MOV CX,[BP + _A0FF + 4];LENGTH OF MOVE IN BYTES
CMP CX,0
JE SHOW256X ;CHECK FOR NASTIES
CMP CX,AMST_WIDE
JL SHOW256A
MOV CX,AMST_WIDE
SHOW256A: MOV AX,AMST_SCREENSEG
MOV ES,AX
PUSH DI ;SCREENTABLE
PUSH SI ;OFFSET OF SOURCE
PUSH CX ;WIDTH OF LINE
;PLANE 8
COLOURPLANE 8
READPLANE 3
MOV AL,080H ;BIT TO CONTROL
PLANE8_REPEAT: MOV AH,DS:[SI] ;GET PIXEL
AND AH,08 ;ONLY WORRY ABOUT 4th BIT
JZ PLANE8_OFF
OR ES:[DI],AL ;TURN BIT ON
JMP PLANE8_DONE
PLANE8_OFF: NOT AL
AND ES:[DI],AL ;TURN BIT OFF
NOT AL
PLANE8_DONE: INC SI
SHR AL,1
JNZ PLANE8_BITOK
MOV AL,080H
INC DI
PLANE8_BITOK: LOOP PLANE8_REPEAT ;IF NOT FINISHED
POP CX
POP SI
POP DI
JMP PLANE4JMP
SHOW256X: POP ES
POP DS
POP BP
RETF
;PLANE 4
PLANE4JMP: PUSH DI ;SCREENTABLE
PUSH SI ;OFFSET OF SOURCE
PUSH CX ;WIDTH OF LINE
COLOURPLANE 4
READPLANE 2
MOV AL,080H ;BIT TO CONTROL
PLANE4_REPEAT: MOV AH,DS:[SI] ;GET PIXEL
AND AH,04 ;ONLY WORRY ABOUT 4th BIT
JZ PLANE4_OFF
OR ES:[DI],AL ;TURN BIT ON
JMP PLANE4_DONE
PLANE4_OFF: NOT AL
AND ES:[DI],AL
NOT AL
PLANE4_DONE: INC SI
SHR AL,1
JNZ PLANE4_BITOK
MOV AL,080H
INC DI
PLANE4_BITOK: LOOP PLANE4_REPEAT ;IF NOT FINISHED
POP CX
POP SI
POP DI
;PLANE 2
PUSH DI ;SCREENTABLE
PUSH SI ;OFFSET OF SOURCE
PUSH CX ;WIDTH OF LINE
COLOURPLANE 2
READPLANE 1
MOV AL,080H ;BIT TO CONTROL
PLANE2_REPEAT: MOV AH,DS:[SI] ;GET PIXEL
AND AH,02 ;ONLY WORRY ABOUT 2nd BIT
JZ PLANE2_OFF
OR ES:[DI],AL ;TURN BIT ON
JMP PLANE2_DONE
PLANE2_OFF: NOT AL
AND ES:[DI],AL
NOT AL
PLANE2_DONE: INC SI
SHR AL,1
JNZ PLANE2_BITOK
MOV AL,080H
INC DI
PLANE2_BITOK: LOOP PLANE2_REPEAT ;IF NOT FINISHED
POP CX
POP SI
POP DI
;PLANE 1
COLOURPLANE 1
READPLANE 0
MOV AL,080H ;BIT TO CONTROL
PLANE1_REPEAT: MOV AH,DS:[SI] ;GET PIXEL
AND AH,01 ;ONLY WORRY ABOUT LAST BIT
JZ PLANE1_OFF
OR ES:[DI],AL ;TURN BIT ON
JMP PLANE1_DONE
PLANE1_OFF: NOT AL
AND ES:[DI],AL
NOT AL
PLANE1_DONE: INC SI
SHR AL,1
JNZ PLANE1_BITOK
MOV AL,080H
INC DI
PLANE1_BITOK: LOOP PLANE1_REPEAT ;IF NOT FINISHED
JMP SHOW256X ;ROUND UP
TRY256_LINE ENDP
;THIS ROUTINE SELECTS THE AMSTRAD 16 COLOUR MODE
;THE HEIGHT AND WIDTH OF THE IMAGE ARE ON THE STACK - THESE
;MAY BE USEFUL IF YOU WANT TO PICK ONE OF SEVERAL AVAILABLE
;MODES BASED ON THE AREA OF THE PICTURE TO BE DISPLAYED
A1512_ON PROC NEAR
MOV AX,0006H
INT 10H
MOV DX,03D9H
MOV AL,0FH
OUT DX,AL
RETF
A1512_ON ENDP
;THIS ROUTINE DISPLAYS AN AMSTRAD LINE
;THE FIRST ARGUMENT ON THE STACK (2 WORDS) IS A FAR POINTER TO
;THE LINE. THE SECOND ARGUMENT IS THE LENGTH OF THE LINE IN BYTES
A1512_LINE PROC NEAR
PUSH BP
MOV BP,SP
PUSH DS
PUSH ES
MOV SI,[BP + _A0FF + 0] ;OFFSET OF SOURCE
MOV DS,[BP + _A0FF + 2] ;SEGMENT OF SOURCE
MOV BX,[BP + _A0FF + 6] ;GET LINE NUMBER
CMP BX,AMST_DEEP
JGE SHOWAMSTX
SHL BX,1
MOV DI,CS:[SCREENTABLE+BX]
MOV AX,AMST_SCREENSEG
MOV ES,AX
MOV BX,[BP + _A0FF + 4] ;LENGTH OF MOVE IN BYTES
MOV CX,BX
COLOURPLANE 1
CLD
PUSH DI
REPNE MOVSB
POP DI
MOV CX,BX
COLOURPLANE 2
PUSH DI
REPNE MOVSB
POP DI
MOV CX,BX
COLOURPLANE 4
PUSH DI
REPNE MOVSB
POP DI
MOV CX,BX
COLOURPLANE 8
PUSH DI
REPNE MOVSB
POP DI
;COLOURPLANE 0FH NOT NEEDED HERE
SHOWAMSTX: POP ES
POP DS
POP BP
RETF
AMST_LINE ENDP
A1512_OFF PROC NEAR
MOV AX,0003H
INT 10H
RETF
A1512_OFF ENDP
A1512_PALETTE PROC NEAR
RETF
A1512_PALETTE ENDP
HICGA_ON PROC NEAR
MOV AX,0006H
INT 10H
RETF
HICGA_ON ENDP
UPDATE_MOVE EQU 2
UPDATE_PAD EQU 4
UPDATE_ADJUST EQU 6
;THIS ROUTINE DISPLAYS A FULL MONOCHROME PAGE
;THE FIRST ARGUMENT ON THE STACK IS A FAR POINTER TO THE PAGE
;THE SECOND ARGUMENT IS THE WIDTH OF THE BITMAP (IN BYTES)
;THE THIRD ARGUMENT IS THE NUMBER OF LINES TO DISPLAY
;NOTE : THE SOURCE BUFFER MAY BE GREATER THAN 64K
HICGA_FRAME PROC NEAR
PUSH BP
MOV BP,SP
SUB SP,UPDATE_ADJUST
PUSH DS
PUSH ES
MOV AX,AMST_SCREENSEG ;POINT TO THE SCREEN
MOV ES,AX
MOV AX,[BP + _A0FF + 4] ;GET THE WIDTH OF MOVE
MOV [BP - UPDATE_MOVE],AX ;SAVE IT LOCALLY
MOV WORD PTR [BP-UPDATE_PAD],0 ;SET ADJUSTMENT
CMP AX,AMST_BYTES ;IF THE MOVE IS LESS THAN
JL UPDATE0 ;SCREEN WIDTH, GO FOR IT
SUB AX,AMST_BYTES ;ELSE, SET MOVE WIDTH
MOV [BP-UPDATE_PAD],AX ;...AND THE AMOUNT TO
MOV AX,AMST_BYTES ;...ADJUST THE POINTER
MOV [BP-UPDATE_MOVE],AX ;..AFTER EACH LINE
UPDATE0: MOV SI,[BP+ _A0FF + 0] ;OFFSET OF BITMAP
MOV DS,[BP+ _A0FF + 2] ;SEGMENT OF BITMAP
MOV CX,[BP+ _A0FF + 6] ;NUMBER OF LINES
CLD
SUB BX,BX
UPDATE1: PUSH CX ;SAVE COUNT (LINE NUMBER)
MOV DI,CS:[SCREENTABLE + BX]
ADD BX,2 ;POINT TO THE NEXT LINE
MOV CX,[BP - UPDATE_MOVE] ;GET THE MOVE SIZE
REPNE MOVSB ;DO THE MOVE
ADD SI,[BP-UPDATE_PAD] ;ADJUST THE POINTER
CMP SI,0F800H ;ARE WE WITHIN 2K OF THE TOP?
JL UPDATE2 ;IF NOT, CARRY ON
MOV AX,SI ;SEE HOW MANY SEGMENTS ARE IN
MOV CL,4 ;...SI (SI DIV 4)
SHR AX,CL
MOV CX,DS ;ADD THEM TO DATA SEGMENT
ADD CX,AX ;...(YOU CAN'T JUST ADD DS,AX)
MOV DS,CX
AND SI,000FH ;ADJUST SI (SI MOD 16)
UPDATE2: POP CX ;GET COUNT BACK
LOOP UPDATE1 ;DECREMENT AND LOOP
POP ES
POP DS
ADD SP,UPDATE_ADJUST
POP BP
RETF
HICGA_FRAME ENDP
;THIS ROUTINE DISPLAYS A SINGLE MONOCHROME LINE
;THE FIRST ARGUMENT ON THE STACK IS A FAR POINTER TO THE LINE
;THE SECOND ARGUMENT IS THE LINE NUMBER
;THE THIRD ARGUMENT IS THE WIDTH OF THE BITMAP (IN BYTES)
HICGA_LINE PROC NEAR
PUSH BP
MOV BP,SP
PUSH DS
PUSH ES
MOV AX,AMST_SCREENSEG ;POINT TO THE SCREEN
MOV ES,AX
MOV CX,[BP+ _A0FF + 6] ;SET THE WIDTH OF MOVE
CMP CX,0
JE MONO_LINE2
CMP CX,AMST_BYTES
JL MONO_LINE1
MOV CX,AMST_BYTES
MONO_LINE1: MOV SI,[BP + _A0FF + 0] ;OFFSET OF BITMAP
MOV DS,[BP + _A0FF + 2] ;SEGMENT OF BITMAP
MOV BX,[BP + _A0FF + 4] ;GET LINE NUMBER
SHL BX,1
CLD ;CLEAR DIRECTION FLAG
MOV DI,CS:[SCREENTABLE +BX]
REPNE MOVSB ;DO THE MOVE
MONO_LINE2: POP ES
POP DS
POP BP
RETF
HICGA_LINE ENDP
HICGA_OFF PROC NEAR
MOV AX,0003H
INT 10H
SUB AX,AX
RETF
MONO_OFF ENDP
NOT_USED PROC NEAR
RETF ;EXIT IMMEDIATELY
NOT_USED ENDP
;THIS IS A LINE START LOOKUP TABLE
;I FIND THIS IS A BETTER WAY TO STORE THE TABLE WITH THE AMSTRAD AS IT
;DOES NOT CHANGE AT ALL AS CGA>EGA>VGA TABLES MIGHT. YOU MIGHT, HOWEVER,
;WANT TO DO AWAY WITH THIS AND SAVE A BIT OF VALUABLE SPACE?
SCREENTABLE dw 00,02000,050,02050, 0a0,020a0,0f0,020f0
dw 0140,02140,0190,02190, 01e0,021e0,0230,02230
dw 0280,02280,02d0,022d0, 0320,02320,0370,02370
dw 03c0,023c0,0410,02410, 0460,02460,04b0,024b0
dw 0500,02500,0550,02550, 05a0,025a0,05f0,025f0
dw 0640,02640,0690,02690, 06e0,026e0,0730,02730
dw 0780,02780,07d0,027d0, 0820,02820,0870,02870
dw 08c0,028c0,0910,02910, 0960,02960,09b0,029b0
dw 0a00,02a00,0a50,02a50, 0aa0,02aa0,0af0,02af0
dw 0b40,02b40,0b90,02b90, 0be0,02be0,0c30,02c30
dw 0c80,02c80,0cd0,02cd0, 0d20,02d20,0d70,02d70
dw 0dc0,02dc0,0e10,02e10, 0e60,02e60,0eb0,02eb0
dw 0f00,02f00,0f50,02f50, 0fa0,02fa0,0ff0,02ff0
dw 01040,03040,01090,03090, 010e0,030e0,01130,03130
dw 01180,03180,011d0,031d0, 01220,03220,01270,03270
dw 012c0,032c0,01310,03310, 01360,03360,013b0,033b0
dw 01400,03400,01450,03450, 014a0,034a0,014f0,034f0
dw 01540,03540,01590,03590, 015e0,035e0,01630,03630
dw 01680,03680,016d0,036d0, 01720,03720,01770,03770
dw 017c0,037c0,01810,03810, 01860,03860,018b0,038b0
dw 01900,03900,01950,03950, 019a0,039a0,019f0,039f0
dw 01a40,03a40,01a90,03a90, 01ae0,03ae0,01b30,03b30
dw 01b80,03b80,01bd0,03bd0, 01c20,03c20,01c70,03c70
dw 01cc0,03cc0,01d10,03d10, 01d60,03d60,01db0,03db0
dw 01e00,03e00,01e50,03e50, 01ea0,03ea0,01ef0,03ef0
CODE ENDS
END