1 ; XTile Assembler routine lib
2 ;
3 ; COPYRIGHT (C) 1993 Erich P Gatejen 1993 All Rights Reserved
4 ;
5 ; File: XTILE.ASM
6 ;
7 ; Mode X graphics manager.
8
9 ; Ver 1.1 : Add sprites
10 ; Add 4-Pixel font
11 ; Add mouse interface
12 ; Add put pixel
13
14 ; Ver 2.0 : Major rewrite!
15 ; Add virtual size
16 ; Split-screen
17 ; More modes
18
19
20 IDEAL
21
22
23 INCLUDE "XTILE20!.USE"
24
25
26 DOSSEG
27
28 ; LARGE memory model.
29 MODEL LARGE
30
31 ; ------------------------------------------------------------------------
32 ; ----------------------------- Data Seg ---------------------------------
33 ; ------------------------------------------------------------------------
34 FARDATA
35
36 ; --- Mode set tables ----------------------------------------------------
37
38 ; - CRTC Values
39 CRTC_Single_Scan: ; Single scan per line (400/480 Line modes)
40 dw 04009H ; 1 Scan Line
41 dw 00014H ; Dword Mode off
42 dw 0E317H ; Byte Mode
43
44 CRTC_Double_Scan: ; Double scan per line (200/240 Line modes)
45 dw 04109H ; Cell Height (2 Scan Lines)
46 dw 00014H ; Dword Mode off
47 dw 0E317H ; turn on Byte Mode
48
49 CRTC_320_Wide: ; CRTC Setup Data for 320 Horz Pixels
50 dw 05F00H ; Horz total
51 dw 04F01H ; Horz Displayed
52 dw 05002H ; Start Horz Blanking
53 dw 08203H ; End Horz Blanking
54 dw 05404H ; Start H Sync
55 dw 08005H ; End H Sync
56
57 CRTC_360_Wide: ; CRTC Setup Data for 360 Horz Pixels
58 dw 06B00H ; Horz total
59 dw 05901H ; Horz Displayed
60 dw 05A02H ; Start Horz Blanking
61 dw 08E03H ; End Horz Blanking
62 dw 05E04H ; Start H Sync
63 dw 08A05H ; End H Sync
64
65 CRTC_200_Tall:
66 CRTC_400_Tall: ; CRTC Setup Data for 200/400 Line modes
67 dw 0BF06H ; Vertical Total
68 dw 01F07H ; Overflow
69 dw 09C10H ; V Sync Start
70 dw 08E11H ; V Sync End/Prot Cr0 Cr7
71 dw 08F12H ; Vertical Displayed
72 dw 09615H ; V Blank Start
73 dw 0B916H ; V Blank End
74 dw 0 ; End table
75
76 CRTC_240_Tall:
77 CRTC_480_Tall: ; CRTC Setup Data for 240/480 Line modes
78 dw 00D06H ; Vertical Total
79 dw 03E07H ; Overflow
80 dw 0EA10H ; V Sync Start
81 dw 08C11H ; V Sync End/Prot Cr0 Cr7
82 dw 0DF12H ; Vertical Displayed
83 dw 0E715H ; V Blank Start
84 dw 00616H ; V Blank End
85 dw 0 ; End table
86
87
88 ; - Tables for each mode
89 XMODE_320x240: ; 320 by 240 Pixels | Standard ModeX
90 dw 0E3h ; 480 scan Lines & 28 Mhz Clock
91 dw 320, 240 ; View size
92 dw OFFSET CRTC_320_Wide
93 dw OFFSET CRTC_240_Tall
94 dw OFFSET CRTC_Double_Scan
95
96 XMODE_320x200: ; 320 by 200 mode
97 dw 063h ; 400 scan Lines & 25 Mhz Clock
98 dw 320, 200 ; View size
99 dw OFFSET CRTC_320_Wide
100 dw OFFSET CRTC_200_Tall
101 dw OFFSET CRTC_Double_Scan
102
103 XMODE_320x400: ; 320 by 200 Pixels
104 dw 063h ; 400 scan Lines & 25 Mhz Clock
105 dw 320, 400 ; View size
106 dw OFFSET CRTC_320_Wide
107 dw OFFSET CRTC_400_Tall
108 dw OFFSET CRTC_Single_Scan
109
110 XMODE_360x240: ; 360 by 240 Pixels
111 dw 0E7h ; 480 scan Lines & 28 Mhz Clock
112 dw 360, 240 ; View size
113 dw OFFSET CRTC_360_Wide
114 dw OFFSET CRTC_240_Tall
115 dw OFFSET CRTC_Double_Scan
116
117 XMODE_360x480: ; 360 by 480 Pixels
118 dw 0E7h ; 480 scan Lines & 28 Mhz Clock
119 dw 360, 480 ; View size
120 dw OFFSET CRTC_360_Wide
121 dw OFFSET CRTC_480_Tall
122 dw OFFSET CRTC_Single_Scan
123
124 XMODE_320x480: ; 320 by 480 Pixels
125 dw 0E3h ; 480 scan Lines & 28 Mhz Clock
126 dw 320, 480 ; View size
127 dw OFFSET CRTC_320_Wide
128 dw OFFSET CRTC_480_Tall
129 dw OFFSET CRTC_Single_Scan
130
131 XMODE_360x200: ; 360 by 200 Pixels
132 dw 067h ; 400 scan Lines & 28 Mhz Clock
133 dw 360, 200 ; View size
134 dw OFFSET CRTC_360_Wide
135 dw OFFSET CRTC_200_Tall
136 dw OFFSET CRTC_Double_Scan
137
138 XMODE_360x400: ; 360 by 200 Pixels
139 dw 067h ; 400 scan Lines & 28 Mhz Clock
140 dw 360, 400 ; View size
141 dw OFFSET CRTC_360_Wide
142 dw OFFSET CRTC_400_Tall
143 dw OFFSET CRTC_Single_Scan
144
145 ; Structure to access mode tables
146 STRUC MODE_TABLE
147 MiscTiming dw ?
148 XSizeM dw ?
149 YSizeM dw ?
150 WidthDataO dw ?
151 HightDataO dw ?
152 ScanDataO dw ?
153
154 ENDS MODE_TABLE
155
156
157 ; - Table of available modes. Position relates to mode number
158 XMODE_TABLE:
159 dw OFFSET XMODE_320x240 ; Mode 0. Standard mode X
160 dw OFFSET XMODE_320x200 ; Mode 1.
161 dw OFFSET XMODE_320x400 ; Mode 2.
162 dw OFFSET XMODE_360x400 ; Mode 3.
163 dw OFFSET XMODE_360x200 ; Mode 4.
164 dw OFFSET XMODE_360x240 ; Mode 5.
165 dw OFFSET XMODE_320x480 ; Mode 6.
166 dw OFFSET XMODE_360x480 ; Mode 7.
167
168
169 ; --- Other Tables --------------------------------------------------------
170
171 ; Pixel mask table for pixel put.
172 LABEL PMask_Table BYTE
173 db 00000001b ; Plane 0, first pix of XBlock
174 db 00000010b ; Plane 1, second pix of XBlock
175 db 00000100b ; Plane 2, third pix of XBlock
176 db 00001000b ; Plane 3, forth pix of XBlock
177
178
179 ; ---- Copyright notice --------------------------------------------------
180 Banner db 'COPYRIGHT (C) 1993 Erich P Gatejen' ; Do not remove
181 db ' All Rights Reserved ' ; Do not remove
182 ID db ' !!!!'
183
184
185 ; ---- XTile local data --------------------------------------------------
186
187 ; --- Define the current write page
188 Write_Page dw ? ; Offset into current write page
189 WLine_Offset dw ? ; Line size in the current write page
190
191 ; --- Define the current display page
192 Display_Page dw ? ; Offset into display page
193 DLine_Offset dw ? ; Line size in current display page
194 DisplaySizeX dw ? ; Size of display page (X)
195 DisplaySizeY dw ? ; Size of display page (Y)
196 ViewXLoc dw ? ; Starting X of view
197 ViewYLoc dw ? ; Starting Y of view
198 MaxViewX dw ? ; Maximum View X
199 MaxViewY dw ? ; Max View Y
200 SplitY dw ? ; 0 = no split screen. Else, Y size.
201 ScreenSizeX dw ? ; Actual screen size
202 ScreenSizeY dw ? ; Actual screen size
203
204
205 ; --- Font data
206 ; 8-pix font
207 UpLoaded8 dw 1 ; Is it uploaded? Assume not.
208 Font_SiteU8 dw ? ; Offset of registered uploaded font
209 LABEL Font_Addr8 DWORD ; For loading the address of an non-uploaded font
210 Font_SiteD8 dw ? ; Offset of registered not-uploaded font
211 FSS8 dw ? ; Segment. Don't change
212 Char_Base8 dw ? ; Base character for font
213 Font_Mask_S8 dw ? ; Seg with masks for font set
214 Font_Mask_O8 dw ? ; Offset
215
216 ; 4-pix font
217 UpLoaded4 dw 1 ; Is it uploaded? Assume not.
218 Font_SiteU4 dw ? ; Offset of registered uploaded font
219 LABEL Font_Addr4 DWORD ; For loading the address of an non-uploaded font
220 Font_SiteD4 dw ? ; Offset of registered not-uploaded font
221 FSS4 dw ? ; Segment. Don't change
222 Char_Base4 dw ? ; Base character for font
223 Font_Mask_S4 dw ? ; Seg with masks for font set
224 Font_Mask_O4 dw ? ; Offset
225
226
227 ; --- Mouse data
228 Mouse_Hndlr_O dd FAR ? ; Address of the user defined mouse handler
229 LABEL MPointerMask DWORD ; Address of the S:O for the next two
230 MPointerMask_O dw ? ; Location in user data of the mouse pntr mask
231 MPointerMask_S dw ? ; Segment ^
232 MUEventMask dw ? ; Events user wishes to be reported
233 MLastX dw ? ; Last known X location of the mouse
234 MLastY dw ? ; Last known Y location of the mouse
235 LockHandler dw 0 ; Block re-entry into mouse handler
236
237 ; --- Clip Values
238 ClipXS dw ? ; Clip starting X
239 ClipYS dw ? ; Clip starting Y
240 ClipXE dw ? ; Clip ending X
241 ClipYE dw ? ; Clip ending Y
242
243
244
245 ENDS
246
247
248
249 ; ------------------------------------------------------------------------
250 ; ---------------------------- Code Seg ----------------------------------
251 ; ------------------------------------------------------------------------
252 SEGMENT CODE WORD PUBLIC 'CODE'
253
254
255 ASSUME cs:CODE
256
257 ; --------------------------- _XInit_Mode -------------------------------
258 ; - This will initialize Mode X.
259 ; -
260 public _XInit_Mode
261
262 PROC _XInit_Mode FAR
263
264 ARG Mode:WORD
265
266 push bp
267 mov bp, sp ; Save Stack frame
268 push si di ds ; Save calling frame
269
270 ASSUME ds: @fardata
271 mov ax, @fardata ; Set DS to segment w/ Table
272 mov ds, ax
273
274 ; Load SI with pointer to table entry
275 mov bx, [Mode] ; Get mode number
276 shl bx, 1 ; Find table offset
277 ; FIX THIS
278 mov di, OFFSET XMODE_TABLE ; Point to the entry
279 add di, bx
280 mov si, [di]
281
282 ; Set mode
283 mov ax, 13H ; First, setup as Mode 13H
284 int 10h ; Let BIOS do it
285
286 mov dx, SC_INDEX ; Modify the Sequence Controller
287 mov ax, 0604h ; Disable CHAIN-4
288 out dx, ax
289
290 mov ax, 0100h ; Synch reset
291 out dx, ax
292
293 mov dx, MISC_OUTPUT ; Modify the Misc Output
294 mov ax, [(MODE_TABLE PTR si).MiscTiming] ; Set timing and size
295 out dx, al
296
297 mov dx, SC_INDEX ; Modify the Sequence Cont.
298 mov ax, 0300h ; Resart the sequencer
299 out dx, ax
300
301 ; Unprotect the CRTC registers
302 mov dx, CRTC_INDEX
303 mov al, 011h
304 out dx, al
305 inc dx
306 in al, dx
307 and al, 07Fh ; Mask out protect bit
308 out dx, al ; Unprotect
309
310 ; --- Set up the CRT controller
311 mov dx, CRTC_INDEX
312
313 ; - Set width
314 mov cx, 6
315 mov di, [(MODE_TABLE PTR si).WidthDataO] ;Get width table off
316 @@LoopWidth:
317 mov ax, [di] ; Load ax with table vaule
318 out dx, ax
319 add di, 2 ; Point to next item
320 loop @@LoopWidth
321
322 ; - Set hight
323 mov di, [(MODE_TABLE PTR si).HightDataO] ;Get hight table off
324 @@LoopHight:
325 mov ax, [di]
326 or ax, ax ; Is it the end of table
327 jz @@Scans ; Yes, move on
328 add di, 2 ; Point to next item
329 out dx, ax ; Send current one out
330 jmp @@LoopHight
331
332 ; - Set scans
333 @@Scans:
334 mov cx, 3
335 mov di, [(MODE_TABLE PTR si).ScanDataO] ; Get width table offset
336 @@LoopScans:
337 mov ax, [di] ; Load ax with table vaule
338 out dx, ax
339 add di, 2 ; Point to next item
340 loop @@LoopScans
341
342 ; --- Set default page information
343
344 ; - Write page
345 mov ax, 0
346 mov [Write_Page], ax ; Write page offset 0000
347 mov ax, [(MODE_TABLE PTR si).XSizeM] ; Default XBlocks p/line is X size
348 shr ax, 1
349 shr ax, 1
350 mov [WLine_Offset], ax ; Set line size in XBlocks
351
352 ; - Display Page. Same page as the default writepage
353 mov [DLine_Offset], ax ; Set line size in XBlocks
354 mov ax, 0
355 mov [Display_Page], ax ; Display offset 0000
356 mov [SplitY], ax ; No split screen
357 mov [ViewX], ax ; View at base
358 mov [ViewY], ax ; View at base
359 mov [MaxViewX], ax ; No room to move
360 mov [MaxViewY], ax
361 mov ax, [(MODE_TABLE PTR si).XSizeM] ; Display size X
362 mov [DisplaySizeX], ax
363 mov [ScreenSizeX], ax
364 mov ax, [(MODE_TABLE PTR si).YSizeM] ; Display size Y
365 mov [DisplaySizeY], ax
366 mov [ScreenSizeY], ax
367
368
369 ; !!DONE!!
370 pop ds di si ; Return state
371 pop bp
372 ret
373
374
375
376 ENDP _XInit_Mode
377
378
379 ; --------------------------- _XSet_Write_Page ------------------------------
380 ; - This will set a write page. It will be the current write page for
381 ; - most write operations ( the ones that don't use this page will say
382 ; - so in thier discription )
383 ; -
384 public _XSet_Write_Page
385
386 PROC _XSet_Write_Page FAR
387
388 ARG Offst:WORD, XSize:WORD
389
390 push bp
391 mov bp, sp ; Save Stack frame
392 push ds
393
394 ; Set the DS to local data
395 ASSUME ds: @fardata
396 mov ax, @fardata
397 mov ds, ax
398
399 ; First, load the page offset
400 mov ax, [Offst] ; Get offset from pass
401 mov [Write_Page], ax ; Put it in var
402
403 ; Calculate the line offset
404 mov ax, [XSize] ; Get the total size
405 shr ax, 1 ; divided by 4 to make XBlocks
406 shr ax, 1
407 mov [WLine_Offset], ax ; Set line size in XBlocks
408
409 ; !!DONE!!
410 pop ds ; Return state
411 pop bp
412 ret
413
414 ENDP _XSet_Write_Page
415
416
417 ; --------------------------- _XSet_Display_Page -------------------------------
418 ; - This function set will set the display page. The view will also be set
419 ; -
420 public _XSet_Display_Page
421
422 PROC _XSet_Display_Page FAR
423
424 ARG Offst:WORD, XSize:WORD, YSize:WORD, ViewX:WORD, ViewY:WORD
425
426
427 push bp
428 mov bp, sp ; Set up stack frame
429 push ds
430
431
432 ; Set DS to local data
433 ASSUME ds: @fardata
434 mov ax, @fardata
435 mov ds, ax
436
437 ; Wait for retrace to end
438 mov dx, IN_STATUS1 ; Input Status #1 Register
439 @Wait:
440 in al, dx
441 and al, 08h
442 jnz @Wait
443
444 ; Set line offset. CRTC Offset register
445 ; Calculate the line offset
446 mov ax, [XSize] ; Get the total size
447 mov [DisplaySizeX], ax ; Save it
448 shr ax, 1 ; divide by 4 to make XBlocks
449 shr ax, 1
450 mov [DLine_Offset], ax ; Save XBlocks per line
451 shr ax, 1 ; divide by 2 to get register value
452
453 ; Set it
454 mov dx, CRTC_INDEX ; Set port
455 mov ah, 13h ; CRTC Offset Register Index
456 xchg al, ah ; Swap format
457 out dx, ax ; Send it
458
459 ; Set the Start Display Address to the new window
460 mov cx, [ViewX] ; Get X start for the view
461 mov [ViewXLoc], cx ; Save it for later
462 mov ax, [ViewY] ; Get Y start for the view
463 mov [ViewYLoc], ax ; Save it for later
464
465 ; Compute proper Display start address to use
466 mul [DLine_Offset] ; AX = Y size (AX) * XBlocks per line
467 shr cx, 1
468 shr cx, 1 ; Convert CX to XBlocks. Figure pan later
469 add cx, ax ; Find view upper left pixel
470 add cx, [Offst] ; Add page offset
471 ; NOTE: This will leave any 0-3 pan for later
472
473 ; Change CRTC
474 mov dx, CRTC_INDEX ; Set port
475 mov al, 0Dh ; Start display low.
476 mov ah, cl ; Load low 8 bits
477 out dx, ax
478 mov al, 0Ch ; Start display high
479 mov ah, ch ; Load high 8 Bits
480 out dx, ax
481
482 ; Wait for a Vertical Retrace
483 mov dx, IN_STATUS1
484 @@Wait2:
485 in al, dx
486 and al, 08h ; Vertical Retrace Start?
487 jz @@Wait2 ; If Not, loop until it is
488
489 ; Now Set the Horizontal Pixel Pan values
490 mov dx, 03C0h ; The Attribute controller
491 mov al, 033h ; Select Pixel Pan Register
492 out dx, al
493
494 ; Get the pan value and send it
495 mov ax, [ViewX] ; Get raw X View start
496 and al, 03 ; Peel off the significant bits
497 shl al, 1 ; Shift for 256 Color Mode
498 out dx, al ; Send it
499
500 ; Set some data values for this display page
501
502 ; Max View limits
503 mov ax, [XSize] ; Get the page size
504 sub ax, [ScreenSizeX] ; subtract the actual screen size
505 dec ax ; Adjust for count from 0
506 mov [MaxViewX], ax ; Save
507
508 mov ax, [YSize] ; Get the page size
509 mov [DisplaySizeY], ax ; Save this
510 sub ax, [ScreenSizeY] ; subtract the actual screen size
511 dec ax ; Adjust for count from 0
512 mov [MaxViewY], ax ; Save
513
514 ; Save page offset
515 mov ax, [Offst]
516 mov [Display_Page], ax
517
518 ; DONE!!
519 @@Done:
520 pop ds ; Return state
521 pop bp
522 ret
523
524 ENDP _XSet_Display_Page
525
526
527 ; --------------------------- _XSet_View ----------------------------------
528 ; - This function set will set the view port within the current page
529 ; - Return 0 if successful, else 1 (TRUE for C)
530 public _XSet_View
531
532 PROC _XSet_View FAR
533
534 ARG ViewX:WORD, ViewY:WORD
535
536
537 push bp
538 mov bp, sp ; Set up stack frame
539 push ds
540
541
542 ; Set DS to local data
543 ASSUME ds: @fardata
544 mov ax, @fardata
545 mov ds, ax
546
547 ; Wait for retrace to end
548 mov dx, IN_STATUS1 ; Input Status #1 Register
549 @@Wait:
550 in al, dx
551 and al, 08h
552 jnz @@Wait
553
554
555 ; Set the Start Display Address to the new window
556 mov cx, [ViewX] ; Get X start for the view
557 cmp cx, [MaxViewX] ; Is it within range
558 ja @@Error ; No, jump out.
559 mov [ViewXLoc], cx ; Save the view location
560
561 mov ax, [ViewY] ; Get Y start for the view
562 cmp ax, [MaxViewY] ; Is it within range
563 ja @@Error ; No, jump out.
564 mov [ViewYLoc], ax ; Save the view loc
565
566 ; Compute proper Display start address to use
567 mul [DLine_Offset] ; AX = Y size (AX) * XBlocks per line
568 shr cx, 1
569 shr cx, 1 ; Conver CX to XBlocks. Figure pan later
570 add cx, ax ; Find view upper left pixel
571 add cx, [Display_Page] ; Add page offset
572 ; NOTE: This will leave any 0-3 pan for later
573
574 ; Change CRTC
575 mov dx, CRTC_INDEX ; Set port
576 mov al, 0Dh ; Start display low.
577 mov ah, cl ; Load low 8 bits
578 out dx, ax
579 mov al, 0Ch ; Start display high
580 mov ah, ch ; Load high 8 Bits
581 out dx, ax
582
583 ; Wait for a Vertical Retrace
584 mov dx, IN_STATUS1
585 @@Wait2:
586 in al, dx
587 and al, 08h ; Vertical Retrace Start?
588 jz @@Wait2 ; If Not, loop until it is
589
590 ; Now Set the Horizontal Pixel Pan values
591 mov dx, 03C0h ; The Attribute controller
592 mov al, 033h ; Select Pixel Pan Register
593 out dx, al
594
595 ; Get the pan value and send it
596 mov ax, [ViewX] ; Get raw X View start
597 and al, 03 ; Peel off the significant bits
598 shl al, 1 ; Shift for 256 Color Mode
599 out dx, al ; Send it
600
601 ; DONE!!
602 mov ax, 0 ; No Error, Get outta here
603 jmp @@Done
604
605 @@Error:
606 mov ax, 1 ; Error
607
608 @@Done:
609 pop ds ; Return state
610 pop bp
611 ret
612
613 ENDP _XSet_View
614
615
616 ; --------------------------- _XWait_Retrace -------------------------------
617 ; - Wait for vertical retrace
618 public _XWait_Retrace
619
620 PROC _XWait_Retrace FAR
621
622 ; Wait for a Vertical Retrace
623 mov dx, IN_STATUS1
624 @@Wait1:
625 in al, dx
626 and al, 08h ; Vertical Retrace Start?
627 jz @@Wait1 ; If Not, loop until it is
628
629 ret
630
631 ENDP _XWait_Retrace
632
633
634 ; --------------------------- _XSet_Box --------------------------------
635 ; - This function will draw a box to the passed value. The X coord must
636 ; - be MOD 4 aligned.
637 ; -
638 public _XSet_Box
639
640 PROC _XSet_Box FAR
641
642 ARG X_S:WORD, Y_S:WORD, X_D:WORD, Y_D:WORD, COLOR:BYTE
643
644 push bp
645 mov bp, sp ; Save Stack frame
646 push ds di si
647
648 ; Set DS to local data
649 ASSUME ds: @fardata
650 mov ax, @fardata
651 mov ds, ax
652
653 cld
654
655 ; Set ES to display mem and DI to start of rectangle on screen
656 mov ax, SCREEN_SEG
657 mov es, ax
658
659 mov ax, [WLine_Offset] ; Get the line length for write page
660 mov bx, ax ; Save in BX for later
661 mul [Y_S] ; Find Y offset value. Place in AX
662
663 mov di, [X_S] ; Find X offset value. Place in DI
664 shr di, 1
665 shr di, 1 ; Adjust for planes
666
667 add di, ax ; Add X and Y offsets
668 add di, [Write_Page] ; Add in page offset
669
670 ; Set all data from CPU and non from latches
671 mov dx, GC_INDEX
672 mov ax, 0FF00h + BIT_MASK ; Set all CPU writes
673 out dx, ax
674
675 ; Insure Map Mask is set to all planes
676 mov ax, 0F02h ; 0F sets all planes. 02 is Map Mask
677 mov dx, SC_INDEX
678 out dx, ax
679
680 ; Insure X dist isn't 0 and put number of XBlocks in CX
681 mov cx, [X_D]
682 shr cx, 1 ; Div by 4 so we have
683 shr cx, 1 ; the actual number addresses to fill
684 ; per line
685 cmp cx, 0
686 jle @@Done ; Jump to stop if invalid
687
688
689 ; SI will contain the number lines
690 mov si, [Y_D]
691
692 ; Load color into al
693 mov al, [COLOR]
694
695 ; Set BX to contain the distance from one scan line to next
696 sub bx, cx ; BX was already loaded with line length
697
698 @@Rowloop:
699 push cx ; Push cx so we can restore for each iteration
700
701 ; Do the actual line. REP STOSB.
702 rep stosb
703
704 ; Adjust for next iteration
705 pop cx ; Restore CX. ( [Pix/line]/4 )
706 add di, bx ; Point DI to start of next line
707
708 ; End of Rowloop. Dec SI, if it is NOT 0 then do next line
709 dec si
710 jnz @@Rowloop
711
712 ; Else DONE!!
713
714 @@Done:
715 pop si di ds
716 pop bp
717 ret
718
719 ENDP _XSet_Box
720
721
722 ; --------------------------- _XClear -------------------------------
723 ; - This will clear all memory on the video card to the passed value
724 ; -
725 public _XClear
726
727 PROC _XClear FAR
728
729 ARG COLOR:WORD
730
731 push bp
732 mov bp, sp ; Save Stack frame
733 push di
734
735 ; Set MAP MASK to all planes
736 mov dx, SC_INDEX
737 mov ax, 0F02h
738 out dx, ax
739
740 ; Clear the screen
741 mov ax, SCREEN_SEG
742 mov es, ax
743 sub di, di
744 sub ax, ax
745 mov ax, [COLOR]
746 mov ah, al
747 mov cx, 8000h
748 rep stosw
749
750 ; DONE!
751 pop di ; Return state
752 pop bp
753 ret
754
755 ENDP _XClear
756
757
758 ; --------------------------- _XPut_Tile -------------------------------
759 ; - This function will place a tile on the current write screen
760 ; - It will be done a plane at a time and will expect the image data
761 ; - to be laid out one plane at a time.
762 ; - If there is an even number of XBlocks then a word write will be used
763 ; -
764 public _XPut_Tile
765
766 PROC _XPut_Tile FAR
767
768 ARG X_S:WORD, Y_S:WORD, X_D:WORD, Y_D:WORD, IMAGE_OFF:DWORD
769
770 push bp
771 mov bp, sp ; Save Stack frame
772 push ds di si
773
774 cld
775
776 ; Set all data from CPU and non from latches
777 mov dx, GC_INDEX
778 mov ax, 0FF00h + BIT_MASK ; Set all CPU writes
779 out dx, ax
780
781 ; Get the Screen Seg and put it in es and load ds to fardata
782 mov ax, SCREEN_SEG
783 mov es, ax
784
785 ASSUME ds: @fardata
786 mov ax, @fardata
787 mov ds, ax ; Set DS to local fardata
788
789 ; Load CX with the number of XBlocks per image line
790 mov cx, [X_D]
791 shr cx, 1
792 shr cx, 1 ; Divide by 4 to get
793 mov [X_D], cx ; Save CX as new Delta
794
795 ; Load di with destination offset and save it in DEST
796 mov ax, [WLine_Offset] ; Size of line in XBlocks
797 mov bx, ax ; Save in DX
798 mul [Y_S]
799
800 mov di, [X_S]
801 shr di, 1
802 shr di, 1
803
804 add di, [Write_Page]
805 add di, ax ; Di is now loaded
806
807 mov [X_S], di ; Store it. Steal X start
808
809 ; Set [Y_S] to the distance from one scan line to next
810 sub bx, cx ; minus number of XBlocks
811 mov [Y_S], bx ; Move to store
812
813 ; Set BX to the number of scan lines
814 mov bx, [Y_D]
815
816 ; Load ds:si with source
817 lds si, [IMAGE_OFF]
818
819 ; Set up DX and AX for plane selection
820 mov al, 02h ; Select Map Mask
821 mov dx, SC_INDEX
822 out dx, al
823 inc dx
824 mov al, 011h ; Set for plane selection
825
826 ; Save CX in AH
827 mov ah, cl
828
829 ; This section is for the WRITES ------------------------------
830
831 @@PlanesW: ; Master plane loop.
832
833 out dx, al ; Set map mask
834 mov dx, [Y_S] ; Steal DX to speed up add
835
836 @@RowloopW: ; Scan line loop
837
838 ; Do the actual line. REP MOVSW.
839 shr cx, 1 ; Shift for word
840 rep movsw
841 adc cx, 0 ; Add 1(carry) to CX if dangling byte
842 rep movsb ; Write dangle if there
843
844 ; Adjust for next iteration
845 mov cl, ah ; Restore CX
846 add di, dx ; Point DI to start of next line
847
848 ; !!End of Rowloop. Dec BX, if it is NOT 0 then do next line
849 dec bx
850 jnz @@RowloopW
851
852 ; Done with plane. Reset Destination pointers. Adjst plane
853 mov di, [X_S] ; Restore destination
854 mov bx, [Y_D] ; Restore scan line count
855
856 ; !!End of Plane loop.
857 mov dx, (SC_INDEX+1) ; Restore DX for next plane
858 shl al, 1 ; Shift up a plane. Carry set = done
859 jnc @@PlanesW ; If carry set, drop out
860
861 ; !!!DONE
862 pop si di ds ; Return state
863 pop bp
864 ret
865
866 ENDP _XPut_Tile
867
868
869 ; --------------------------- _XTile_Size -----------------------------------
870 ; - This function will return the total number of bytes an image requires
871 ; - Div by 4 will yield the number of XBlocks
872 public _XTile_Size
873
874 PROC _XTile_Size FAR
875
876 ARG X_D:WORD, Y_D:WORD
877
878
879 push bp
880 mov bp, sp ; Save Stack frame
881
882 ; Load AX with the total number of bytes
883 mov cx, [X_D]
884 mov ax, [Y_D]
885 mul cx ; Yield is total bytes
886
887 ; AX holds return
888 pop bp
889 ret
890
891 ENDP _XTile_Size
892
893
894 ; --------------------------- _XUpload_Tile -------------------------------
895 ; - This function will place a tile in the display memory
896 ; - It will be done a plane at a time and will expect the image data
897 ; - to be laid out one plane at a time.
898 ; - The tile will be laid out in a linear manner and even though it may be
899 ; - sent to the current screen it will not be correctly displayed
900 ; -
901 public _XUpload_Tile
902 public _XUpload_Sprite
903 LABEL _XUpload_Sprite FAR
904
905 PROC _XUpload_Tile FAR
906
907 ARG DEST:WORD, ISIZE:WORD, IMAGE_OFF:DWORD
908
909 push bp
910 mov bp, sp ; Save Stack frame
911 push ds di si
912
913 cld
914
915 ; Get the Screen Seg and put it in es
916 mov ax, SCREEN_SEG
917 mov es, ax
918
919
920 ; Load di with destination offset and save it in DEST
921 mov di, [DEST]
922 mov bx, di ; Store it
923
924 ; Load ds:si with source
925 lds si, [IMAGE_OFF]
926
927 ; Get number of XBlocks per plane.
928 mov cx, [ISIZE]
929 shr cx, 1
930 shr cx, 1
931 mov bp, cx ; Save size in BP
932
933 ; Set all data from CPU and non from latches
934 mov dx, GC_INDEX
935 mov ax, 0FF00h + BIT_MASK ; Set all CPU writes
936 out dx, ax
937
938 ; Set up DX and AX for plane selection
939 mov al, 02h ; Select the MAP MASK
940 mov dx, SC_INDEX
941 out dx, al
942 inc dx
943 mov al, 11h ; Plane 0
944
945 ; This section is for WRITES ------------------------------
946 @@BeginWrite:
947
948 @@PlanesW: ; Master plane loop.
949
950 out dx, al ; Set the plane
951
952 ; Do the actual line. REP MOVSW.
953 shr cx, 1 ; Set for word writes
954 rep movsw
955 adc cx, 0 ; Add 1(carry) to CX to see if dangle
956 rep movsb ; Write the dangle if there.
957
958 ; Done with plane. Reset Destination pointers. Adjst plane
959 mov di, bx ; Restore Destination
960 mov cx, bp ; Restore CX.
961
962 ; !!End of Plane loop.
963 shl al, 1 ; Shift plane selector
964 jnc @@PlanesW ; If no carry, then more to do
965
966
967 ; !!DONE!!
968 pop si di ds ; Return state
969 pop bp
970 ret
971
972 ENDP _XUpload_Tile
973
974
975 ; --------------------------- _XPaste_Tile -------------------------------
976 ; - This function will place a tile from the display memory to current screen
977 ; -
978 public _XPaste_Tile
979
980 PROC _XPaste_Tile FAR
981
982
983 ARG X_S:WORD, Y_S:WORD, X_D:WORD, Y_D:WORD, TILE:WORD
984
985 push bp
986 mov bp, sp ; Save Stack frame
987 push ds di si
988
989 cld
990
991 ; Load DS.
992
993 ASSUME ds: @fardata
994 mov ax, @fardata
995 mov ds, ax ; Set DS to segment XTile data
996
997 ; Set DI to start of rectangle on screen
998 mov ax, [WLine_Offset]
999 mul [Y_S] ; Find Y offset value. Place in AX
1000
1001 mov di, [X_S] ; Find X offset value. Place in DI
1002 shr di, 1
1003 shr di, 1
1004
1005 add di, ax ; Add X and Y offsets
1006 add di, [Write_Page] ; Add in page offset
1007
1008 ; Set all data from latches
1009 mov dx, GC_INDEX
1010 mov ax, 00000h + BIT_MASK ; Set all latch writes
1011 out dx, ax
1012
1013 ; Insure Map Mask is set to all planes
1014 mov ax, 0F02h ; 0F sets all planes. 02 is Map Mask
1015 mov dx, SC_INDEX
1016 out dx, ax
1017
1018 ; Load CX with XBlocks per scan line
1019 mov cx, [X_D]
1020 shr cx, 1 ; Div by 4 so we have
1021 shr cx, 1 ; Xblock count
1022
1023 ; Set AX to the distance from one scan line to next
1024 mov ax, [WLine_Offset]
1025 sub ax, cx
1026
1027 ; Set SI to source
1028 mov si, [TILE]
1029
1030 ; Get the Screen Seg and put it in DS and ES
1031 mov dx, SCREEN_SEG
1032 mov ds, dx
1033 mov es, dx
1034
1035 ; Set DX to the number of scan lines
1036 mov dx, [Y_D]
1037
1038 ; Save the CX in BP
1039 mov bp, cx
1040
1041 ; This section is for WRITES ------------------------------
1042 @@Rowloop:
1043
1044 ; Do the actual line. REP MOVSB.
1045 rep movsb
1046
1047 ; Adjust for next iteration
1048 mov cx, bp ; Restore CX.
1049 add di, ax ; Point DI to start of next line
1050
1051 ; End of Rowloop. Dec DX, if it is NOT 0 then do next line
1052 dec dx
1053 jnz @@Rowloop
1054
1055 ; !!DONE!!
1056 pop si di ds ; Return state
1057 pop bp
1058 ret
1059
1060 ENDP _XPaste_Tile;
1061
1062
1063 ;-------------------------- _XPaste_Sprite ------------------------------
1064 ; - This function will place a sprite from the display memory to current screen
1065 ; - It will NOT do masking
1066 public _XPaste_Sprite
1067
1068 PROC _XPaste_Sprite FAR
1069
1070
1071 ARG X_S:WORD, Y_S:WORD, X_D:WORD, Y_D:WORD, TILE:WORD
1072
1073 push bp
1074 mov bp, sp ; Save Stack frame
1075 push ds di si
1076
1077 cld
1078
1079 ; Load DS.
1080
1081 ASSUME ds: @fardata
1082 mov ax, @fardata
1083 mov ds, ax ; Set DS to segment XTile data
1084
1085 ; Set DI to start of rectangle on screen
1086 mov ax, [WLine_Offset]
1087 mul [Y_S] ; Find Y offset value. Place in AX
1088
1089 mov di, [X_S] ; Find X offset value. Place in DI
1090 shr di, 1
1091 shr di, 1
1092
1093 add di, ax ; Add X and Y offsets
1094 add di, [Write_Page] ; Add in page offset
1095
1096 ; Set SI to source
1097 mov si, [TILE]
1098
1099 ; Find adjustment to source for alignment
1100 mov ax, [X_D]
1101 mov cx, [X_S]
1102
1103 shr ax, 1 ; Number of XBlocks a line
1104 shr ax, 1
1105 mul [Y_D] ; Find size of each sprite alignment
1106
1107 and cx, 3 ; Mask all but 2 LSBs
1108
1109 mul cx ; Find new offset
1110
1111 add si, ax ; Adjust SI
1112
1113 ; Get the Screen Seg and put it in DS and ES
1114 mov ax, SCREEN_SEG
1115 mov ds, ax
1116 mov es, ax
1117
1118 ; Set all data from latches
1119 mov dx, GC_INDEX
1120 mov ax, 00000h + BIT_MASK ; Set all latch writes
1121 out dx, ax
1122
1123 ; Insure Map Mask is set to all planes
1124 mov ax, 0F02h ; 0F sets all planes. 02 is Map Mask
1125 mov dx, SC_INDEX
1126 out dx, ax
1127
1128 ; Load CX with XBlocks per scan line
1129 mov cx, [X_D]
1130 shr cx, 1 ; Div by 4 so we have
1131 shr cx, 1 ; Xblock count
1132
1133 ; Set AX to the distance from one scan line to next
1134 mov ax, [WLine_Offset]
1135 sub ax, cx
1136
1137 ; Set DX to the number of scan lines
1138 mov dx, [Y_D]
1139
1140 ; Save CX in BP
1141 mov bp, cx
1142
1143 ; This section is for WRITES ------------------------------
1144 @@Rowloop:
1145
1146 ; Do the actual line. REP MOVSB.
1147 rep movsb
1148
1149 ; Adjust for next iteration
1150 mov cx, bp ; Restore CX.
1151 add di, ax ; Point DI to start of next line
1152
1153 ; End of Rowloop. Dec DX, if it is NOT 0 then do next line
1154 dec dx
1155 jnz @@Rowloop
1156
1157 ; !!DONE!!
1158 pop si di ds ; Return state
1159 pop bp
1160 ret
1161
1162 ENDP _XPaste_Sprite
1163
1164
1165 ; --------------------------- _XPut_Tile_M -------------------------------
1166 ; - This function will place a tile on the current write screen
1167 ; - It will be done a plane at a time and will expect the image data
1168 ; - to be laid out one plane at a time.
1169 ; - All 0 pixels will leave the screen intact.
1170 ; -
1171 public _XPut_Tile_M
1172
1173 PROC _XPut_Tile_M FAR
1174
1175 ARG X_S:WORD, Y_S:WORD, X_D:WORD, Y_D:WORD, IMAGE_OFF:DWORD
1176
1177 push bp
1178 mov bp, sp ; Save Stack frame
1179 push ds di si
1180
1181 cld
1182
1183 ; Get the Screen Seg and put it in es
1184 mov ax, SCREEN_SEG
1185 mov es, ax
1186
1187
1188 ; Load CX with the number of XBlocks per scan line
1189 mov cx, [X_D]
1190 shr cx, 1
1191 shr cx, 1 ; Divide by 4 to get
1192
1193 ; Set [X_D] to the distance from one scan line to next
1194 mov ax, [WLine_Offset]
1195 sub ax, cx
1196 mov [X_D], ax
1197
1198 ; Save number of XBlocks a line in upper cx
1199 mov ch, cl
1200
1201 ; Set BL to the number of scan lines and save
1202 mov bx, [Y_D]
1203
1204 ; Load DS.
1205 ASSUME ds: @fardata
1206 mov ax, @fardata
1207 mov ds, ax ; Set DS to fardata segment
1208
1209 ; Load di with destination offset and save it in DEST
1210 mov ax, [WLine_Offset]
1211 mul [Y_S]
1212
1213 mov di, [X_S]
1214 shr di, 1
1215 shr di, 1 ; Adjust to number of XBlocks
1216
1217 add di, [Write_Page]
1218 add di, ax ; Di is now loaded
1219
1220 mov [X_S], di ; Store it
1221
1222 ; Load ds:si with source
1223 lds si, [IMAGE_OFF]
1224
1225 ; Set all data from CPU and non from latches
1226 mov dx, GC_INDEX
1227 mov ax, 0FF00h + BIT_MASK ; Set all CPU writes
1228 out dx, ax
1229
1230 ; Set up DX and AX for plane selection
1231 mov al, 02h ; Plane 0 selected
1232 mov dx, SC_INDEX
1233 inc dx
1234 mov ax, 0101h ; Set up AX
1235
1236 ; This section is for the WRITE ------------------------------
1237 @@PlanesB: ; Master plane loop.
1238
1239 out dx, al ; Set the plane
1240 @@RowloopB: ; Scan line line
1241
1242 ; Do the actual line.
1243 @@PixelLoop:
1244 lodsb ; Get the pixel
1245 or al, al ; Is it zero
1246 jz @@NoDraw ; If zero, don't draw it
1247 mov [es:di], al ; Else, do draw it
1248
1249 @@NoDraw:
1250 inc si ; Move to next pixel
1251 inc di
1252 dec cl
1253 jnz @@PixelLoop
1254
1255 ; Adjust for next iteration
1256 mov cl, ch ; Restore CL. ( [Pix/line]/4 )
1257 add di, [X_D] ; Point DI to start of next line
1258
1259 ; !!End of Rowloop. Dec SI, if it is NOT 0 then do next line
1260 dec bx
1261 jnz @@RowloopB
1262
1263 ; Done with plane. Reset Destination pointers. Adjst plane
1264 mov di, [X_S] ; Restore destination
1265 mov bx, [Y_D] ; Restore scan line count
1266 shl ah, 1 ; Adjust plane
1267 mov ah, al ; Save the
1268 jnc @@PlanesB ; If no carry, then more planes
1269
1270 ; !!!DONE
1271 pop si di ds ; Return state
1272 ret
1273
1274 ENDP _XPut_Tile_M
1275
1276
1277 ; --------------------------- _XMove_Tile ----------------------------------
1278 ; - This function will move a tile about on the current write page
1279 ; - Coord, Size, and destination must be givin
1280 public _XMove_Tile
1281
1282 PROC _XMove_Tile FAR
1283
1284 ARG X_S:WORD, Y_S:WORD, X_E:WORD, Y_E:WORD, X_D:WORD, Y_D:WORD
1285
1286 push bp
1287 mov bp, sp ; Save Stack frame
1288 push ds si di
1289
1290 cld
1291
1292 ; Load DS.
1293 ASSUME ds: @fardata
1294 mov ax, @fardata
1295 mov ds, ax ; Set DS to fardata segment
1296
1297 ; Load si with source X in XBlocks
1298 mov si, [X_S]
1299 shr si, 1
1300 shr si, 1
1301
1302 ; Load di with destination X in XBlocks
1303 mov di, [X_D]
1304 shr di, 1
1305 shr di, 1
1306
1307 ; Convert [X_E] to width in XBlocks
1308 mov bx, [X_E]
1309 shr bx, 1
1310 shr bx, 1
1311
1312 mov ax, bx ; Save in AX
1313 mov [X_E], bx ; Put back
1314
1315 ; Determine the X direction
1316 cmp si, di
1317 jge @@GoLeft
1318
1319 ; Going right. Copy right to left
1320 add si, ax ; Source starts at right edge
1321 add di, ax ; Same with destination
1322 neg bx ; Make negative
1323 std ; Move backwards on string instructions
1324
1325 ; Determine the Y direction
1326 @@GoLeft:
1327 mov cx, [WLine_Offset]
1328 mov ax, [Y_S] ; Get the Y source start
1329 mov dx, [Y_D] ; Get the Y destination
1330
1331 cmp ax, dx ; Going up or down
1332 jge @@GoUp
1333
1334 ; Rectangle going down. Copy bottom to top
1335 mov ax, [Y_E] ; Get the bottom coord
1336 add dx, ax ; Add it to the destination, so
1337 ; it points to end of destination blk
1338 neg cx ; Make CX negative
1339 add ax, [Y_S] ; Point AX to end of source blk
1340 ; By adding size to start
1341
1342 ; Calcuate the offsets
1343 @@GoUp:
1344 push dx ; Save DX the torment of a multiply
1345 mul [WLine_Offset] ; Find Y adder for source
1346 add si, ax ; Add it
1347
1348 pop ax ; Pop off the destination Y into AX
1349 mul [WLine_Offset] ; Find Y adder for destination
1350 add di, ax ; Add it
1351
1352 sub cx, bx ; Find the scan line data
1353
1354 ; Add in the write page offset
1355 add si, [Write_Page]
1356 add di, [Write_Page]
1357
1358 ; Get the Screen Seg and put it in DS and ES
1359 mov ax, SCREEN_SEG
1360 mov ds, ax
1361 mov es, ax
1362
1363 ; Set all data from latches
1364 mov dx, GC_INDEX
1365 mov ax, 00000h + BIT_MASK ; Set all latch writes
1366 out dx, ax
1367
1368 ; Insure Map Mask is set to all planes
1369 mov ax, 0F02h ; 0F sets all planes. 02 is Map Mask
1370 mov dx, SC_INDEX
1371 out dx, ax
1372
1373 ; Set AX to the Scan line lenghth
1374 mov ax, [X_E]
1375
1376 ; Set BX to the Y size
1377 mov bx, [Y_E]
1378
1379 ; Set DX to the Scan line differential
1380 mov dx, cx
1381
1382 ; Do the WRITES---------------------
1383 @@ScanLoop:
1384
1385 mov cx, ax ; Set cx to the Scan size
1386 rep movsb ; Do the line
1387
1388 ; Add the scan line differential to source and dest
1389 add si, dx
1390 add di, dx
1391
1392 ; See if done with all lines
1393 dec bx
1394 jnz @@ScanLoop ; No, then go and do another line
1395
1396 ; !!DONE!!
1397 pop di si ds
1398 pop bp ; Return state
1399 ret
1400
1401 ENDP _XMove_Tile
1402
1403
1404 ; --------------------------- _XRegister_Font8 ------------------------------
1405 ; - This function will register a 8-font.
1406 ; - The function will return in AX the actual number of bytes used.
1407 ; - The function expects each character to be laid out as for Upload_Tile,
1408 ; - one character at a time. Each character is 8x by 10y.
1409
1410 public _XRegister_Font8
1411
1412 PROC _XRegister_Font8 FAR
1413
1414 ARG DEST:WORD, NUMBER:WORD, BASE:WORD, UPLOAD:WORD, FONT_OFF:DWORD
1415
1416 push bp
1417 mov bp, sp ; Save Stack frame
1418 push ds di si
1419
1420 cld
1421
1422 ; Load DS.
1423 ASSUME ds: @fardata
1424 mov ax, @fardata
1425 mov ds, ax ; Set DS to fardata segment
1426
1427 ; Save the base char
1428 mov ax, [BASE]
1429 mov [Char_Base8], ax
1430
1431 ; Will we upload this font?
1432 mov cx, [UPLOAD]
1433 mov [UpLoaded8], cx ; Flag it ( 0 is uploaded )
1434 jcxz @@UploadFont ; Yes!, then jump to it
1435
1436 ; Don't upload this font. Just register and return.
1437 les si, [FONT_OFF]
1438 mov [Font_SiteD8], si
1439 mov ax, es
1440 mov [Font_SiteD8+2], ax
1441 jmp @@DONE
1442
1443 @@UploadFont:
1444 ; Check font size to insure no overrun
1445 mov dx, 20
1446 mov ax, [NUMBER]
1447 mul dx ; Mul number of chars by 20bytes
1448 add ax, [DEST] ; Add destination to get proposed end
1449 cmp ax, STORE ; Where is it in relation to begin
1450 ja @@CONT ; If above, no wrap of AX, OK
1451 mov ax, 0 ; Else leave 0 in AX, indicating ERR
1452 jmp @@DONE ; And jump out
1453
1454 @@CONT:
1455 ; Save the size and location
1456 mov ax, [DEST]
1457 mov [Font_SiteU8], ax
1458
1459 ; Load di with destination offset and save it in DX
1460 mov di, ax ; AX retains it from prev action
1461 mov dx, ax ; Store it
1462
1463 ; Load ds:si with source
1464 lds si, [FONT_OFF]
1465
1466 ; Load es with SCREEN SEG
1467 mov ax, SCREEN_SEG
1468 mov es, ax
1469
1470 ; This section iterates for each char----------------------------
1471 mov bx, [NUMBER] ; Set BL to number of characters
1472
1473 ; Set BP to destination, as was in DX
1474 mov bp, dx
1475
1476 ; Set all data from CPU and non from latches
1477 mov dx, GC_INDEX
1478 mov ax, 0FF00h + BIT_MASK ; Set all CPU writes
1479 out dx, ax
1480
1481 ; Set up DX plane selection
1482 mov dx, SC_INDEX
1483
1484 ; Set CX to number of scan lines in a char
1485 mov cx, 10 ; Set CX to 10 scan lines
1486
1487 @@BeginWrite:
1488
1489 ; Set AX up for plane selection
1490 mov ax, 1102h ; Plane 0 selected
1491
1492 ; This section loops through the planes for each char -----------
1493 @@PlanesW: ; Master plane loop.
1494
1495 out dx, ax ; Set the plane
1496
1497 ; Do the actual line. REP MOVSW. Move both XBlocks on each line
1498 rep movsw
1499
1500 ; Done with plane. Reset Destination pointers. Adjst plane
1501 mov di, bp
1502 shl ah, 1 ; Adjust plane. Carry set if done
1503 mov cx, 10 ; Restore CX.
1504
1505 ; !!End of Plane loop.
1506 jnc @@PlanesW ; If no carry, not done with char
1507
1508 ; !!End of Char loop.
1509
1510 add bp, 20 ; Adjust destination for next char
1511 mov di, bp ; Store it in DI
1512
1513 dec bx ; Another char done
1514 jnz @@BeginWrite ; If not zero, not done with font set
1515
1516 ; !!DONE!!
1517 @@DONE:
1518 pop si di ds ; Return state
1519 pop bp
1520 ret
1521
1522 ENDP _XRegister_Font8
1523
1524
1525 ; ----------------------------- _XChar8 ----------------------------------
1526 ; - This function will place a char from the current font to current screen
1527 ; - Uses the 8pix font
1528 public _XChar8
1529
1530 PROC _XChar8 FAR
1531
1532 ARG X_S:WORD, Y_S:WORD, CHAR:WORD
1533
1534 push bp
1535 mov bp, sp ; Save Stack frame
1536 push ds di si
1537
1538 cld
1539
1540 ; Load DS.
1541 ASSUME ds: @fardata
1542 mov ax, @fardata
1543 mov ds, ax ; Set DS to segment w/ Table
1544
1545 ; Set DI to start of character on screen
1546 mov ax, [WLine_Offset]
1547 mul [Y_S] ; Find Y offset value. Place in AX
1548
1549 mov di, [X_S] ; Find X offset value. Place in DI
1550 shr di, 1
1551 shr di, 1 ; Adjust to number of XBlocks
1552
1553 add di, ax ; Add X and Y offsets
1554 add di, [Write_Page] ; Add in page offset
1555
1556 ; Is the font uploaded or not
1557 mov ax, [UpLoaded8]
1558 cmp ax, UPLOADFONT
1559 je @@FontIsUploaded ; The font is uploaded
1560
1561 ; - Font is not uploaded
1562 ; Set CX to the scan line differential
1563 mov cx, [WLine_Offset]
1564 sub cx, 2 ; Subtract the XBlocks of a char
1565
1566 ; Figure character offset and add to load ds:si font site
1567 mov ax, 80 ; Put font size in ax
1568 xor bx, bx ; Clear bx
1569 mov bx, [CHAR] ; Put character place in BX
1570 sub bx, [Char_Base8] ; Subtract base char
1571 mul bx ; Mul size by place
1572 lds si, [Font_Addr8]
1573 add si, ax
1574
1575 ; Move the scan line differential from CX to BP
1576 mov bp, cx
1577
1578 ; Save the base destination in CX
1579 mov cx, di
1580
1581 ; Get the Screen Seg and put it in ES
1582 mov ax, SCREEN_SEG
1583 mov es, ax
1584
1585 ; Set all data from CPU and non from latches
1586 mov dx, GC_INDEX
1587 mov ax, 0FF00h + BIT_MASK ; Set all CPU writes
1588 out dx, ax
1589
1590 ; Set up DX and AX for plane selection
1591 mov ax, 1102h ; Plane 0 selected
1592 mov dx, SC_INDEX
1593
1594 ; This section is for WRITES ------------------------------
1595
1596 ; Set BH to number of lines to do
1597 mov bx, 10 ; 10 scan lines per 8-pix font
1598
1599 @@PlanesW: ; Master plane loop.
1600
1601 out dx, ax ; Set the plane
1602
1603 @@RowloopW: ; Scan line loop
1604
1605 ; Do the actual line. MOVSW.
1606 movsw
1607
1608 ; Adjust for next iteration
1609 add di, bp ; Point DI to start of next line
1610
1611 ; !!End of Rowloop. Dec BH, if it is NOT 0 then do next line
1612 dec bx
1613 jnz @@RowloopW
1614
1615 ; Done with plane. Reset Destination pointers. Adjst plane
1616 mov di, cx ; Restore the destination start
1617 mov bx, 10 ; Restore scan line count
1618 shl ah, 1 ; Adjust plane
1619
1620 ; !!End of Plane loop.
1621 jnc @@PlanesW ; If no carry, then more to do.
1622
1623
1624
1625 ; Done with this
1626 jmp @@DONE
1627
1628
1629 ; - Font is uploaded
1630 @@FontIsUploaded:
1631 ; Calc the source and put in SI
1632 mov si, [Font_SiteU8] ; Get base location
1633 mov ax, 20 ; Put font size in ax (in XBlock)
1634 mov bx, [CHAR] ; Put character place in BX
1635 sub bx, [Char_Base8] ; Subtract base char
1636 mul bx ; Mul size by place
1637 add si, ax ; Put in SI
1638
1639 ; Insure Map Mask is set to all planes
1640 mov ax, 0F02h ; 0F sets all planes. 02 is Map Mask
1641 mov dx, SC_INDEX
1642 out dx, ax
1643
1644 ; Set all data from latches
1645 mov dx, GC_INDEX
1646 mov ax, 00000h + BIT_MASK ; Set all latch writes
1647 out dx, ax
1648
1649 ; Set AX to line dif.
1650 mov ax, [WLine_Offset] ; Page width
1651 sub ax, 2 ; minus XBlocks per char
1652
1653 ; Get the Screen Seg and put it in DS and ES
1654 mov dx, SCREEN_SEG
1655 mov ds, dx
1656 mov es, dx
1657
1658 ; Set CX to the number of scan lines
1659 mov cx, 10
1660
1661 ; This section is for WRITES ------------------------------
1662 @@Rowloop:
1663
1664 ; Do the actual line. MOVSB.
1665 movsb
1666 movsb
1667
1668 ; Adjust for next iteration
1669 add di, ax ; Point DI to start of next line
1670
1671 ; End of Rowloop.
1672 loop @@Rowloop
1673
1674 ; !!DONE!!
1675 @@DONE:
1676 pop si di ds ; Return state
1677 pop bp
1678 ret
1679
1680 ENDP _XChar8;
1681
1682
1683 ; ------------------------ _Register_Font_Masks8 ---------------------------
1684 ; - This function registers a font mask for the current 8pix font
1685 ; - This mask can be used for MFont character drawing
1686 public _Register_Font_Masks8
1687
1688 PROC _Register_Font_Masks8 FAR
1689
1690 ARG MASK_OFF:WORD, MASK_SEG:WORD
1691
1692 push bp
1693 mov bp, sp ; Save Stack frame
1694 push ds
1695
1696 ; Load DS.
1697 ASSUME ds: @fardata
1698 mov ax, @fardata
1699 mov ds, ax ; Set DS to fardata segment
1700
1701 ; Move location to local
1702 mov ax, [MASK_OFF]
1703 mov [Font_Mask_O8], ax
1704
1705 mov ax, [MASK_SEG]
1706 mov [Font_Mask_S8], ax
1707
1708 ; !!DONE!!
1709 pop ds
1710 pop bp ; Return state
1711 ret
1712
1713 ENDP _Register_Font_Masks8
1714
1715
1716 ; ----------------------------- _XChar8_M ----------------------------------
1717 ; - This function will place a char from the current font to current screen
1718 ; - This function requires a font mask set to be registered.
1719 ; - Uses the 8pix font
1720 public _XChar8_M
1721
1722 PROC _XChar8_M FAR
1723
1724 ARG X_S:WORD, Y_S:WORD, CHAR:WORD
1725
1726
1727 push bp
1728 mov bp, sp ; Save Stack frame
1729 push ds di si
1730
1731 cld
1732
1733 ; Load DS.
1734 ASSUME ds: @fardata
1735 mov ax, @fardata
1736 mov ds, ax ; Set DS to fardata segment
1737
1738 ; Set DI to start of rectangle on screen
1739 mov ax, [WLine_Offset]
1740 mov bx, ax ; Save in BX for later
1741 mul [Y_S] ; Find Y offset value. Place in AX
1742
1743 mov di, [X_S] ; Find X offset value. Place in DI
1744 shr di, 1
1745 shr di, 1
1746
1747 add di, ax ; Add X and Y offsets
1748 add di, [Write_Page] ; Add in page offset
1749
1750 ; Is the font uploaded or not
1751 mov cx, [UpLoaded8] ; UPLOADED is 0!
1752 jcxz @@Uploaded ; The font is uploaded
1753
1754 ; - Font is not uploaded
1755
1756 ; Figure character offset and add to load ds:si font site
1757 mov ax, 80 ; Put font size in ax
1758 mov cx, [CHAR] ; Put character place in BX
1759 sub cx, [Char_Base8] ; Subtract base char
1760 mul cx ; Mul size by place
1761 lds si, [Font_Addr8]
1762 add si, ax
1763
1764 ; Set BX to the line differential
1765 dec bx ; BX was set above - first XBlock
1766
1767 ; Save the base destination in BP
1768 mov bp, di
1769
1770 ; Get the Screen Seg and put it in ES
1771 mov ax, SCREEN_SEG
1772 mov es, ax
1773
1774 ; Set all data from CPU and non from latches
1775 mov dx, GC_INDEX
1776 mov ax, 0FF00h + BIT_MASK ; Set all CPU writes
1777 out dx, ax
1778
1779 ; Set up DX and AX for plane selection
1780 mov ax, 0102h ; Plane 0 selected
1781 mov dx, SC_INDEX
1782
1783 ; This section is for WORD WRITES ------------------------------
1784
1785 ; Set CX to number of lines to do
1786 mov cx, 10 ; 10 scan lines per 8-pix font
1787
1788 @@PlanesW: ; Master plane loop.
1789
1790 out dx, ax ; Set the plane
1791
1792 @@RowloopW: ; Scan line loop
1793
1794 ; Do the actual DRAW. MOV.
1795 lodsb ; Get the pixel
1796 or al, al ; Is it zero
1797 jz @@NoDraw1 ; If zero, don't draw it
1798 mov [es:di], al ; Else, do draw it
1799
1800 @@NoDraw1:
1801 inc di
1802
1803 lodsb ; Get the pixel
1804 or al, al ; Is it zero
1805 jz @@NoDraw2 ; If zero, don't draw it
1806 mov [es:di], al ; Else, do draw it
1807
1808 @@NoDraw2:
1809 ; Adjust for next iteration
1810 add di, bx ; Point DI to start of next line
1811
1812 ; !!End of Rowloop. Dec CX, if it is NOT 0 then do next line
1813 loop @@RowloopW
1814
1815 ; Done with plane. Reset Destination pointers. Adjst plane
1816 mov di, bp ; Restore the destination start
1817 mov cx, 10 ; Restore scan line count
1818
1819 mov al, 02h ; Restore MAP MASK pointer
1820 shl ah, 1 ; Adjust plane
1821
1822 ; !!End of Plane loop. If carry not set, then not done
1823 jnc @@PlanesW
1824
1825 ; Done with this
1826 jmp @@DONE
1827
1828
1829 @@Uploaded:
1830 ; - Font is uploaded
1831 ; Set SI to mask offset
1832 mov ax, 10 ; Put mask size in ax
1833 mov cx, [CHAR] ; Put character place in CX
1834 sub cx, [Char_Base8] ; Subtract base char
1835 mul cx ; Mul size by place
1836 add ax, [Font_Mask_O8] ; Find masks offset in mask set
1837 mov si, ax ; Save it
1838
1839 ; Calc the source and put in BX
1840 mov bx, [Font_SiteU8] ; Get base location
1841 mov ax, 20 ; Put font size in ax
1842 mov cx, [CHAR] ; Put character place in BX
1843 sub cx, [Char_Base8] ; Subtract base char
1844 mul cx ; Mul size by place
1845 add bx, ax ; Put in SI
1846
1847 ; Set BP to the scan line differential
1848 mov bp, [WLine_Offset]
1849 dec bp
1850
1851 ; Set DS to mask area
1852 mov ax, [Font_Mask_S8]
1853 mov ds, ax
1854
1855 ; Get the Screen Seg and put it in ES
1856 mov ax, SCREEN_SEG
1857 mov es, ax
1858
1859 ; Set all data from latches
1860 mov dx, GC_INDEX
1861 mov ax, 00000h + BIT_MASK ; Set all latch writes
1862 out dx, ax
1863
1864 ; Set up Map Mask
1865 mov al, 02h ; 02 is Map Mask
1866 mov dx, SC_INDEX
1867 out dx, al
1868 inc dx
1869
1870 ; Set CH to the number of scan lines
1871 mov ch, 10
1872
1873 ; Set CL to shift spaces
1874 mov cl, 4
1875
1876 ; This section is for WRITES ------------------------------
1877 @@Rowloop:
1878 ; This section prep the Map Mask
1879 lodsb ; Get mask byte
1880
1881 ; Set mask for first write
1882 out dx, al ; Set map mask
1883
1884 ; Write the first byte
1885 mov ah, [es:bx]
1886 mov [es:di], ah
1887
1888 ; Adjust di, bx
1889 inc di
1890 inc bx
1891
1892 ; Set mask for second write
1893 shr al, cl ; Move upper nibble down
1894 out dx, al ; Set map mask
1895
1896 ; Write the second byte
1897 mov ah, [es:bx]
1898 mov [es:di], ah
1899
1900 ; Adjust bx
1901 inc bx
1902
1903 ; Adjust for next iteration
1904 add di, bp ; Point DI to start of next line
1905
1906 ; End of Rowloop.
1907 dec ch
1908 jnz @@Rowloop
1909
1910 ; !!DONE!!
1911 @@DONE:
1912 pop si di ds ; Return state
1913 pop bp
1914 ret
1915
1916 ENDP _XChar8_M;
1917
1918
1919 ;----------------------------- _XString8 ----------------------------------
1920 ; - This function will place a char from the current font to current screen
1921 ; - It will use the masked font on mask flag set to not 0.
1922 public _XString8
1923
1924 PROC _XString8 FAR
1925
1926 ARG X_S:WORD, Y_S:WORD, MASKIT:WORD, STR_OFF:DWORD
1927
1928 push bp
1929 mov bp, sp ; Save Stack frame
1930 push ds di si
1931
1932 ; Load DS.
1933 ASSUME ds: @fardata
1934 mov ax, @fardata
1935 mov ds, ax ; Set DS to segment w/ Table
1936
1937 ; Move flag into CX
1938 mov cx, [MASKIT]
1939
1940 ; Load DS:SI
1941 lds si, [STR_OFF]
1942
1943 ; !!! This is the master string loop
1944 @@STRING:
1945 xor ax, ax
1946 mov al, [ds:si] ; Get the char
1947 cmp al, 0 ; Is it the EOS
1948 je @@DONE ; If so jump
1949
1950 ; Save cx
1951 push cx
1952
1953 ; Build stack frame
1954 push ax ; Push the char
1955 push [Y_S] ; Push the Y coor
1956 push [X_S] ; Push the X coor
1957 ; To mask or not to mask
1958 jcxz @@DontMask ; If Flag = 0, dont mask
1959 call _XChar8_M ; Put the masked char
1960 jmp @@Continue
1961
1962 @@DontMask:
1963 call _XChar8 ; Don't mask
1964
1965 @@Continue:
1966 add sp, 6 ; Adjust the stack
1967
1968 pop cx ; Restore cx
1969
1970 add [X_S], 8 ; Move the cursor
1971 inc si ; Point to next char
1972 jmp @@STRING ; Continue
1973
1974 ; !!DONE!!
1975 @@DONE:
1976 pop si di ds ; Return state
1977 pop bp
1978 ret
1979
1980 ENDP _XString8
1981
1982
1983 ; --------------------------- _XRegister_Font4 ------------------------------
1984 ; - This function will register a 4-font.
1985 ; - The function will return in AX the actual number of bytes used.
1986 ; - The function expects each character to be laid out as for Upload_Tile,
1987 ; - one character at a time. Each character is 4x by 6y.
1988
1989 public _XRegister_Font4
1990
1991 PROC _XRegister_Font4 FAR
1992
1993 ARG DEST:WORD, NUMBER:WORD, BASE:WORD, UPLOAD:WORD, FONT_OFF:DWORD
1994
1995 push bp
1996 mov bp, sp ; Save Stack frame
1997 push ds di si
1998
1999 cld
2000
2001 ; Load DS.
2002 ASSUME ds: @fardata
2003 mov ax, @fardata
2004 mov ds, ax ; Set DS to fardata segment
2005
2006 ; Save the base char
2007 mov ax, [BASE]
2008 mov [Char_Base4], ax
2009
2010 ; Will we upload this font?
2011 mov cx, [UPLOAD]
2012 mov [UpLoaded4], cx ; Flag it ( 0 is uploaded )
2013 jcxz @@UploadFont ; Yes!, then jump to it
2014
2015 ; Don't upload this font. Just register and return.
2016 les si, [FONT_OFF]
2017 mov [Font_SiteD4], si
2018 mov ax, es
2019 mov [Font_SiteD4+2], ax
2020 jmp @@DONE
2021
2022 @@UploadFont:
2023 ; Check font size to insure no overrun
2024 mov dx, 6
2025 mov ax, [NUMBER]
2026 mul dx ; Mul number of chars by 20bytes
2027 add ax, [DEST] ; Add destination to get proposed end
2028 cmp ax, STORE ; Where is it in relation to begin
2029 ja @@CONT ; If above, no wrap of AX, OK
2030 mov ax, 0 ; Else leave 0 in AX, indicating ERR
2031 jmp @@DONE ; And jump out
2032
2033 @@CONT:
2034 ; Save the size and location
2035 mov ax, [DEST]
2036 mov [Font_SiteU4], ax
2037
2038 ; Load di with destination offset and save it in DX
2039 mov di, ax ; AX retains it from prev action
2040 mov dx, di ; Store it
2041
2042 ; Load ds:si with source
2043 lds si, [FONT_OFF]
2044
2045 ; Load es with SCREEN SEG
2046 mov ax, SCREEN_SEG
2047 mov es, ax
2048
2049 ; This section iterates for each char----------------------------
2050 mov bx, [NUMBER] ; Set BX to number of characters
2051
2052 ; Set BP to destination
2053 mov bp, dx ; From above.
2054
2055 ; Set all data from CPU and non from latches
2056 mov dx, GC_INDEX
2057 mov ax, 0FF00h + BIT_MASK ; Set all CPU writes
2058 out dx, ax
2059
2060 ; Set up DX plane selection
2061 mov dx, SC_INDEX
2062
2063 @@BeginWrite:
2064
2065 ; Set AX up for plane selection
2066 mov ax, 1102h ; Plane 0 selected
2067
2068 ; This section loops through the planes for each char -----------
2069 @@PlanesB: ; Master plane loop.
2070
2071 out dx, ax ; Set the plane
2072
2073 ; Do the actual write. MOVSB. Move 6 single XBlocks on each line
2074 movsb ; 1
2075 movsb ; 2
2076 movsb ; 3
2077 movsb ; 4
2078 movsb ; 5
2079 movsb ; 6
2080
2081 @@EndPlane:
2082 ; Done with plane. Reset Destination pointers. Adjst plane
2083 mov di, bp
2084 shl ah, 1 ; Adjust plane. Carry set if done
2085
2086 ; !!End of Plane loop.
2087 jnc @@PlanesB ; If no carry, not done with char
2088
2089 ; !!End of Char loop.
2090
2091 add bp, 6 ; Adjust destination for next char
2092 mov di, bp ; Store it in DI
2093
2094 dec bx ; Another char done
2095 jnz @@BeginWrite ; If not zero, not done with font set
2096
2097 ; !!DONE!!
2098 @@DONE:
2099 pop si di ds ; Return state
2100 pop bp
2101 ret
2102
2103 ENDP _XRegister_Font4
2104
2105
2106 ; ----------------------------- _XChar4 ----------------------------------
2107 ; - This function will place a char from the current font to current screen
2108 ; - Uses the 8pix font
2109 public _XChar4
2110
2111 PROC _XChar4 FAR
2112
2113 ARG X_S:WORD, Y_S:WORD, CHAR:WORD
2114
2115 push bp
2116 mov bp, sp ; Save Stack frame
2117 push ds di si
2118
2119 cld
2120
2121 ; Load DS.
2122 ASSUME ds: @fardata
2123 mov ax, @fardata
2124 mov ds, ax ; Set DS to segment w/ Table
2125
2126 ; Set DI to start of character on screen
2127 mov ax, [WLine_Offset]
2128 mul [Y_S] ; Find Y offset value. Place in AX
2129
2130 mov di, [X_S] ; Find X offset value. Place in DI
2131 shr di, 1
2132 shr di, 1 ; Adjust to number of XBlocks
2133
2134 add di, ax ; Add X and Y offsets
2135 add di, [Write_Page] ; Add in page offset
2136
2137 ; Is the font uploaded or not
2138 mov ax, [UpLoaded4]
2139 cmp ax, UPLOADFONT
2140 je @@FontIsUploaded ; The font is uploaded
2141
2142 ; - Font is not uploaded
2143 ; Set CX to the scan line differential
2144 mov cx, [WLine_Offset]
2145 dec cx ; Subtract the XBlock of a char
2146
2147 ; Figure character offset and add to load ds:si font site
2148 mov ax, 24 ; Put font size in ax
2149 mov bx, [CHAR] ; Put character place in BX
2150 sub bx, [Char_Base4] ; Subtract base char
2151 mul bx ; Mul size by place
2152 lds si, [Font_Addr4]
2153 add si, ax
2154
2155 ; Save the base destination in BX
2156 mov bx, di
2157
2158 ; Get the Screen Seg and put it in ES
2159 mov ax, SCREEN_SEG
2160 mov es, ax
2161
2162 ; Set all data from CPU and non from latches
2163 mov dx, GC_INDEX
2164 mov ax, 0FF00h + BIT_MASK ; Set all CPU writes
2165 out dx, ax
2166
2167 ; Set up DX and AX for plane selection
2168 mov ax, 1102h ; Plane 0 selected
2169 mov dx, SC_INDEX
2170
2171 ; This section is for WRITES ------------------------------
2172
2173 @@PlanesW: ; Master plane loop.
2174
2175 out dx, ax ; Set the plane
2176
2177 ; Put a plane. Completely un-rolled
2178
2179 ; Do line # 1
2180 movsb
2181 add di, cx ; Point DI to start of next line
2182
2183 ; Do line # 2
2184 movsb
2185 add di, cx ; Point DI to start of next line
2186
2187 ; Do line # 3
2188 movsb
2189 add di, cx ; Point DI to start of next line
2190
2191 ; Do line # 4
2192 movsb
2193 add di, cx ; Point DI to start of next line
2194
2195 ; Do line # 5
2196 movsb
2197 add di, cx ; Point DI to start of next line
2198
2199 ; Do line # 6
2200 movsb
2201
2202
2203 ; Done with plane. Reset Destination pointers. Adjst plane
2204 mov di, bx ; Restore the destination start
2205 shl ah, 1 ; Adjust plane
2206
2207 ; !!End of Plane loop.
2208 jnc @@PlanesW ; If no carry, then more to do.
2209
2210
2211 ; Done with this
2212 jmp @@DONE
2213
2214
2215 ; - Font is uploaded
2216 @@FontIsUploaded:
2217 ; Calc the source and put in SI
2218 mov si, [Font_SiteU4] ; Get base location
2219 mov ax, 6 ; Put font size in ax
2220 xor bx, bx ; Clear bx
2221 mov bx, [CHAR] ; Put character place in BX
2222 sub bx, [Char_Base4] ; Subtract base char
2223 mul bx ; Mul size by place
2224 add si, ax ; Put in SI
2225
2226 ; Insure Map Mask is set to all planes
2227 mov ax, 0F02h ; 0F sets all planes. 02 is Map Mask
2228 mov dx, SC_INDEX
2229 out dx, ax
2230
2231 ; Set all data from latches
2232 mov dx, GC_INDEX
2233 mov ax, 00000h + BIT_MASK ; Set all latch writes
2234 out dx, ax
2235
2236 ; Set AX to line dif.
2237 mov ax, [WLine_Offset] ; Page width
2238 dec ax ; minus XBlocks per char
2239
2240 ; Get the Screen Seg and put it in DS and ES
2241 mov dx, SCREEN_SEG
2242 mov ds, dx
2243 mov es, dx
2244
2245 ; This section is for WRITES ------------------------------
2246
2247 ; - Completely un-rolled
2248
2249 ; Scan line #1
2250 movsb
2251 add di, ax ; Point DI to start of next line
2252
2253 ; Scan line #2
2254 movsb
2255 add di, ax ; Point DI to start of next line
2256
2257 ; Scan line #3
2258 movsb
2259 add di, ax ; Point DI to start of next line
2260
2261 ; Scan line #4
2262 movsb
2263 add di, ax ; Point DI to start of next line
2264
2265 ; Scan line #5
2266 movsb
2267 add di, ax ; Point DI to start of next line
2268
2269 ; Scan line #6
2270 movsb
2271
2272
2273 ; !!DONE!!
2274 @@DONE:
2275 pop si di ds ; Return state
2276 pop bp
2277 ret
2278
2279 ENDP _XChar4;
2280
2281
2282 ; ------------------------ _Register_Font_Masks4 ---------------------------
2283 ; - This function registers a font mask for the current 4pix font
2284 ; - This mask can be used for MFont character drawing
2285 public _Register_Font_Masks4
2286
2287 PROC _Register_Font_Masks4 FAR
2288
2289 ARG MASK_OFF:WORD, MASK_SEG:WORD
2290
2291 push bp
2292 mov bp, sp ; Save Stack frame
2293 push ds
2294
2295 ; Load DS.
2296 ASSUME ds: @fardata
2297 mov ax, @fardata
2298 mov ds, ax ; Set DS to fardata segment
2299
2300 ; Move location to local
2301 mov ax, [MASK_OFF]
2302 mov [Font_Mask_O4], ax
2303
2304 mov ax, [MASK_SEG]
2305 mov [Font_Mask_S4], ax
2306
2307 ; !!DONE!!
2308 pop ds
2309 pop bp ; Return state
2310 ret
2311
2312 ENDP _Register_Font_Masks4
2313
2314
2315 ; ----------------------------- _XChar4_M ----------------------------------
2316 ; - This function will place a char from the current font to current screen
2317 ; - This function requires a font mask set to be registered.
2318 ; - Uses the 4pix font
2319 public _XChar4_M
2320
2321 PROC _XChar4_M FAR
2322
2323 ARG X_S:WORD, Y_S:WORD, CHAR:WORD
2324
2325
2326 push bp
2327 mov bp, sp ; Save Stack frame
2328 push ds di si
2329
2330 cld
2331
2332 ; Load DS.
2333 ASSUME ds: @fardata
2334 mov ax, @fardata
2335 mov ds, ax ; Set DS to fardata segment
2336
2337 ; Set DI to start of rectangle on screen
2338 mov ax, [WLine_Offset]
2339 mov bx, ax ; Save in BX as S/L differential
2340 mul [Y_S] ; Find Y offset value. Place in AX
2341
2342 mov di, [X_S] ; Find X offset value. Place in DI
2343 shr di, 1
2344 shr di, 1
2345
2346 add di, ax ; Add X and Y offsets
2347 add di, [Write_Page] ; Add in page offset
2348
2349 ; Is the font uploaded or not
2350 mov cx, [UpLoaded4] ; UPLOADED is 0!
2351 jcxz @@Uploaded ; The font is uploaded
2352
2353 ; - Font is not uploaded
2354
2355 ; Figure character offset and add to load ds:si font site
2356 mov ax, 24 ; Put font size in ax
2357 mov cx, [CHAR] ; Put character place in BX
2358 sub cx, [Char_Base4] ; Subtract base char
2359 mul cx ; Mul size by place
2360 lds si, [Font_Addr4]
2361 add si, ax
2362
2363 ; Save the base destination in CX
2364 mov cx, di
2365
2366 ; Get the Screen Seg and put it in ES
2367 mov ax, SCREEN_SEG
2368 mov es, ax
2369
2370 ; Set all data from CPU and non from latches
2371 mov dx, GC_INDEX
2372 mov ax, 0FF00h + BIT_MASK ; Set all CPU writes
2373 out dx, ax
2374
2375 ; Set up DX and AX for plane selection
2376 mov ax, 0102h ; Plane 0 selected
2377 mov dx, SC_INDEX
2378
2379 ; This section is for WORD WRITES ------------------------------
2380
2381 @@PlanesW: ; Master plane loop.
2382
2383 out dx, ax ; Set the plane
2384
2385
2386 ; Do the actual DRAW. MOV. Completely un-rolled!!
2387
2388 ; Scan line #1
2389 lodsb ; Get the pixel
2390 or al, al ; Is it zero
2391 jz @@NoDraw1 ; If zero, don't draw it
2392 mov [es:di], al ; Else, do draw it
2393 @@NoDraw1:
2394 add di, bx ; Point DI to start of next line
2395
2396 ; Scan line #2
2397 lodsb ; Get the pixel
2398 or al, al ; Is it zero
2399 jz @@NoDraw2 ; If zero, don't draw it
2400 mov [es:di], al ; Else, do draw it
2401 @@NoDraw2:
2402 add di, bx ; Point DI to start of next line
2403
2404 ; Scan line #3
2405 lodsb ; Get the pixel
2406 or al, al ; Is it zero
2407 jz @@NoDraw3 ; If zero, don't draw it
2408 mov [es:di], al ; Else, do draw it
2409 @@NoDraw3:
2410 add di, bx ; Point DI to start of next line
2411
2412 ; Scan line #4
2413 lodsb ; Get the pixel
2414 or al, al ; Is it zero
2415 jz @@NoDraw4 ; If zero, don't draw it
2416 mov [es:di], al ; Else, do draw it
2417 @@NoDraw4:
2418 add di, bx ; Point DI to start of next line
2419
2420 ; Scan line #5
2421 lodsb ; Get the pixel
2422 or al, al ; Is it zero
2423 jz @@NoDraw5 ; If zero, don't draw it
2424 mov [es:di], al ; Else, do draw it
2425 @@NoDraw5:
2426 add di, bx ; Point DI to start of next line
2427
2428 ; Scan line #6
2429 lodsb ; Get the pixel
2430 or al, al ; Is it zero
2431 jz @@NoDraw6 ; If zero, don't draw it
2432 mov [es:di], al ; Else, do draw it
2433 @@NoDraw6:
2434
2435
2436 ; Done with plane. Reset Destination pointers. Adjst plane
2437 mov di, cx ; Restore the destination start
2438
2439 mov al, 02h ; Restore MAP MASK pointer
2440 shl ah, 1 ; Adjust plane
2441
2442 ; !!End of Plane loop. If carry not set, then not done
2443 jnc @@PlanesW
2444
2445 ; Done with this
2446 jmp @@DONE
2447
2448
2449 @@Uploaded:
2450 ; - Font is uploaded
2451 ; Set SI to mask offset
2452 mov ax, 3 ; Put mask size in ax
2453 mov cx, [CHAR] ; Put character place in CX
2454 sub cx, [Char_Base4] ; Subtract base char
2455 mul cx ; Mul size by place
2456 add ax, [Font_Mask_O4] ; Find masks offset in mask set
2457 mov si, ax ; Save it
2458
2459 ; Calc the source and put in BX
2460 mov bx, [Font_SiteU4] ; Get base location
2461 mov ax, 6 ; Put font size in ax
2462 mov cx, [CHAR] ; Put character place in BX
2463 sub cx, [Char_Base4] ; Subtract base char
2464 mul cx ; Mul size by place
2465 add bx, ax ; Put in SI
2466
2467 ; Set BP to the scan line differential
2468 mov bp, [WLine_Offset]
2469
2470 ; Set DS to mask area
2471 mov ax, [Font_Mask_S4]
2472 mov ds, ax
2473
2474 ; Get the Screen Seg and put it in ES
2475 mov ax, SCREEN_SEG
2476 mov es, ax
2477
2478 ; Set all data from latches
2479 mov dx, GC_INDEX
2480 mov ax, 00000h + BIT_MASK ; Set all latch writes
2481 out dx, ax
2482
2483 ; Set up Map Mask
2484 mov al, 02h ; 02 is Map Mask
2485 mov dx, SC_INDEX
2486 out dx, al
2487 inc dx
2488
2489 ; Set CL to shift spaces
2490 mov cl, 4
2491
2492 ; This section is for WRITES ------------------------------
2493
2494 ; -- Completely unrolled
2495
2496 ; Scan Line #1
2497 ; This section prep the Map Mask
2498 lodsb ; Get mask byte
2499
2500 ; Set mask for first write
2501 out dx, al ; Set map mask
2502
2503 ; Write the byte
2504 mov ah, [es:bx]
2505 mov [es:di], ah
2506
2507 ; Scan Line #2
2508 ; Set mask for next write
2509 shr al, cl ; Move upper nibble down
2510 out dx, al ; Set map mask
2511
2512 ; Adjust for next scan line
2513 add di, bp ; Point DI to start of next line
2514 inc bx
2515
2516 ; Write the second byte
2517 mov al, [es:bx]
2518 mov [es:di], al
2519
2520 ; Adjust for next scan line
2521 add di, bp ; Point DI to start of next line
2522 inc bx
2523
2524 ; Scan Line #3
2525 ; This section prep the Map Mask
2526 lodsb ; Get mask byte
2527
2528 ; Set mask for first write
2529 out dx, al ; Set map mask
2530
2531 ; Write the byte
2532 mov ah, [es:bx]
2533 mov [es:di], ah
2534
2535 ; Scan Line #4
2536 ; Set mask for next write
2537 shr al, cl ; Move upper nibble down
2538 out dx, al ; Set map mask
2539
2540 ; Adjust for next scan line
2541 add di, bp ; Point DI to start of next line
2542 inc bx
2543
2544 ; Write the second byte
2545 mov al, [es:bx]
2546 mov [es:di], al
2547
2548 ; Adjust for next scan line
2549 add di, bp ; Point DI to start of next line
2550 inc bx
2551
2552 ; Scan Line #5
2553 ; This section prep the Map Mask
2554 lodsb ; Get mask byte
2555
2556 ; Set mask for first write
2557 out dx, al ; Set map mask
2558
2559 ; Write the byte
2560 mov ah, [es:bx]
2561 mov [es:di], ah
2562
2563 ; Scan Line #6
2564 ; Set mask for next write
2565 shr al, cl ; Move upper nibble down
2566 out dx, al ; Set map mask
2567
2568 ; Adjust for next scan line
2569 add di, bp ; Point DI to start of next line
2570 inc bx
2571
2572 ; Write the second byte
2573 mov al, [es:bx]
2574 mov [es:di], al
2575
2576
2577 ; !!DONE!!
2578 @@DONE:
2579 pop si di ds ; Return state
2580 pop bp
2581 ret
2582
2583 ENDP _XChar4_M;
2584
2585
2586 ;----------------------------- _XString4 ----------------------------------
2587 ; - This function will place a char from the current font to current screen
2588 ; - It will use the masked font on mask flag set to not 0.
2589 public _XString4
2590
2591 PROC _XString4 FAR
2592
2593 ARG X_S:WORD, Y_S:WORD, MASKIT:WORD, STR_OFF:DWORD
2594
2595 push bp
2596 mov bp, sp ; Save Stack frame
2597 push ds di si
2598
2599 ; Load DS.
2600 ASSUME ds: @fardata
2601 mov ax, @fardata
2602 mov ds, ax ; Set DS to segment w/ Table
2603
2604 ; Move flag into CX
2605 mov cx, [MASKIT]
2606
2607 ; Load DS:SI
2608 lds si, [STR_OFF]
2609
2610 ; !!! This is the master string loop
2611 @@STRING:
2612 xor ax, ax
2613 mov al, [ds:si] ; Get the char
2614 cmp al, 0 ; Is it the EOS
2615 je @@DONE ; If so jump
2616
2617 ; Save cx
2618 push cx
2619
2620 ; Build stack frame
2621 push ax ; Push the char
2622 push [Y_S] ; Push the Y coor
2623 push [X_S] ; Push the X coor
2624 ; To mask or not to mask
2625 jcxz @@DontMask ; If Flag = 0, dont mask
2626 call _XChar4_M ; Put the char
2627 jmp @@Continue
2628
2629 @@DontMask:
2630 call _XChar4 ; Do a mask instead
2631
2632 @@Continue:
2633 add sp, 6 ; Adjust the stack
2634
2635 pop cx ; Restore cx
2636
2637 add [X_S], 4 ; Move the cursor
2638 inc si ; Point to next char
2639 jmp @@STRING ; Continue
2640
2641 ; !!DONE!!
2642 @@DONE:
2643 pop si di ds ; Return state
2644 pop bp
2645 ret
2646
2647 ENDP _XString4
2648
2649
2650 ; --------------------------- _XPaste_Tile_M -------------------------------
2651 ; - This function will place a tile from the display memory to current screen
2652 ; - It will use the mask passed to it to leave background transparent
2653 ; - Max Y size is 255
2654
2655 public _XPaste_Tile_M
2656
2657 PROC _XPaste_Tile_M FAR
2658
2659 ARG X_S:WORD, Y_S:WORD, X_D:WORD, Y_D:WORD, TILE:WORD, MASK_O:DWORD
2660
2661 push bp
2662 mov bp, sp ; Save Stack frame
2663 push ds di si
2664
2665 cld
2666
2667 ; Load DS.
2668 ASSUME ds: @fardata
2669 mov ax, @fardata
2670 mov ds, ax ; Set DS to fardata segment
2671
2672 ; Set DI to start of rectangle on screen
2673 mov ax, [WLine_Offset]
2674 mul [Y_S] ; Find Y offset value. Place in AX
2675
2676 mov di, [X_S] ; Find X offset value. Place in DI
2677 shr di, 1
2678 shr di, 1 ; Adjust to number of XBlocks
2679
2680 add di, ax ; Add X and Y offsets
2681 add di, [Write_Page] ; Add in page offset
2682
2683 ; Put in source in BX
2684 mov bx, [TILE]
2685
2686 ; Get the Screen Seg and put it in ES
2687 mov ax, SCREEN_SEG
2688 mov es, ax
2689
2690 ; Set all data from latches
2691 mov dx, GC_INDEX
2692 mov ax, 00000h + BIT_MASK ; Set all latch writes
2693 out dx, ax
2694
2695 ; Set CX to the number of XBlocks per line
2696 mov cx, [X_D]
2697 shr cx, 1
2698 shr cx, 1
2699
2700 ; Get distance from end of one line to start of other and save
2701 mov ax, [WLine_Offset] ; Get screen width
2702 sub ax, cx ; Del number of XBlocks
2703 mov dx, ax ; Save in DX
2704
2705 ; Save cl in ch.
2706 mov ch, cl ; Save in CH
2707
2708
2709 ; Set DS:SI to mask area
2710 lds si, [MASK_O]
2711
2712 ; Set AH to the rows to do
2713 mov ax, [Y_D] ; Puts number in AX
2714 mov ah, al ; Puts number in ah
2715
2716 ; Move scan line differential from dx to bp
2717 mov bp, dx
2718
2719 ; Set up Map Mask
2720 mov al, 02h ; 02 is Map Mask
2721 mov dx, SC_INDEX
2722 out dx, al
2723 inc dx
2724
2725 ; This section is for WRITES ------------------------------
2726 @@Rowloop:
2727
2728 @@ScanLine:
2729 ; This section prep the Map Mask
2730 lodsb ; Get mask byte
2731
2732 ; Set mask for write
2733 out dx, al ; Set map mask
2734
2735 ; Write the XBlock
2736 mov al, [es:bx]
2737 mov [es:di], al
2738
2739 ; Adjust bx and si
2740 inc bx
2741 inc di
2742
2743 ; End of ScanLine
2744 dec cl
2745 jnz @@ScanLine
2746
2747 ; Adjust for next iteration
2748 add di, bp ; Point DI to start of next line
2749
2750 ; Restore cl
2751 mov cl, ch
2752
2753 ; End of Rowloop.
2754 dec ah
2755 jnz @@Rowloop
2756
2757 ; !!DONE!!
2758 @@DONE:
2759 pop si di ds ; Return state
2760 pop bp
2761 ret
2762
2763 ENDP _XPaste_Tile_M;
2764
2765
2766 ; --------------------------- _XPaste_Sprite_M ----------------------------
2767 ; - This function will place a sprite from the display memory to current screen
2768 ; - It will use the mask passed to it to leave background transparent
2769 ; - Max Y size is 255
2770 public _XPaste_Sprite_M
2771
2772 PROC _XPaste_Sprite_M FAR
2773
2774 ARG X_S:WORD, Y_S:WORD, X_D:WORD, Y_D:WORD, TILE:WORD, MASK_O:DWORD
2775
2776 push bp
2777 mov bp, sp ; Save Stack frame
2778 push ds di si
2779
2780 cld
2781
2782 ; Load DS.
2783 ASSUME ds: @fardata
2784 mov ax, @fardata
2785 mov ds, ax ; Set DS to fardata segment
2786
2787 ; Set all data from latches
2788 mov dx, GC_INDEX
2789 mov ax, 00000h + BIT_MASK ; Set all latch writes
2790 out dx, ax
2791
2792 ; Set DI to start of rectangle on screen
2793 mov ax, [WLine_Offset] ; Scan line size
2794 mul [Y_S] ; Find Y offset value. Place in AX
2795
2796 mov di, [X_S] ; Find X offset value. Place in DI
2797 shr di, 1
2798 shr di, 1 ; Adjust to number of XBlocks
2799
2800 add di, ax ; Add X and Y offsets
2801 add di, [Write_Page] ; Add in page offset
2802
2803 ; Put source in BX
2804 mov bx, [TILE]
2805
2806 ; Find adjustment to source for alignment
2807 mov ax, [X_D]
2808 mov cx, [X_S]
2809
2810 shr ax, 1 ; Number of XBlocks a line
2811 shr ax, 1
2812 mul [Y_D] ; Find size of each sprite alignment
2813
2814 and cx, 3 ; Mask all but 2 LSBs
2815
2816 mul cx ; Find new offset
2817
2818 add bx, ax ; Adjust BX
2819
2820 ; Save adjustment for mask for alignment in DX
2821 mov dx, ax ; AX as calculated above
2822
2823 ; Set CX to the number of XBlocks
2824 mov cx, [X_D]
2825 shr cx, 1
2826 shr cx, 1
2827
2828 ; Get distance from end of one line to start of other and save
2829 mov ax, [WLine_Offset] ; Get screen width
2830 sub ax, cx ; Del number of XBlocks
2831
2832 ; Set DS:SI to mask area
2833 lds si, [MASK_O]
2834
2835 ; Add alignment adjust to si
2836 add si, dx
2837
2838 ; Set AH to the rows to do
2839 mov dx, [Y_D] ; Puts number in AX
2840 mov bp, ax ; Move diff into BP
2841 mov ah, dl ; Puts number in ah
2842
2843 ; Get the Screen Seg and put it in ES
2844 mov dx, SCREEN_SEG
2845 mov es, dx
2846
2847 ; Set up Map Mask
2848 mov al, 02h ; 02 is Map Mask
2849 mov dx, SC_INDEX
2850 out dx, al
2851 inc dx
2852
2853 ; Save scan length (CL) in CH
2854 mov ch, cl
2855
2856 ; This section is for WRITES ------------------------------
2857 @@Rowloop:
2858
2859 @@ScanLine:
2860 ; This section prep the Map Mask
2861 lodsb ; Get mask byte
2862
2863 ; Set mask for write
2864 out dx, al ; Set map mask
2865
2866 ; Write the XBlock
2867 mov al, [es:bx]
2868 mov [es:di], al
2869
2870 ; Adjust bx and si
2871 inc bx
2872 inc di
2873
2874 ; End of ScanLine
2875 dec cl
2876 jnz @@ScanLine
2877
2878
2879 ; Adjust for next iteration
2880 add di, bp ; Point DI to start of next line
2881
2882 ; Restore scan length
2883 mov cl, ch
2884
2885 ; End of Rowloop.
2886 dec ah
2887 jnz @@Rowloop
2888
2889 ; !!DONE!!
2890 @@DONE:
2891 pop si di ds ; Return state
2892 pop bp
2893 ret
2894
2895 ENDP _XPaste_Sprite_M;
2896
2897
2898 ; ------------------------ _XSet_Pal_Color ---------------------------
2899 ; - This function uses the bios to set a single color in the palette
2900 ; -
2901 public _XSet_Pal_Color
2902
2903 PROC _XSet_Pal_Color
2904
2905 ARG COLOR:WORD, RED:WORD, GREEN:WORD, BLUE:WORD
2906
2907 push bp
2908 mov bp, sp ; Save Stack frame
2909
2910 mov bx, [COLOR] ; Load color number
2911
2912 mov ax, [RED]
2913 mov dh, al ; Load Red value
2914
2915 mov ax, [GREEN]
2916 mov ch, al ; Load Green value
2917
2918 mov ax, [BLUE]
2919 mov cl, al ; Load Blue value
2920
2921 mov ax, 01010h ; Load ax with BIOS routine id
2922 int 010h ; Call BIOS
2923
2924 pop bp ; Return state
2925 ret
2926
2927 ENDP _XSet_Pal_Color
2928
2929 ; ------------------------ _XSet_Pal_Block ---------------------------
2930 ; - This function uses the bios to set a block of colors in the palette
2931 ; -
2932 public _XSet_Pal_Block
2933
2934 PROC _XSet_Pal_Block
2935
2936 ARG START:WORD, NUMBER:WORD, PAL_O:DWORD
2937
2938 push bp
2939 mov bp, sp ; Save Stack frame
2940
2941 mov bx, [START] ; Load start color number
2942
2943 mov cx, [NUMBER] ; Load number of colors
2944
2945 les dx, [PAL_O] ; Load pointer data
2946
2947 mov ax, 01012h ; Load ax with BIOS routine id
2948 int 010h ; Call BIOS
2949
2950 pop bp ; Return state
2951 ret
2952
2953 ENDP _XSet_Pal_Block
2954
2955
2956 ; ------------------------ _XPut_Pixel ------------------------------------
2957 ; - Put a pixel to the screen.
2958 ; -
2959 public _XPut_Pixel
2960
2961 PROC _XPut_Pixel
2962
2963 ARG X_LOC:WORD, Y_LOC:WORD, COLOR:WORD
2964
2965 push bp
2966 mov bp, sp ; Save Stack frame
2967
2968 push ds di
2969
2970
2971 ; Load DS.
2972 ASSUME ds: @fardata
2973 mov ax, @fardata
2974 mov ds, ax ; Set DS to fardata segment
2975
2976 ; Set DI to the XBlock
2977 mov ax, [WLine_Offset] ; Scan line size
2978 mul [Y_LOC] ; Find Y offset value. Place in AX
2979
2980 mov di, [X_LOC] ; Find X offset value. Place in DI
2981 mov cx, di ; For later to determine the mask
2982 shr di, 1
2983 shr di, 1 ; Adjust to number of XBlocks
2984
2985 add di, ax ; Add X and Y offsets
2986 add di, [Write_Page] ; Add in page offset
2987
2988
2989 ; Set ah to the mask
2990 and cx, 03h ; Get the lower 2 bits
2991 mov ax, 0102h ; MAP MASK
2992 shl ah, cl ; Shift to app. plane
2993
2994 ; Set up Map Mask
2995 mov dx, SC_INDEX
2996 out dx, ax
2997
2998 ; Set all data from CPU and non from latches
2999 mov dx, GC_INDEX
3000 mov ax, 0FF00h + BIT_MASK ; Set all CPU writes
3001 out dx, ax
3002
3003 ; Get the Screen Seg and put it in DS
3004 mov ax, SCREEN_SEG
3005 mov ds, ax
3006
3007 ; Get the color
3008 mov ax, [COLOR]
3009
3010 ; Put the Pixel
3011 mov [di], al
3012
3013 ; !!DONE!!
3014 pop di ds ; Return state
3015 pop bp
3016 ret
3017
3018 ENDP _XPut_Pixel
3019
3020
3021 ; ------------------------ _MEvent_Handler ---------------------------
3022 ; - Xtile's mouse event handler
3023 ; -
3024 PROC _MEvent_Handler
3025
3026 ; Save thier DS
3027 push ds di si
3028
3029 ; This function is not callable from 'c' so we won't build a
3030 ; stack frame
3031
3032 ; Save the event masks
3033 push ax
3034
3035 ; Correct X pos
3036 shr cx, 1
3037
3038 ; Save dx in SI
3039 mov si, dx
3040
3041 ; Load DS.
3042 ASSUME ds: @fardata
3043 mov ax, @fardata
3044 mov ds, ax ; Set DS to fardata segment
3045
3046 ; Check for Lock
3047 cmp [LockHandler], NOTLOCKM ; Is it locked
3048 jz @@NotLocked
3049
3050 ; !!!Locked!!! Jump out
3051 pop ax ; Pull flags off stack
3052 jmp @@Done
3053
3054 @@NotLocked:
3055 ; Lock the handler
3056 mov ax, LOCKM
3057 mov [LockHandler], ax
3058
3059 ; Get and save the status of bit mask and map mask
3060 ; Get status of bit mask
3061 mov dx, GC_INDEX
3062 mov ax, 0808h ; 08 is bit mask
3063 out dx, al
3064 inc dx
3065 in al, dx ; Get the bit mask
3066 xchg al, ah
3067 push ax
3068
3069 ; Get Map Mask
3070 mov ax, 0202h ; 02 is Map Mask
3071 mov dx, SC_INDEX
3072 out dx, al
3073 inc dx
3074 in al, dx
3075 xchg al, ah
3076 push ax
3077
3078 ; -- Restore the the current background location ---
3079 ; This is a Save Site restore
3080 cld
3081
3082 ; Set DI to start of rectangle on screen
3083 mov ax, [DLine_Offset] ; Get line size
3084 mov bx, [MLastY] ; Get Y into view
3085 push bx ; Save on stack
3086 add bx, [ViewYLoc] ; Add start of view
3087 mul bx ; Find Y offset value. Place in AX
3088
3089 mov di, [MLastX] ; Find X offset value. Place in DI
3090 mov bp, di ; Save X in BP
3091 add di, [ViewXLoc] ; Get start of view and add it
3092 shr di, 1
3093 shr di, 1
3094
3095 add di, ax ; Add X and Y offsets
3096 add di, [Display_Page] ; Add in page offset
3097
3098 ; Get DX back
3099 mov dx, si
3100
3101 ; Save the new location as the last known
3102 mov [MLastY], dx
3103 mov [MLastX], cx
3104
3105 ; See if we need to clip Second XBlock
3106 mov cx, 2 ; Assume 2 XBlocks to write
3107 mov dx, [ScreenSizeX] ; Get screen size
3108 sub dx, 4 ; Get 2nd to last XBlock
3109 cmp dx, bp
3110 jae @@Continue ; Both blocks on reload
3111 dec cx ; Only one block on reload
3112
3113 @@Continue:
3114 ; Set all data from latches
3115 mov dx, GC_INDEX
3116 mov ax, 00000h + BIT_MASK ; Set all latch writes
3117 out dx, ax
3118
3119 ; Insure Map Mask is set to all planes
3120 mov ax, 0F02h ; 0F sets all planes. 02 is Map Mask
3121 mov dx, SC_INDEX
3122 out dx, ax
3123
3124 ; Set DX to number of lines to display
3125 mov dx, 8 ; Assume 8 scan lines
3126 pop bx ; Get Y last and put in BX
3127 mov ax, [ScreenSizeY] ; Get Screen size Y and put in ax
3128 sub ax, 8 ; Subtract to make mimimum clip
3129
3130 cmp ax, bx ; Does it need clipping?
3131 ja @@ContinueC ; No, then go!
3132
3133 sub bx, ax ; Needs clipping! Find new DX
3134 sub dx, bx
3135
3136 @@ContinueC:
3137 ; Set BP to the distance from one scan line to next
3138 mov bp, [DLine_Offset]
3139 sub bp, cx ; # XBlocks per scan line
3140
3141 ; Get the Screen Seg and put it in DS and ES
3142 mov ax, SCREEN_SEG
3143 mov ds, ax
3144 mov es, ax
3145
3146 ; Set SI to source
3147 mov si, MSAVEOFFSET
3148
3149 ; Save number to move (CX) in BX
3150 mov bx, cx
3151
3152 ; This section is for WRITES ------------------------------
3153 ; The Reload will be clipped if appropriate
3154
3155 @@RowLoop:
3156 ; Put 1 or 2 XBlocks
3157 rep movsb
3158
3159 ; Ready next iteration
3160 add di, bp ; Point DI to start of next line
3161
3162 ; Reload CX
3163 mov cx, bx
3164
3165 ; Are we done?
3166 dec dx
3167 jnz @@RowLoop ; No, then go and do another line
3168
3169
3170 ; ------ Now save the new area --------
3171 ; -- Do the reload
3172
3173 ; Load DS.
3174 ASSUME ds: @fardata
3175 mov ax, @fardata
3176 mov ds, ax ; Set DS to fardata segment
3177
3178 ; Set SI to start of rectangle on screen
3179 mov ax, [DLine_Offset] ; Get line size
3180 mov bx, [MLastY] ; Get Y into view
3181 mov di, bx ; Save in DI
3182 add bx, [ViewYLoc] ; Add start of view
3183 mul bx ; Find Y offset value. Place in AX
3184
3185 mov si, [MLastX] ; Find X offset value. Place in DI
3186 mov bp, si ; Save in BP for later
3187 add si, [ViewXLoc] ; Get start of view and add it
3188 shr si, 1
3189 shr si, 1
3190
3191 add si, ax ; Add X and Y offsets
3192 add si, [Display_Page] ; Add in page offset
3193
3194 push si ; Save what will later be DI
3195
3196 ; See if we need to clip Second XBlock
3197 mov cx, 2 ; Assume 2 XBlocks to write
3198 mov dx, [ScreenSizeX] ; Get screen size
3199 sub dx, 4 ; Get 2nd to last XBlock
3200 cmp dx, bp ; BP from above.
3201 jae @@Continue3 ; Both blocks on reload
3202 dec cx ; Only one block on reload
3203
3204 @@Continue3:
3205 ; Set DX to number of lines to reload
3206 mov dx, 8 ; Assume 8 scan lines
3207 mov bx, di ; Get Y last and put in BX (from SI)
3208 mov ax, [ScreenSizeY] ; Get Screen size Y and put in ax
3209 sub ax, 8 ; Subtract to make mimimum clip
3210
3211 cmp ax, bx ; Does it need clipping?
3212 ja @@Continue4 ; No, then go!
3213
3214 sub bx, ax ; Needs clipping! Find new DX
3215 sub dx, bx
3216
3217 @@Continue4:
3218 ; Save DX ( as number of lines to do ) for later
3219 push dx
3220
3221 ; Set BP to scan line dif.
3222 mov bp, [DLine_Offset]
3223 sub bp, cx
3224
3225 ; Get the Screen Seg and put it in DS
3226 mov ax, SCREEN_SEG
3227 mov ds, ax
3228
3229 ; Set destination
3230 mov di, MSAVEOFFSET
3231
3232 ; Save SI so we dont have to calc later
3233 mov ax, si
3234
3235 ; Save CX in BX
3236 mov bx, cx
3237
3238 ; This section is for the MOVE ------------------------------
3239
3240 @@RowLoop2:
3241 ; Do line
3242 rep movsb ; One or two XBlocks
3243
3244 ; Prep for next line
3245 add si, bp ; Point SI to start of next line
3246 mov cx, bx ; Restore CX
3247
3248 ; Are we done?
3249 dec dx
3250 jnz @@RowLoop2 ; No, then go and do another
3251
3252
3253 ; -------- Put the pointer in the new position ---------
3254
3255 ; Load DS.
3256 ASSUME ds: @fardata
3257 mov ax, @fardata
3258 mov ds, ax ; Set DS to fardata segment
3259
3260
3261 ; Find adjustment to source for alignment
3262 mov bx, [MLastX] ; Put X loc into cx
3263 add bx, [ViewXLoc] ; Add view start
3264 mov ax, 16 ; Alignment size ( 2XBlocks*8Scan )
3265
3266 and bx, 3 ; Mask all but 2 LSBs
3267 mul bx ; Find offset into alignments (Put in AX)
3268
3269 ; Put source into BX and add the alignment adj
3270 mov bx, MOUSEOFFSET
3271 add bx, ax ; Adjust BX
3272
3273
3274 ; Set DS:SI to mask area
3275 lds si, [MPointerMask]
3276
3277 ; Add adjustment for mask for alignment
3278 add si, ax ; AX as calculated above
3279
3280 ; Set ah to rows to do
3281 pop ax ; Was DX in the reload
3282 mov ah, al ; Move to upper nibble
3283
3284 ; Increment BP to account for no last inc
3285 inc bp
3286
3287 ; Pop the destination, prev si, from the stack
3288 pop di
3289
3290 ; Set up Map Mask
3291 mov al, 02h ; 02 is Map Mask
3292 mov dx, SC_INDEX
3293 out dx, al
3294 inc dx
3295
3296 ; Shift CX down to see if we need to write 2nd XBlock
3297 shr cx, 1
3298
3299 ; This section is for WRITES ------------------------------
3300 @@Rowloop3:
3301
3302
3303 ; Set mask for first XBlock write
3304 lodsb ; Get mask byte
3305 out dx, al ; Set map mask
3306
3307 ; Write the 1st XBlock
3308 mov al, [es:bx]
3309 mov [es:di], al
3310
3311 ; Load the next mask
3312 lodsb
3313
3314 ; Increment source pointers
3315 inc bx
3316
3317 ; If CX is zero, pointer is clipped. Don't put next XBlock
3318 jcxz @@Clipped
3319
3320 ; - Do another write
3321 ; Set the mask
3322 out dx, al ; Set map mask
3323
3324 ; Increment destination pointers
3325 inc di
3326
3327 ; Write the 2nd XBlock
3328 mov al, [es:bx]
3329 mov [es:di], al
3330
3331 @@Clipped:
3332 ; Adjust for next iteration
3333 add di, bp ; Point to next scan line
3334 inc bx
3335
3336 ; End of Rowloop.
3337 dec ah
3338 jnz @@Rowloop3
3339
3340 ; -- Done with screen
3341
3342 ; Restore the state of the bit mask and map mask
3343 ; Get Map Mask
3344 mov dx, SC_INDEX
3345 pop ax
3346 out dx, ax
3347
3348 ; Do the BIT MASK
3349 mov dx, GC_INDEX
3350 pop ax
3351 out dx, ax
3352
3353 ; -- See if we have to call the user's handler
3354
3355 ; Make ES the local data
3356 ASSUME es: @fardata
3357 mov ax, @fardata
3358 mov es, ax ; Set ES to fardata segment
3359
3360 ; Restore event masks
3361 pop ax
3362
3363 ; AND the mask with users mask
3364 and ax, [es:MUEventMask]
3365
3366 ; If zero then don't call user's
3367 je @@Done
3368
3369 ; Load users DGROUP
3370 mov ax, @data
3371 mov ds, ax
3372
3373 ; Otherwise set up stack and call users routine
3374 push ax ; Push the event mask
3375
3376 push [es:MLastY] ; Push Y location
3377
3378 push [es:MLastX] ; Push X location
3379
3380 call [es:Mouse_Hndlr_O] ; User pointer to call user handler
3381
3382 ; Clean stack after call
3383 add sp, 6
3384
3385
3386 ; -- DONE!!
3387
3388 @@Done:
3389 ; Make DS the local data
3390 ASSUME ds: @fardata
3391 mov ax, @fardata
3392 mov ds, ax ; Set DS to fardata segment
3393
3394 ; Unlock the handler
3395 mov ax, NOTLOCKM
3396 mov [LockHandler], ax
3397
3398 pop si di ds ; Pop mouses DS
3399 ret
3400
3401 ENDP _MEvent_Handler
3402
3403
3404 ; ------------------------ _XRegister_Mouse ---------------------------
3405 ; - This function sets up the use of the mouse
3406 ; - It returns FALSE (0) if it cannot
3407 ; -
3408 public _XRegister_Mouse
3409
3410 PROC _XRegister_Mouse
3411
3412 ARG MPOINT:DWORD, MMASK:DWORD, HANDLER:DWORD
3413
3414 push bp
3415 mov bp, sp ; Save Stack frame
3416
3417 ; Save registers
3418 push ds si di
3419
3420 ; First see if mouse is available
3421 mov ax, 0
3422 int 33h
3423
3424 cmp ax, 0FFFFh ; If ax is FFFFh then mouse is present
3425 je @@Cont
3426
3427 mov ax, MOUSE_NOTPRES
3428 jmp @@Done ; Otherwise, done
3429
3430 ; Mouse is present so continue
3431 @@Cont:
3432
3433 ; ----------- Upload mouse pointer ------------
3434
3435 ; Prep the stack for call to upload sprite
3436 les si, [MPOINT] ; Get the image offset
3437 push es
3438 push si
3439
3440 mov si, (64*4) ; Mouse sprite size
3441 push si
3442
3443 mov si, MOUSEOFFSET ; Mouse pointer site
3444 push si
3445
3446 ; Call upload sprite
3447 call _XUpload_Sprite
3448
3449 ; Fix the stack after call
3450 add sp, 8
3451
3452 ; ---- Done uploading mouse pointer
3453
3454
3455 ; Load DS.
3456 ASSUME ds: @fardata
3457 mov ax, @fardata
3458 mov ds, ax ; Set DS to fardata segment
3459
3460 ; Get the pointer mask address
3461 les si, [MMASK]
3462 mov [MPointerMask_O], si
3463 mov ax, es
3464 mov [MPointerMask_S], ax
3465
3466 ; Set up user handler
3467 les si, [HANDLER]
3468 mov [OFFSET Mouse_Hndlr_O], si
3469 mov ax, es
3470 mov [OFFSET Mouse_Hndlr_O+2], ax
3471
3472 ; !!DONE!!
3473 mov ax, MOUSE_PRESENT ; Return the mouse is present
3474
3475
3476 ; Set the new mickey counts
3477 mov ax, 000Fh ; Mouse driver routine
3478 mov cx, 8 ; Double horizontal
3479 mov dx, 8 ; Default vertical
3480 int 033h ; Call routine
3481
3482 @@Done:
3483 pop di si ds
3484
3485 pop bp ; Return state
3486 ret
3487
3488 ENDP _XRegister_Mouse
3489
3490
3491 ; ------------------------ _Mouse_Active ---------------------------
3492 ; - Makes the mouse active and starts display of the pointer
3493 ; -
3494 public _XMouse_Active
3495
3496 PROC _XMouse_Active
3497
3498 ARG EMASK:WORD, STARTX:WORD, STARTY:WORD
3499
3500 push bp
3501 mov bp, sp ; Save Stack frame
3502
3503 ; Save regs
3504 push ds si di
3505
3506 ; Load DS.
3507 ASSUME ds: @fardata
3508 mov ax, @fardata
3509 mov ds, ax ; Set DS to fardata segment
3510
3511 cld
3512
3513 ; Save the users mask
3514 mov cx, [EMASK] ; Get user's mask
3515 push cx
3516
3517 ; Set mouse reporting limits
3518 mov ax, 0007h ; Set X limits function
3519 mov cx, 0000h ; X minimum
3520 mov dx, [ScreenSizeX] ; X maximum
3521 dec dx
3522 shl dx, 1 ; Comp for oddity
3523 int 033h
3524
3525 mov ax, 0008h ; Set Y limits function
3526 mov cx, 0000h ; Y minimum
3527 mov dx, [ScreenSizeY] ; Y maximum
3528 dec dx ; Adjust for pointer size
3529 int 033h
3530
3531 ; -- Set up VGA Registers
3532 ; Set all data from latches
3533 mov dx, GC_INDEX
3534 mov ax, 00000h + BIT_MASK ; Set all latch writes
3535 out dx, ax
3536
3537 ; Insure Map Mask is set to all planes
3538 mov ax, 0F02h ; 0F sets all planes. 02 is Map Mask
3539 mov dx, SC_INDEX
3540 out dx, ax
3541
3542 ; -- Set the mouse's position and display the pointer
3543
3544 ; Let the driver know where the mouse pointer is
3545 mov ax, 0004h ; Set mouse pointer position func
3546
3547 mov cx, [STARTX] ; Set X coord
3548 mov dx, [STARTY] ; Set Y coord
3549
3550 mov [MLastX], cx ; Save as last location
3551 mov [MLastY], dx
3552
3553 shl cx, 1 ; Comp
3554
3555 int 033h ; Call function
3556
3557 ; Reload background & fake a mouse event to put the pointer
3558 ; on the screen the first time
3559
3560 ; -- Do the reload
3561
3562 ; Return CX to actual coord
3563 shr cx, 1
3564
3565 ; Set SI to start of rectangle on screen
3566 mov ax, [DLine_Offset] ; Get line size
3567 mov bx, [MLastY] ; Get Y into view
3568 mov di, bx ; Save in DI
3569 add bx, [ViewYLoc] ; Add start of view
3570 mul bx ; Find Y offset value. Place in AX
3571
3572 mov si, [MLastX] ; Find X offset value. Place in DI
3573 mov bp, si ; Save in BP for later
3574 add si, [ViewXLoc] ; Get start of view and add it
3575 shr si, 1
3576 shr si, 1
3577
3578 add si, ax ; Add X and Y offsets
3579 add si, [Display_Page] ; Add in page offset
3580
3581 ; See if we need to clip Second XBlock
3582 mov cx, 2 ; Assume 2 XBlocks to write
3583 mov dx, [ScreenSizeX] ; Get screen size
3584 sub dx, 4 ; Get 2nd to last XBlock
3585 cmp dx, bp ; BP from above.
3586 jge @@Continue3 ; Both blocks on reload
3587 dec cx ; Only one block on reload
3588
3589 @@Continue3:
3590 ; Set DX to number of lines to reload
3591 mov dx, 8 ; Assume 8 scan lines
3592 mov bx, di ; Get Y last and put in BX (from SI)
3593 mov ax, [ScreenSizeY] ; Get Screen size Y and put in ax
3594 sub ax, 8 ; Subtract to make mimimum clip
3595
3596 cmp ax, bx ; Does it need clipping?
3597 jg @@Continue4 ; No, then go!
3598
3599 sub bx, ax ; Needs clipping! Find new DX
3600 sub dx, bx
3601
3602 @@Continue4:
3603
3604 ; Set BP to scan line dif.
3605 mov bp, [DLine_Offset]
3606 sub bp, cx
3607
3608 ; Get the Screen Seg and put it in DS and ES
3609 mov ax, SCREEN_SEG
3610 mov ds, ax
3611 mov es, ax
3612
3613 ; Set destination
3614 mov di, MSAVEOFFSET
3615
3616 ; Save CX in BX
3617 mov bx, cx
3618
3619 ; This section is for the MOVE ------------------------------
3620 ; Completely unrolled
3621
3622 @@RowLoop2:
3623 ; Do line
3624 rep movsb ; One or two XBlocks
3625
3626 ; Prep for next line
3627 add si, bp ; Point SI to start of next line
3628 mov cx, bx ; Restore CX
3629
3630 ; Are we done?
3631 dec dx
3632 jnz @@RowLoop2 ; No, then go and do another
3633
3634 ; - Done with Reload
3635
3636 ; Load DS.
3637 ASSUME ds: @fardata
3638 mov ax, @fardata
3639 mov ds, ax ; Set DS to fardata segment
3640
3641 ; Ensure the mouse is not locked
3642 mov ax, NOTLOCKM
3643 mov [LockHandler], ax
3644
3645 ; Fake a mouse event and call handler
3646 mov ax, 0001h ; Indicate a move
3647 mov bx, 0000h ; No info
3648 mov cx, [MLastX] ; X coord
3649 shl cx, 1 ; Double, that's how it is expected
3650 mov dx, [MLastY] ; Y coord
3651
3652 call _MEvent_Handler
3653
3654 ; Get the users event mask, save, and build our mask in cx
3655 pop cx ; Get the Mask back
3656 mov [MUEventMask], cx ; Save it
3657 or cx, 0001h ; Build ours
3658 ; We must make sure all moves are reported
3659
3660 ; Define XTile's handler and register it with the mouse driver
3661 mov ax, 0000Ch ; Function number
3662
3663 mov dx, cs ; Get XTile's handler address
3664 mov es, dx
3665 mov dx, OFFSET _MEvent_Handler
3666
3667 int 033h ; Call the mouse driver
3668 ; !!DONE!!
3669
3670 pop di si ds ; Restore regs
3671
3672 pop bp ; Return state
3673 ret
3674
3675 ENDP _XMouse_Active
3676
3677
3678 ; ------------------------ _XMouse_InActive ---------------------------
3679 ; - Turns off the mouse. Restores background to last known mouse position.
3680 ; -
3681 public _XMouse_InActive
3682
3683 PROC _XMouse_InActive
3684
3685 push bp
3686 mov bp, sp ; Save Stack frame
3687
3688 ; Save regs
3689 push ds si di
3690
3691 ; Register with mouse driver that we don't want any more reports
3692 mov ax, 0000Ch ; Function number
3693 mov cx, 00000h ; Clear flag
3694 mov dx, 00000h ; Get XTile's handler address
3695 mov es, dx
3696 mov dx, 00000h
3697
3698 int 033h ; Call the mouse driver
3699
3700 ; Load DS with local segment
3701 ASSUME ds: @fardata
3702 mov ax, @fardata
3703 mov ds, ax ; Set DS to fardata segment
3704
3705 ; Ensure the mouse is locked
3706 mov ax, LOCKM
3707 mov [LockHandler], ax
3708
3709 ; Clear the users mask
3710 mov cx, 0000h ; Set to no events
3711 mov [MUEventMask], cx ; Save it
3712
3713 ; ---- This is the restore
3714 cld
3715
3716 ; Set DI to start of rectangle on screen
3717 mov ax, [DLine_Offset] ; Get line size
3718 mov bx, [MLastY] ; Get Y into view
3719 mov si, bx ; Save in SI
3720 add bx, [ViewYLoc] ; Add start of view
3721 mul bx ; Find Y offset value. Place in AX
3722
3723 mov di, [MLastX] ; Find X offset value. Place in DI
3724 mov bp, di ; Save X in BP
3725 add di, [ViewXLoc] ; Get start of view and add it
3726 shr di, 1
3727 shr di, 1
3728
3729 add di, ax ; Add X and Y offsets
3730 add di, [Display_Page] ; Add in page offset
3731
3732
3733 ; See if we need to clip Second XBlock
3734 mov cx, 2 ; Assume 2 XBlocks to write
3735 mov dx, [ScreenSizeX] ; Get screen size
3736 sub dx, 4 ; Get 2nd to last XBlock
3737 cmp dx, bp
3738 ja @@Continue ; Both blocks on reload
3739 dec cx ; Only one block on reload
3740
3741 @@Continue:
3742 ; Set all data from latches
3743 mov ax, GC_INDEX
3744 mov ax, 00000h + BIT_MASK ; Set all latch writes
3745 out dx, ax
3746
3747 ; Insure Map Mask is set to all planes
3748 mov ax, 0F02h ; 0F sets all planes. 02 is Map Mask
3749 mov dx, SC_INDEX
3750 out dx, ax
3751
3752 ; Set DX to number of lines to display
3753 mov dx, 8 ; Assume 8 scan lines
3754 mov ax, [ScreenSizeY] ; Get Screen size Y and put in ax
3755 sub ax, 8 ; Subtract to make mimimum clip
3756
3757 cmp ax, si ; Does it need clipping? (SI = last Y)
3758 ja @@ContinueC ; No, then go!
3759
3760 sub si, ax ; Needs clipping! Find new DX
3761 sub dx, si
3762
3763 @@ContinueC:
3764 ; Set BP to the distance from one scan line to next
3765 mov bp, [DLine_Offset]
3766 sub bp, cx ; # XBlocks per scan line
3767
3768 ; Get the Screen Seg and put it in DS and ES
3769 mov ax, SCREEN_SEG
3770 mov ds, ax
3771 mov es, ax
3772
3773 ; Set SI to source
3774 mov si, MSAVEOFFSET
3775
3776 ; Save number to move (CX) in BX
3777 mov bx, cx
3778
3779 ; This section is for WRITES ------------------------------
3780 ; The Reload will be clipped if appropriate
3781
3782 @@RowLoop:
3783 ; Put 1 or 2 XBlocks
3784 rep movsb
3785
3786 ; Ready next iteration
3787 add di, bp ; Point DI to start of next line
3788
3789 ; Reload CX
3790 mov cx, bx
3791
3792 ; Are we done?
3793 dec dx
3794 jnz @@RowLoop ; No, then go and do another line
3795
3796
3797 ; -- DONE!!
3798
3799 pop di si ds ; Restore regs
3800 pop bp ; Return state
3801 ret
3802
3803 ENDP _XMouse_InActive
3804
3805
3806 ; ------------------------ _XReload_TileW ---------------------------
3807 ; - This will "reload" a tile from the write page to display memory
3808 ; - storeage
3809 ; -
3810 public _XReload_TileW
3811
3812 PROC _XReload_TileW
3813
3814 ARG STARTX:WORD, STARTY:WORD, XDELTA:WORD, YDELTA:WORD, OFFST:WORD
3815
3816 push bp
3817 mov bp, sp ; Save Stack frame
3818
3819 ; Save regs
3820 push ds si di
3821
3822 ; Load DS.
3823 ASSUME ds: @fardata
3824 mov ax, @fardata
3825 mov ds, ax ; Set DS to fardata segment
3826
3827 ; -- Do the reload
3828
3829 ; Set SI to start of rectangle on screen
3830 mov ax, [WLine_Offset] ; Get line size
3831 mul [STARTY] ; Find Y offset
3832
3833 mov si, [STARTX] ; Find X offset value. Place in DI
3834 shr si, 1
3835 shr si, 1
3836
3837 add si, ax ; Add X and Y offsets
3838 add si, [Write_Page] ; Add in page offset
3839
3840 ; Set destination
3841 mov di, [OFFST]
3842
3843 ; Set all data from latches
3844 mov dx, GC_INDEX
3845 mov ax, 00000h + BIT_MASK ; Set all latch writes
3846 out dx, ax
3847
3848 ; Insure Map Mask is set to all planes
3849 mov ax, 0F02h ; 0F sets all planes. 02 is Map Mask
3850 mov dx, SC_INDEX
3851 out dx, ax
3852
3853 ; Set CX to the number of XBlocks to move per scan line
3854 mov cx, [XDELTA]
3855 shr cx, 1
3856 shr cx, 1
3857
3858 ; Set BX to the number of scan lines to do
3859 mov bx, [YDELTA]
3860
3861 ; Set AX to scan line dif.
3862 mov ax, [WLine_Offset]
3863 sub ax, cx ; Scan size minus tile size
3864
3865 ; Get the Screen Seg and put it in ES
3866 mov dx, SCREEN_SEG
3867 mov es, dx
3868 mov ds, dx
3869
3870 ; Save number of XBlocks (CX) in DX
3871 mov dx, cx
3872
3873 ; This section is for the MOVE ------------------------------
3874 @@Rowloop:
3875
3876 rep movsb
3877
3878 ; Adjust for next iteration
3879 add si, ax ; Point DI to start of next line
3880
3881 ; Re-load CX
3882 mov cx, dx
3883
3884 ; End of Rowloop.
3885 dec bx
3886 jnz @@Rowloop
3887
3888
3889 ; DONE!!!
3890 pop di si ds
3891
3892 pop bp ; Return state
3893 ret
3894
3895 ENDP _XReload_TileW
3896
3897
3898 ; ------------------------ _XSet_Clip ---------------------------
3899 ; - This will set the clip boundries
3900 ; -
3901 public _XSet_Clip
3902
3903 PROC _XSet_Clip
3904
3905 ARG STARTX:WORD, STARTY:WORD, ENDX:WORD, ENDY:WORD
3906
3907 push bp
3908 mov bp, sp ; Save Stack frame
3909
3910 ; Save regs
3911 push ds
3912
3913 ; Load DS.
3914 ASSUME ds: @fardata
3915 mov ax, @fardata
3916 mov ds, ax ; Set DS to fardata segment
3917
3918 ; -- Load the values
3919 mov ax, [STARTX]
3920 mov [ClipSX], ax
3921 mov ax, [STARTY]
3922 mov [ClipSY], ax
3923 mov ax, [ENDX]
3924 mov [ClipEX], ax
3925 mov ax, [ENDY]
3926 mov [ClipEY], ax
3927
3928 ; DONE!!!
3929 pop ds
3930
3931 pop bp ; Return state
3932 ret
3933
3934 ENDP _XSet_Clip
3935
3936
3937 ENDS
3938
3939 END
|