Files
hovertank_3d/IDASME.ASM
T
2026-07-14 19:31:07 +02:00

1653 lines
36 KiB
NASM

; Hovertank 3-D Source Code
; Copyright (C) 1993-2014 Flat Rock Software
;
; This program is free software; you can redistribute it and/or modify
; it under the terms of the GNU General Public License as published by
; the Free Software Foundation; either version 2 of the License, or
; (at your option) any later version.
;
; This program is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
; GNU General Public License for more details.
;
; You should have received a copy of the GNU General Public License along
; with this program; if not, write to the Free Software Foundation, Inc.,
; 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
IDEAL
MODEL SMALL,C
include "GRAPHHOV.EQU"
;============================================================================
;
; EGA Graphic routines
;
;============================================================================
SC_INDEX = 03C4h
SC_RESET = 0
SC_CLOCK = 1
SC_MAPMASK = 2
SC_CHARMAP = 3
SC_MEMMODE = 4
CRTC_INDEX = 03D4h
CRTC_H_TOTAL = 0
CRTC_H_DISPEND = 1
CRTC_H_BLANK = 2
CRTC_H_ENDBLANK = 3
CRTC_H_RETRACE = 4
CRTC_H_ENDRETRACE = 5
CRTC_V_TOTAL = 6
CRTC_OVERFLOW = 7
CRTC_ROWSCAN = 8
CRTC_MAXSCANLINE = 9
CRTC_CURSORSTART = 10
CRTC_CURSOREND = 11
CRTC_STARTHIGH = 12
CRTC_STARTLOW = 13
CRTC_CURSORHIGH = 14
CRTC_CURSORLOW = 15
CRTC_V_RETRACE = 16
CRTC_V_ENDRETRACE = 17
CRTC_V_DISPEND = 18
CRTC_OFFSET = 19
CRTC_UNDERLINE = 20
CRTC_V_BLANK = 21
CRTC_V_ENDBLANK = 22
CRTC_MODE = 23
CRTC_LINECOMPARE = 24
GC_INDEX = 03CEh
GC_SETRESET = 0
GC_ENABLESETRESET = 1
GC_COLORCOMPARE = 2
GC_DATAROTATE = 3
GC_READMAP = 4
GC_MODE = 5
GC_MISCELLANEOUS = 6
GC_COLORDONTCARE = 7
GC_BITMASK = 8
ATR_INDEX = 03c0h
ATR_MODE = 16
ATR_OVERSCAN = 17
ATR_COLORPLANEENABLE = 18
ATR_PELPAN = 19
ATR_COLORSELECT = 20
SCREENWIDTH equ 40
;
; offsets into sprite/pictable
;
PICWIDTHOFS equ 0
PICHEIGHTOFS equ 2
DATASEG
screenseg dw 0a000h
otherseg dw 0
screenofs dw 0
screenorigin dw 0
planemask dw 0
planecount dw 0
linewidth dw 0
PUBLIC screenseg,screenofs,screenorigin,otherseg,linewidth
EXTRN pictable:WORD
EXTRN spritetable:WORD
EXTRN grsegs:WORD ; master location table for all graphics
ylookup dw 256 dup (?)
PUBLIC ylookup
;============================================================================
CODESEG
;============================================================================
MACRO WORDOUT
out dx,al
inc dx
xchg al,ah
out dx,al
dec dx
xchg al,ah
ENDM
;====================
;
; EGAplane
; Sets read/write mode 0 and selects the given plane (0-3)
; for reading and writing
;
;====================
PROC EGAplane plane:WORD
PUBLIC EGAplane
cli
mov dx,GC_INDEX
mov ax,GC_MODE
WORDOUT ;set read / write mode 0
mov dx,GC_INDEX
mov al,4 ;read map select
mov ah,[BYTE plane] ;read from this plane number
out dx,ax
mov dx,SC_INDEX
mov al,SC_MAPMASK
mov ah,1
mov cl,[BYTE plane] ;write to this plane only
shl ah,cl
WORDOUT
sti
ret
ENDP
;==============
;
; SetScreen
;
;==============
;
; EGA registers
;
HPELPAN equ 20h or 13h
PROC SetScreen crtc:WORD, pel:WORD
PUBLIC SetScreen
;
; set the CRTC start registers for the screen just drawn
;
; wait for no display enable and no vertical sync, so the raster is in a
; horizontal sync, not on the last line!
cli
mov dx,CRTC_INDEX+6
@@waitnovbl:
in al,dx
test al,00001000b
jnz @@waitnovbl ;vertical syncing now
or al,1
jz @@waitnovbl ;in the middle of a scan line
mov cx,[crtc]
mov dx,3d4h ;CRTC address register
mov al,0ch ;start address high register
out dx,al
inc dx
mov al,ch
out dx,al ;set the high byte
dec dx
mov al,0dh ;start address low register
out dx,al
inc dx
mov al,cl
out dx,al ;set the low byte
sti
mov dx,CRTC_INDEX+6
@@waitvbl:
in al,dx
test al,00001000b ;look for vertical retrace
jz @@waitvbl
;
; set horizontal panning
;
cli
mov bx,[pel]
mov dx,CRTC_INDEX+6
in al,dx
mov dx,ATR_INDEX
mov al,HPELPAN
out dx,al
mov ax,bx ;pel pan value
out dx,al
sti
ret
ENDP
;=============
;
; XorBar
;
; xcoord in bytes, ycoord in pixels
;
;=============
PROC XorBar xl:WORD, yl:WORD, wide:WORD, height:WORD
USES SI,DI
PUBLIC XorBar
; set write mode 0
mov dx,GC_INDEX
mov ax,GC_MODE
WORDOUT
; set xor mode
mov ax,GC_DATAROTATE + 11000b * 256
WORDOUT
mov dx,[wide] ;bytes / line
mov ch,[BYTE height] ;lines
mov bx,[yl]
shl bx,1
mov di,[ylookup+bx]
add di,[screenofs]
add di,[xl]
mov es,[screenseg]
mov ah,0ffh
; ch = vertical loops
; cl = horizontal loops
@@vertloop:
mov cl,dl
xor bx,bx
@@horizloop:
mov al,[es:di+bx] ;load latches
mov [es:di+bx],ah ;xor in $ff
inc bx
dec cl
jnz @@horizloop
add di,SCREENWIDTH
dec ch
jnz @@vertloop
; set copy mode
mov dx,GC_INDEX
mov ax,GC_DATAROTATE
WORDOUT
; set mapmask to all
mov dx,SC_INDEX
mov ax,SC_MAPMASK + 15*256
WORDOUT
ret
ENDP
;=============
;
; XPlot
;
; Xdraws one point
;
;=============
PROC XPlot x:WORD, y:WORD, color:WORD
USES SI,DI
PUBLIC XPlot
; set write mode 0
mov dx,GC_INDEX
mov ax,GC_MODE
WORDOUT
; set xor mode
mov ax,GC_DATAROTATE + 11000b * 256
WORDOUT
; set mapmask to color
mov dx,SC_INDEX
mov al,SC_MAPMASK
mov ah,[BYTE color]
WORDOUT
; calculate screen location
mov bx,[y]
shl bx,1
mov di,[ylookup+bx]
add di,[screenofs]
mov ax,[x]
mov bx,ax
shr bx,1
shr bx,1
shr bx,1
add di,bx ; byte value of x
and ax,7
mov cx,7
sub cx,ax ; bit position
mov ax,100h
shl ax,cl ; high byte holds mask
; set bitmask to pixel
mov dx,GC_INDEX
mov al,GC_BITMASK
WORDOUT
mov es,[screenseg]
mov al,[es:di] ; load latches
mov [BYTE es:di],0ffh ; xor out 1s to active planes/bits
; set copy mode
mov dx,GC_INDEX
mov ax,GC_DATAROTATE
WORDOUT
; set mapmask to all
mov dx,SC_INDEX
mov ax,SC_MAPMASK + 15*256
WORDOUT
; set bitmask to pixel
mov dx,GC_INDEX
mov ax,GC_BITMASK + 255*256
WORDOUT
ret
ENDP
;=============
;
; DrawChar (int xcoord, int ycoord, int charnum)
;
; xcoord in bytes, ycoord in pixels
;
; Source is grsegs[STARTTILE8+charnum]
;
;=============
PROC DrawChar xcoord:WORD, ycoord:WORD, charnum:WORD
USES SI,DI
PUBLIC DrawChar
mov es,[screenseg]
mov di,[screenofs]
add di,[xcoord]
mov bx,[ycoord]
shl bx,1
add di,[ylookup+bx] ;screen destination
cld
mov bx,[linewidth]
dec bx
mov si,[charnum]
shl si,1
shl si,1
shl si,1
shl si,1
shl si,1
mov ds,[grsegs+STARTTILE8*2] ; segment for all tile8s
;
; start drawing
;
cli
mov dx,GC_INDEX ;set write mode 0
mov ax,GC_MODE
WORDOUT
sti
mov cx,4 ;planes to draw
mov [ss:planemask],0001b ;map mask
mov bx,6
@@planeloop:
cli
mov dx,SC_INDEX
mov al,SC_MAPMASK
mov ah,[BYTE ss:planemask]
shl [ss:planemask],1
WORDOUT
sti
mov dx,[ss:linewidth]
dec dx
dec bx
dec bx
push di
REPT 7
movsb
add di,dx
ENDM
movsb
pop di
loop @@planeloop
cli
mov dx,SC_INDEX
mov ax,SC_MAPMASK+15*256 ;write to all planes
WORDOUT
sti
mov ax,ss
mov ds,ax ;restore turbo's data segment
ret
ENDP
;=======================================================================
;============
;
; DrawPic (int xcoord, int ycoord, int picnum)
;
; xcoord in bytes, ycoord in pixels
;
;============
DATASEG
picwidth dw ?
picxcoord dw ?
picheight dw ?
picoffset dw ? ;offset into data planes
PUBLIC picoffset
CODESEG
PROC DrawPic xcoord:WORD, ycoord:WORD, picnum:WORD
USES SI,DI
PUBLIC DrawPic
mov si,[picnum]
shl si,1
shl si,1
mov ax,[pictable+si+PICWIDTHOFS]
mov [picwidth],ax
mov ax,[pictable+si+PICHEIGHTOFS]
mov [picheight],ax
mov es,[screenseg]
mov di,[screenofs]
add di,[xcoord]
mov bx,[ycoord]
shl bx,1
add di,[ylookup+bx] ;screen destination
cld
;
; start drawing
;
cli
mov dx,GC_INDEX ;set write mode 0
mov ax,GC_MODE
WORDOUT
sti
mov [planecount],3
mov [planemask],0001b ;map mask
mov si,[picnum]
shl si,1
mov ds,[grsegs+STARTPICS*2+si] ; segment of pictures (PARA'd)
xor si,si ; segment aligned
mov bx,6
@@planeloop:
cli
mov dx,SC_INDEX
mov al,SC_MAPMASK
mov ah,[BYTE ss:planemask]
shl [ss:planemask],1
WORDOUT
sti
mov dx,[ss:linewidth]
sub dx,[ss:picwidth]
mov bx,[ss:planecount]
shl bx,1
push di
mov bx,[ss:picheight]
@@lineloop:
mov cx,[ss:picwidth]
rep movsb
add di,dx
dec bx
jnz @@lineloop
pop di
dec [ss:planecount]
jns @@planeloop
cli
mov dx,SC_INDEX
mov ax,SC_MAPMASK+15*256 ;write to all planes
WORDOUT
sti
mov ax,ss
mov ds,ax ;restore turbo's data segment
ret
ret
ENDP
;============
;
; Bar (int xl,yl,width,height)
;
; xcoord in bytes, ycoord in pixels
;
;============
PROC Bar xl:WORD, yl:WORD, wide:WORD, height:WORD, fill:WORD
USES SI,DI
PUBLIC Bar
mov di,[screenofs]
mov bx,[yl]
shl bx,1
add di,[ylookup+bx]
add di,[xl]
mov es,[screenseg]
cld
cli ;no interrupts during EGA stuff!
mov dx,GC_INDEX
mov ax,GC_MODE ;write mode 0
WORDOUT
mov dx,SC_INDEX
mov ax,SC_MAPMASK+15*256
WORDOUT
sti
mov bx,[ss:linewidth]
sub bx,[wide]
mov al,[BYTE fill]
@@drawrow:
mov cx,[wide]
rep stosb
add di,bx
dec [height]
jnz @@drawrow
mov ax,ss
mov ds,ax ;restore turbo's data segment
ret
ENDP
;============
;
; CopyEGA
;
; Must be in latch mode
;
;============
PROC CopyEGA wide:WORD, height:WORD, source:word, dest:word
PUBLIC CopyEGA
USES SI,DI
mov ax,0a000h
mov ds,ax
mov es,ax
@@zapasprite:
;
; erase a sprite by copying a block from the master screen
;
mov ah,[BYTE wide] ;width of block
mov bx,[WORD height] ;height of block
mov di,[dest] ;destination to erase
mov si,[source]
mov dx,[ss:linewidth]
sub dl,ah
xor ch,ch
EVEN
@@clearloop:
mov cl,ah
rep movsb
add si,dx
add di,dx
dec bx
jnz @@clearloop
mov ax,ss
mov ds,ax ;restore ds
ret
ENDP
if NUMFONT+NUMFONTM
;===========================================================================
;
; SHIFT TABLES
;
;===========================================================================
DATASEG
LABEL shiftdata0 WORD
dw 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13
dw 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27
dw 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41
dw 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55
dw 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69
dw 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83
dw 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97
dw 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111
dw 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125
dw 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139
dw 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153
dw 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167
dw 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181
dw 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195
dw 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209
dw 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223
dw 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237
dw 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251
dw 252, 253, 254, 255
LABEL shiftdata1 WORD
dw 0,32768, 1,32769, 2,32770, 3,32771, 4,32772, 5,32773, 6,32774
dw 7,32775, 8,32776, 9,32777, 10,32778, 11,32779, 12,32780, 13,32781
dw 14,32782, 15,32783, 16,32784, 17,32785, 18,32786, 19,32787, 20,32788
dw 21,32789, 22,32790, 23,32791, 24,32792, 25,32793, 26,32794, 27,32795
dw 28,32796, 29,32797, 30,32798, 31,32799, 32,32800, 33,32801, 34,32802
dw 35,32803, 36,32804, 37,32805, 38,32806, 39,32807, 40,32808, 41,32809
dw 42,32810, 43,32811, 44,32812, 45,32813, 46,32814, 47,32815, 48,32816
dw 49,32817, 50,32818, 51,32819, 52,32820, 53,32821, 54,32822, 55,32823
dw 56,32824, 57,32825, 58,32826, 59,32827, 60,32828, 61,32829, 62,32830
dw 63,32831, 64,32832, 65,32833, 66,32834, 67,32835, 68,32836, 69,32837
dw 70,32838, 71,32839, 72,32840, 73,32841, 74,32842, 75,32843, 76,32844
dw 77,32845, 78,32846, 79,32847, 80,32848, 81,32849, 82,32850, 83,32851
dw 84,32852, 85,32853, 86,32854, 87,32855, 88,32856, 89,32857, 90,32858
dw 91,32859, 92,32860, 93,32861, 94,32862, 95,32863, 96,32864, 97,32865
dw 98,32866, 99,32867, 100,32868, 101,32869, 102,32870, 103,32871, 104,32872
dw 105,32873, 106,32874, 107,32875, 108,32876, 109,32877, 110,32878, 111,32879
dw 112,32880, 113,32881, 114,32882, 115,32883, 116,32884, 117,32885, 118,32886
dw 119,32887, 120,32888, 121,32889, 122,32890, 123,32891, 124,32892, 125,32893
dw 126,32894, 127,32895
LABEL shiftdata2 WORD
dw 0,16384,32768,49152, 1,16385,32769,49153, 2,16386,32770,49154, 3,16387
dw 32771,49155, 4,16388,32772,49156, 5,16389,32773,49157, 6,16390,32774,49158
dw 7,16391,32775,49159, 8,16392,32776,49160, 9,16393,32777,49161, 10,16394
dw 32778,49162, 11,16395,32779,49163, 12,16396,32780,49164, 13,16397,32781,49165
dw 14,16398,32782,49166, 15,16399,32783,49167, 16,16400,32784,49168, 17,16401
dw 32785,49169, 18,16402,32786,49170, 19,16403,32787,49171, 20,16404,32788,49172
dw 21,16405,32789,49173, 22,16406,32790,49174, 23,16407,32791,49175, 24,16408
dw 32792,49176, 25,16409,32793,49177, 26,16410,32794,49178, 27,16411,32795,49179
dw 28,16412,32796,49180, 29,16413,32797,49181, 30,16414,32798,49182, 31,16415
dw 32799,49183, 32,16416,32800,49184, 33,16417,32801,49185, 34,16418,32802,49186
dw 35,16419,32803,49187, 36,16420,32804,49188, 37,16421,32805,49189, 38,16422
dw 32806,49190, 39,16423,32807,49191, 40,16424,32808,49192, 41,16425,32809,49193
dw 42,16426,32810,49194, 43,16427,32811,49195, 44,16428,32812,49196, 45,16429
dw 32813,49197, 46,16430,32814,49198, 47,16431,32815,49199, 48,16432,32816,49200
dw 49,16433,32817,49201, 50,16434,32818,49202, 51,16435,32819,49203, 52,16436
dw 32820,49204, 53,16437,32821,49205, 54,16438,32822,49206, 55,16439,32823,49207
dw 56,16440,32824,49208, 57,16441,32825,49209, 58,16442,32826,49210, 59,16443
dw 32827,49211, 60,16444,32828,49212, 61,16445,32829,49213, 62,16446,32830,49214
dw 63,16447,32831,49215
LABEL shiftdata3 WORD
dw 0, 8192,16384,24576,32768,40960,49152,57344, 1, 8193,16385,24577,32769,40961
dw 49153,57345, 2, 8194,16386,24578,32770,40962,49154,57346, 3, 8195,16387,24579
dw 32771,40963,49155,57347, 4, 8196,16388,24580,32772,40964,49156,57348, 5, 8197
dw 16389,24581,32773,40965,49157,57349, 6, 8198,16390,24582,32774,40966,49158,57350
dw 7, 8199,16391,24583,32775,40967,49159,57351, 8, 8200,16392,24584,32776,40968
dw 49160,57352, 9, 8201,16393,24585,32777,40969,49161,57353, 10, 8202,16394,24586
dw 32778,40970,49162,57354, 11, 8203,16395,24587,32779,40971,49163,57355, 12, 8204
dw 16396,24588,32780,40972,49164,57356, 13, 8205,16397,24589,32781,40973,49165,57357
dw 14, 8206,16398,24590,32782,40974,49166,57358, 15, 8207,16399,24591,32783,40975
dw 49167,57359, 16, 8208,16400,24592,32784,40976,49168,57360, 17, 8209,16401,24593
dw 32785,40977,49169,57361, 18, 8210,16402,24594,32786,40978,49170,57362, 19, 8211
dw 16403,24595,32787,40979,49171,57363, 20, 8212,16404,24596,32788,40980,49172,57364
dw 21, 8213,16405,24597,32789,40981,49173,57365, 22, 8214,16406,24598,32790,40982
dw 49174,57366, 23, 8215,16407,24599,32791,40983,49175,57367, 24, 8216,16408,24600
dw 32792,40984,49176,57368, 25, 8217,16409,24601,32793,40985,49177,57369, 26, 8218
dw 16410,24602,32794,40986,49178,57370, 27, 8219,16411,24603,32795,40987,49179,57371
dw 28, 8220,16412,24604,32796,40988,49180,57372, 29, 8221,16413,24605,32797,40989
dw 49181,57373, 30, 8222,16414,24606,32798,40990,49182,57374, 31, 8223,16415,24607
dw 32799,40991,49183,57375
LABEL shiftdata4 WORD
dw 0, 4096, 8192,12288,16384,20480,24576,28672,32768,36864,40960,45056,49152,53248
dw 57344,61440, 1, 4097, 8193,12289,16385,20481,24577,28673,32769,36865,40961,45057
dw 49153,53249,57345,61441, 2, 4098, 8194,12290,16386,20482,24578,28674,32770,36866
dw 40962,45058,49154,53250,57346,61442, 3, 4099, 8195,12291,16387,20483,24579,28675
dw 32771,36867,40963,45059,49155,53251,57347,61443, 4, 4100, 8196,12292,16388,20484
dw 24580,28676,32772,36868,40964,45060,49156,53252,57348,61444, 5, 4101, 8197,12293
dw 16389,20485,24581,28677,32773,36869,40965,45061,49157,53253,57349,61445, 6, 4102
dw 8198,12294,16390,20486,24582,28678,32774,36870,40966,45062,49158,53254,57350,61446
dw 7, 4103, 8199,12295,16391,20487,24583,28679,32775,36871,40967,45063,49159,53255
dw 57351,61447, 8, 4104, 8200,12296,16392,20488,24584,28680,32776,36872,40968,45064
dw 49160,53256,57352,61448, 9, 4105, 8201,12297,16393,20489,24585,28681,32777,36873
dw 40969,45065,49161,53257,57353,61449, 10, 4106, 8202,12298,16394,20490,24586,28682
dw 32778,36874,40970,45066,49162,53258,57354,61450, 11, 4107, 8203,12299,16395,20491
dw 24587,28683,32779,36875,40971,45067,49163,53259,57355,61451, 12, 4108, 8204,12300
dw 16396,20492,24588,28684,32780,36876,40972,45068,49164,53260,57356,61452, 13, 4109
dw 8205,12301,16397,20493,24589,28685,32781,36877,40973,45069,49165,53261,57357,61453
dw 14, 4110, 8206,12302,16398,20494,24590,28686,32782,36878,40974,45070,49166,53262
dw 57358,61454, 15, 4111, 8207,12303,16399,20495,24591,28687,32783,36879,40975,45071
dw 49167,53263,57359,61455
LABEL shiftdata5 WORD
dw 0, 2048, 4096, 6144, 8192,10240,12288,14336,16384,18432,20480,22528,24576,26624
dw 28672,30720,32768,34816,36864,38912,40960,43008,45056,47104,49152,51200,53248,55296
dw 57344,59392,61440,63488, 1, 2049, 4097, 6145, 8193,10241,12289,14337,16385,18433
dw 20481,22529,24577,26625,28673,30721,32769,34817,36865,38913,40961,43009,45057,47105
dw 49153,51201,53249,55297,57345,59393,61441,63489, 2, 2050, 4098, 6146, 8194,10242
dw 12290,14338,16386,18434,20482,22530,24578,26626,28674,30722,32770,34818,36866,38914
dw 40962,43010,45058,47106,49154,51202,53250,55298,57346,59394,61442,63490, 3, 2051
dw 4099, 6147, 8195,10243,12291,14339,16387,18435,20483,22531,24579,26627,28675,30723
dw 32771,34819,36867,38915,40963,43011,45059,47107,49155,51203,53251,55299,57347,59395
dw 61443,63491, 4, 2052, 4100, 6148, 8196,10244,12292,14340,16388,18436,20484,22532
dw 24580,26628,28676,30724,32772,34820,36868,38916,40964,43012,45060,47108,49156,51204
dw 53252,55300,57348,59396,61444,63492, 5, 2053, 4101, 6149, 8197,10245,12293,14341
dw 16389,18437,20485,22533,24581,26629,28677,30725,32773,34821,36869,38917,40965,43013
dw 45061,47109,49157,51205,53253,55301,57349,59397,61445,63493, 6, 2054, 4102, 6150
dw 8198,10246,12294,14342,16390,18438,20486,22534,24582,26630,28678,30726,32774,34822
dw 36870,38918,40966,43014,45062,47110,49158,51206,53254,55302,57350,59398,61446,63494
dw 7, 2055, 4103, 6151, 8199,10247,12295,14343,16391,18439,20487,22535,24583,26631
dw 28679,30727,32775,34823,36871,38919,40967,43015,45063,47111,49159,51207,53255,55303
dw 57351,59399,61447,63495
LABEL shiftdata6 WORD
dw 0, 1024, 2048, 3072, 4096, 5120, 6144, 7168, 8192, 9216,10240,11264,12288,13312
dw 14336,15360,16384,17408,18432,19456,20480,21504,22528,23552,24576,25600,26624,27648
dw 28672,29696,30720,31744,32768,33792,34816,35840,36864,37888,38912,39936,40960,41984
dw 43008,44032,45056,46080,47104,48128,49152,50176,51200,52224,53248,54272,55296,56320
dw 57344,58368,59392,60416,61440,62464,63488,64512, 1, 1025, 2049, 3073, 4097, 5121
dw 6145, 7169, 8193, 9217,10241,11265,12289,13313,14337,15361,16385,17409,18433,19457
dw 20481,21505,22529,23553,24577,25601,26625,27649,28673,29697,30721,31745,32769,33793
dw 34817,35841,36865,37889,38913,39937,40961,41985,43009,44033,45057,46081,47105,48129
dw 49153,50177,51201,52225,53249,54273,55297,56321,57345,58369,59393,60417,61441,62465
dw 63489,64513, 2, 1026, 2050, 3074, 4098, 5122, 6146, 7170, 8194, 9218,10242,11266
dw 12290,13314,14338,15362,16386,17410,18434,19458,20482,21506,22530,23554,24578,25602
dw 26626,27650,28674,29698,30722,31746,32770,33794,34818,35842,36866,37890,38914,39938
dw 40962,41986,43010,44034,45058,46082,47106,48130,49154,50178,51202,52226,53250,54274
dw 55298,56322,57346,58370,59394,60418,61442,62466,63490,64514, 3, 1027, 2051, 3075
dw 4099, 5123, 6147, 7171, 8195, 9219,10243,11267,12291,13315,14339,15363,16387,17411
dw 18435,19459,20483,21507,22531,23555,24579,25603,26627,27651,28675,29699,30723,31747
dw 32771,33795,34819,35843,36867,37891,38915,39939,40963,41987,43011,44035,45059,46083
dw 47107,48131,49155,50179,51203,52227,53251,54275,55299,56323,57347,58371,59395,60419
dw 61443,62467,63491,64515
LABEL shiftdata7 WORD
dw 0, 512, 1024, 1536, 2048, 2560, 3072, 3584, 4096, 4608, 5120, 5632, 6144, 6656
dw 7168, 7680, 8192, 8704, 9216, 9728,10240,10752,11264,11776,12288,12800,13312,13824
dw 14336,14848,15360,15872,16384,16896,17408,17920,18432,18944,19456,19968,20480,20992
dw 21504,22016,22528,23040,23552,24064,24576,25088,25600,26112,26624,27136,27648,28160
dw 28672,29184,29696,30208,30720,31232,31744,32256,32768,33280,33792,34304,34816,35328
dw 35840,36352,36864,37376,37888,38400,38912,39424,39936,40448,40960,41472,41984,42496
dw 43008,43520,44032,44544,45056,45568,46080,46592,47104,47616,48128,48640,49152,49664
dw 50176,50688,51200,51712,52224,52736,53248,53760,54272,54784,55296,55808,56320,56832
dw 57344,57856,58368,58880,59392,59904,60416,60928,61440,61952,62464,62976,63488,64000
dw 64512,65024, 1, 513, 1025, 1537, 2049, 2561, 3073, 3585, 4097, 4609, 5121, 5633
dw 6145, 6657, 7169, 7681, 8193, 8705, 9217, 9729,10241,10753,11265,11777,12289,12801
dw 13313,13825,14337,14849,15361,15873,16385,16897,17409,17921,18433,18945,19457,19969
dw 20481,20993,21505,22017,22529,23041,23553,24065,24577,25089,25601,26113,26625,27137
dw 27649,28161,28673,29185,29697,30209,30721,31233,31745,32257,32769,33281,33793,34305
dw 34817,35329,35841,36353,36865,37377,37889,38401,38913,39425,39937,40449,40961,41473
dw 41985,42497,43009,43521,44033,44545,45057,45569,46081,46593,47105,47617,48129,48641
dw 49153,49665,50177,50689,51201,51713,52225,52737,53249,53761,54273,54785,55297,55809
dw 56321,56833,57345,57857,58369,58881,59393,59905,60417,60929,61441,61953,62465,62977
dw 63489,64001,64513,65025
shifttabletable dw shiftdata0,shiftdata1,shiftdata2,shiftdata3
dw shiftdata4,shiftdata5,shiftdata6,shiftdata7
shiftdrawtable dw egafont1,egafont1,egafont2,egafont3
fontcolor dw 15 ;0-16 mapmask value
px dw 0
py dw 0
pdrawmode dw 11000b
fontseg dw ?
PUBLIC fontcolor,px,py,pdrawmode,fontseg
pcharheight equ 0 ;lines high
charloc equ 2 ;address of every character
charwidth equ 514 ;width in pixels
; temporary variables, to be optimised out later
sourceptr dw 0
destptr dw 0
shiftptr dw 0
drawptr dw 0
egaxor dw 0
CODESEG
;==================
;
; DrawPchar
; Draws a proportional character at px,py, and increments px
;
;==================
PROC DrawPchar charnum:WORD
PUBLIC DrawPchar
USES si,di
; set write mode 0
mov dx,GC_INDEX
mov ax,GC_MODE
WORDOUT
; set xor mode
mov al,GC_DATAROTATE
mov ah,[BYTE pdrawmode]
WORDOUT
; set mapmask to color
mov dx,SC_INDEX
mov al,SC_MAPMASK
mov ah,[BYTE fontcolor]
WORDOUT
mov es,[fontseg] ;font segment
;
; calculate destination on screen
;
mov bx,[py]
shl bx,1
mov di,[ylookup+bx]
add di,[screenofs]
mov bx,[px]
mov ax,bx
shr ax,1
shr ax,1
shr ax,1 ;x location in bytes
add di,ax
mov [destptr],di ; DI holds destination <<<<<========
;
; look up which shift table to use, based on x coordinate
;
and bx,7 ;low bits of x location
shl bx,1
mov ax,[shifttabletable+bx]
mov [shiftptr],ax ;<<<<<<=========
;
; find character location, width, and height
;
mov bx,[charnum] ;move source for pic into bx
mov si,[es:charwidth+bx]
and si,0ffh
shl bx,1
mov ax,[es:charloc+bx]
mov [sourceptr],ax ;<<<<<<=========
add [px],si ;move the location for the next drawing
add si,7
shr si,1
shr si,1
shr si,1
; advance past mask for or only
mov ax,si
mov dx,[es:pcharheight]
mul dl
add [sourceptr],ax
;
shl si,1 ;bytes wide
mov ax,[shiftdrawtable+si] ;procedure to draw this width
mov [drawptr],ax ;<<<<<<=========
; xor in data
mov bx,[sourceptr]
mov bp,[shiftptr]
mov cx,[es:pcharheight]
mov es,[screenseg]
mov ds,[fontseg]
call [ss:drawptr]
; set copy mode
mov dx,GC_INDEX
mov ax,GC_DATAROTATE
WORDOUT
; set mapmask to all
mov dx,SC_INDEX
mov ax,SC_MAPMASK + 15*256
WORDOUT
mov ax,ss
mov ds,ax
ret
ENDP
; ax scratch
; bx source location
; cx height counter
; dx xor value
; si byte value*2, to look up in scale table
; di screen location
; bp scale table to use
;
; ds source segment
; es screenseg
; ss table segment
MACRO SHIFTXOR
mov al,[bx] ;source data
xor ah,ah
shl ax,1
mov si,ax
mov al,[es:di] ;load latches
mov ax,[bp+si] ;shift into two bytes
xor ax,dx
stosb ;write latches
mov al,[es:di] ;load latches
mov [es:di],ah ;write latches
inc bx
ENDM
MACRO SHIFTNOXOR
mov al,[bx] ;source data
xor ah,ah
shl ax,1
mov si,ax
mov al,[es:di] ;load latches
mov ax,[bp+si] ;shift into two bytes
stosb ;write latches
mov al,[es:di] ;load latches
mov [es:di],ah ;write latches
inc bx
ENDM
EVEN
egafont1: ; draw a font that is 1 byte wide
mov dx,[ss:linewidth]
dec dx
EVEN
@@loop1:
SHIFTNOXOR
add di,dx
loop @@loop1
ret
EVEN
egafont2: ; draw a font that is 2 byte wide
mov dx,[ss:linewidth]
dec dx
dec dx
EVEN
@@loop2:
SHIFTNOXOR
SHIFTNOXOR
add di,dx
loop @@loop2
ret
EVEN
egafont3: ; draw a font that is 3 byte wide
mov dx,[ss:linewidth]
dec dx
dec dx
EVEN
@@loop3:
SHIFTNOXOR
SHIFTNOXOR
SHIFTNOXOR
add di,dx
loop egafont3
ret
endif ; if fonts
;===========================================================================
;
; SCALING GRAPHICS
;
;===========================================================================
MACRO MAKELAB NUM
lab&NUM:
ENDM
MACRO MAKEREF NUM
dw OFFSET lab&NUM
ENDM
;=========================================================================
MAXSCALES equ 256
DATASEG
LABEL endtable WORD
labcount = 0
REPT MAXSCALES
MAKEREF %labcount
labcount = labcount + 1
ENDM
CODESEG
;==================================================
;
; void scaleline (int scale, unsigned picseg, unsigned maskseg,
; unsigned screen, unsigned width)
;
;==================================================
PROC ScaleLine pixels:word, scaleptr:dword, picptr:dword, screen:word
USES si,di
PUBLIC ScaleLine
;
; modify doline procedure for proper width
;
mov bx,[pixels]
cmp bx,MAXSCALES
jbe @@scaleok
mov bx,MAXSCALES
@@scaleok:
shl bx,1
mov bx,[endtable+bx]
push [cs:bx] ;save the code that will be modified over
mov [WORD cs:bx],0d18eh ;mov ss,cx
push [cs:bx+2] ;save the code that will be modified over
mov [WORD cs:bx+2],90c3h ;ret / nop
push bx
mov dx,[linewidth]
mov di,[WORD screen]
mov es,[screenseg]
mov si,[WORD scaleptr]
mov ds,[WORD scaleptr+2]
mov bx,[WORD picptr]
mov ax,[WORD picptr+2] ;will be moved into ss after call
mov bp,bx
cli
call doline
sti
;
; restore doline to regular state
;
pop bx ;address of modified code
pop [cs:bx+2]
pop [cs:bx]
mov ax,ss
mov ds,ax
ret
;================
;
; doline
;
; Big unwound scaling routine
;
; ds:si = scale table
; ss:bx = pic data
; es:di = screen location
;
;================
doline:
mov cx,ss
mov ss,ax ;can't call a routine with ss used...
labcount = 0
REPT MAXSCALES
MAKELAB %labcount
labcount = labcount + 1
lodsb ; get scaled pixel number
xlat [ss:bx] ; look it up in the picture
xchg [es:di],al ; load latches and write pixel to screen
add di,dx ; down to next line
ENDM
mov ss,cx
ret
ENDP
;===========================================================================
;
; SPRITE routines
;
;===========================================================================
if NUMSPRITES
;============
;
; DrawSprite
;
; Source is a (void _seg *) to the sprite
;
; Must be in write mode 0
;
;============
DATASEG
EGAdraws dw BadSize,EGAone,EGAtwo,EGAthree,EGAfour,EGAfive,EGAsix
dw EGAseven,EGAeight,EGAnine,EGAten
dw 10 dup (BadSize)
EGAdrawsOdd dw BadSize,EGAone,EGAtwoOdd,EGAthreeOdd,EGAfourOdd
dw EGAfiveOdd,EGAsixOdd,EGAsevenOdd,EGAeightOdd
dw EGAnineOdd,EGAtenOdd
dw 10 dup (BadSize)
spriteroutine dw ?
blocksize dw ?
blockheight dw ?
blockdest dw ?
CODESEG
PROC DrawSpriteT wide:WORD, height:WORD, source:WORD, dest:WORD, plsize:WORD
USES SI,DI
PUBLIC DrawSpriteT
mov ax,[dest]
mov [blockdest],ax
mov ax,[height]
mov [blockheight],ax
mov ax,[plsize]
mov [blocksize],ax
mov bx,ax
shl bx,1
shl bx,1 ;mask is four planes from first byte
mov si,[wide]
mov dx,[linewidth]
sub dx,si ;dx is delta to next line (move to bp)
shl si,1
mov di,[dest]
test di,1
jz @@evens
mov ax,[EGAdrawsOdd+si]
jmp @@gotit
@@evens:
mov ax,[EGAdraws+si]
@@gotit:
mov [spriteroutine],ax
mov es,[screenseg]
mov ds,[source]
mov bp,dx
xor si,si
;=================
;
; AX: scratch
; BX: offset to mask
; CX: height
; DX: scratch
; SI: source in sprite
; DI: screen
; BP: delta to next line
; DS: sprite
; ES: screen
; SS: stack
;
;=================
;
; draw plane 0
;
mov dx,SC_INDEX
mov ax,1*256+SC_MAPMASK
WORDOUT
add dx,GC_INDEX-SC_INDEX
mov ax,0*256+GC_READMAP
WORDOUT
mov cx,[ss:blockheight]
mov di,[ss:blockdest]
call [ss: spriteroutine] ;draw the plane's data
;
; draw plane 1
;
mov dx,SC_INDEX
mov ax,2*256+SC_MAPMASK
WORDOUT
add dx,GC_INDEX-SC_INDEX
mov ax,1*256+GC_READMAP
WORDOUT
sub bx,[ss:blocksize]
mov cx,[ss:blockheight]
mov di,[ss:blockdest]
call [ss:spriteroutine] ;draw the plane's data
;
; draw plane 2
;
mov dx,SC_INDEX
mov ax,4*256+SC_MAPMASK
WORDOUT
add dx,GC_INDEX-SC_INDEX
mov ax,2*256+GC_READMAP
WORDOUT
sub bx,[ss:blocksize]
mov cx,[ss:blockheight]
mov di,[ss:blockdest]
call [ss:spriteroutine] ;draw the plane's data
;
; draw plane 3
;
mov dx,SC_INDEX
mov ax,8*256+SC_MAPMASK
WORDOUT
add dx,GC_INDEX-SC_INDEX
mov ax,3*256+GC_READMAP
WORDOUT
sub bx,[ss:blocksize]
mov cx,[ss:blockheight]
mov di,[ss:blockdest]
call [ss:spriteroutine] ;draw the plane's data
mov ax,ss
mov ds,ax
ret
ENDP
;=================
PROC BadSize
mov ax,@Data
mov ds,ax
mov ss,ax
ret
ENDP
;===========================================================================
;
; sprite macros
;
;===========================================================================
MACRO MASKBYTE
mov dl,[es:di] ;background
and dl,[si+bx] ;mask
lodsb ;data
or al,dl
stosb ;screen
ENDM
MACRO MASKWORD
mov dx,[es:di] ;background
and dx,[si+bx] ;mask
lodsw ;data
or ax,dx
stosw ;screen
ENDM
;=================
;
; AX: scratch
; BX: offset to mask
; CX: height
; DX: scratch
; SI: source in sprite
; DI: screen
; BP: delta to next line
; DS: sprite
; ES: screen
; SS: stack
;
;=================
;===========================================================================
;
; even shifts
;
;===========================================================================
EVEN
PROC EGAone
MASKBYTE
add di,bp
loop EGAone
ret
ENDP
;=================
EVEN
PROC EGAtwo
MASKWORD
add di,bp
loop EGAtwo
ret
ENDP
;=================
EVEN
PROC EGAthree
MASKWORD
MASKBYTE
add di,bp
loop EGAthree
ret
ENDP
;=================
EVEN
PROC EGAfour
MASKWORD
MASKWORD
add di,bp
loop EGAfour
ret
ENDP
;=================
EVEN
PROC EGAfive
MASKWORD
MASKWORD
MASKBYTE
add di,bp
loop EGAfive
ret
ENDP
;=================
EVEN
PROC EGAsix
MASKWORD
MASKWORD
MASKWORD
add di,bp
loop EGAsix
ret
ENDP
;=================
EVEN
PROC EGAseven
MASKWORD
MASKWORD
MASKWORD
MASKBYTE
add di,bp
loop EGAseven
ret
ENDP
;=================
EVEN
PROC EGAeight
MASKWORD
MASKWORD
MASKWORD
MASKWORD
add di,bp
loop EGAeight
ret
ENDP
;=================
EVEN
PROC EGAnine
MASKWORD
MASKWORD
MASKWORD
MASKWORD
MASKBYTE
add di,bp
loop EGAnine
ret
ENDP
;=================
EVEN
PROC EGAten
MASKWORD
MASKWORD
MASKWORD
MASKWORD
MASKWORD
add di,bp
loop EGAten
ret
ENDP
;===========================================================================
;
; odd shifts
;
;===========================================================================
EVEN
PROC EGAoneOdd
MASKBYTE
add di,bp
loop EGAoneOdd
ret
ENDP
;=================
EVEN
PROC EGAtwoOdd
MASKBYTE
MASKBYTE
add di,bp
loop EGAtwoOdd
ret
ENDP
;=================
EVEN
PROC EGAthreeOdd
MASKBYTE
MASKWORD
add di,bp
loop EGAthreeOdd
ret
ENDP
;=================
EVEN
PROC EGAfourOdd
MASKBYTE
MASKWORD
MASKBYTE
add di,bp
loop EGAfourOdd
ret
ENDP
;=================
EVEN
PROC EGAfiveOdd
MASKBYTE
MASKWORD
MASKWORD
add di,bp
loop EGAfiveOdd
ret
ENDP
;=================
EVEN
PROC EGAsixOdd
MASKBYTE
MASKWORD
MASKWORD
MASKBYTE
add di,bp
loop EGAsixOdd
ret
ENDP
;=================
EVEN
PROC EGAsevenOdd
MASKBYTE
MASKWORD
MASKWORD
MASKWORD
add di,bp
loop EGAsevenOdd
ret
ENDP
;=================
EVEN
PROC EGAeightOdd
MASKBYTE
MASKWORD
MASKWORD
MASKWORD
MASKBYTE
add di,bp
loop EGAeightOdd
ret
ENDP
;=================
EVEN
PROC EGAnineOdd
MASKBYTE
MASKWORD
MASKWORD
MASKWORD
MASKWORD
add di,bp
loop EGAnineOdd
ret
ENDP
;=================
EVEN
PROC EGAtenOdd
MASKBYTE
MASKWORD
MASKWORD
MASKWORD
MASKWORD
MASKBYTE
add di,bp
loop EGAtenOdd
ret
ENDP
endif ; if numsprites
END