1 | Routines to interface C to the graphics card in the Prisma
2 | These replace the ROM routines.
4 | 0.1 16/02/99 G.Harvey first created
5 | 0.11 19/02/99 G.Harvey optimise line drawing (c_ldraw4())
6 | 0.2 20/02/99 G.Harvey add read/write pixel
7 | 0.3 21/02/99 G.Harvey add video init routines
8 | 0.4 23/02/99 G.Harvey add r1pix
9 | 0.41 26/02/99 G.Harvey add w1pix
10 | 0.5 27/02/99 G.Harvey add rd_rect, wr_rect
11 | 0.51 02/03/99 G.Harvey add wr_rect5
13 | Base addr of GC video buffer control registers
17 | GC Video Buffer write registers (offsets from the base addr)
19 GCW_CE = 0x00 | chip enable
20 GCW_PSEL = 0x04 | plane select
21 GCW_INTEN = 0x08 | intensity write data
22 GCW_CMD = 0x0c | command
23 GCW_CMAP = 0x10 | colour map address / data
24 GCW_DAC = 0x14 | DAC / video control
25 GCW_PY_SM = 0x18 | pixel Y address / start single mem cycle
26 GCW_IN_SM = 0x1c | intensity write data / start single mem cycle
27 GCW_PX_SL = 0x20 | pixel X address / start line
28 GCW_PX_SM = 0x24 | pixel X address / start single mem cycle
29 GCW_PY = 0x28 | pixel Y address
30 GCW_PX = 0x2c | pixel X address
31 GCW_LG1 = 0x30 | line generation algorithm
32 GCW_LG2 = 0x34 | line generation algorithm
33 GCW_LG3 = 0x38 | line generation algorithm
34 GCW_LG4 = 0x3c | line generation algorithm
36 | GC Video Buffer read registers (offsets from the base addr)
38 GCR_INTEN = 0x00 | read intensity
39 GCR_RESV = 0x04 | reserved
40 GCR_CMAP = 0x08 | read colour map
41 GCR_STATUS = 0x0c | read VBUSY, VBLANK status
42 GCR_IN_SM = 0x10 | read intensity / start single mem cycle
47 | from LAB_0367 at 0x00104760
55 lea GC_BASE,a0 | base of video control registers
57 tstl a0@(524) | 0x20064c - CMD reg but inhibit command
59 btst #6,a0@(524) | GCR_STATUS with command inhibit
60 beq init1_1 | wait for VBLANK ?
62 btst #5,a0@(524) | GCR_STATUS
63 bne init1_2 | VBLANK ?
64 clrl a0@(GCW_CMAP) | colour map
75 moveb d0,init_flag1 | ??
92 movel #0x1ff,line_selmask
100 | LAB_036B at 0x0010047f4
105 moveml d2-d7/a2-a5,sp@-
112 movew init_flag2,init_flag3
129 cmpw init_flag5,d0 | 06F4
131 movew init_flag3,d1 | 06F8
135 movel d1,init_flag6 | 6F0
140 orl d1,init_flag6 | 6F0
144 orl d1,init_flag6 | 6F0
148 movel init_flag6,a2@+ | store map entry in table
180 addw d0,init_flag3 | 06F8
181 addqw #1,init_flag5 | 06F4
184 pea init_flag4 | start of colour map
185 moveq #16,d0 | no. of entries
187 bsr c_pcmap | write colour map to video board
189 addqw #1,init_flag2 | 06F6
192 moveml sp@+,d2-d7/a2-a5
197 | C entry to program the colour map
198 | c_pcmap(int len, int *map)
200 | the format of the map appears to be an array of longwords, each word
201 | contains an index value and the values for R, G and B, all 8 bits.
202 | Format is: :INDEX:RED:GREEN:BLUE:
210 moveal a6@(12),a5 | point to colour map
211 movel a6@(8),d7 | no. of entries
218 | program colour map 1
219 | looks like you can only set a maximum of 127 entries at a time
223 moveml d0-d7/a0-a6,sp@-
229 bne pcmap1_1 | bra if more than 127 entries
236 bsr pcmap2 | first 127 entries
238 bsr pcmap2 | remainder of entries
240 moveml sp@+,d0-d7/a0-a6
243 | program colour map 2
244 | this subroutine actually writes to the colour map on the video
249 lea GC_BASE,a0 | pint to control registers
250 tstl a0@(524) | wait for VBLANK
258 movel a5@+,d3 | map entry
263 movel d3,a0@(GCW_CMAP) | upper 8 bits is addr, lower is data
264 movel d0,a0@(GCW_DAC) | write RED
266 movel d3,a0@(GCW_CMAP)
267 movel d1,a0@(GCW_DAC) | write GREEN
269 movel d3,a0@(GCW_CMAP)
270 movel d2,a0@(GCW_DAC) | write BLUE
272 dbeq d7,pcmap2_3 | loop
276 moveb #7,d1 | line_flag when ROM monitor active
279 orw #0x100,d0 | overlay on
285 | moveb init_flag1,d1
286 moveb #6,d1 | init_flag1 when ROM monitor active
287 lsll #5,d1 | overlay colour ?
289 movel d0,a0@(GCW_DAC) | set overlay colour & operating mode
293 | LAB_0389 at 0x001004b0c
298 movel line_selmask,d6
308 lea GC_BASE,a0 | base of video control registers
310 movel d0,a0@(GCW_INTEN) | intensity
311 movel d6,a0@(GCW_PSEL) | plane select
312 movel #0x0e,a0@(GCW_CMD) | command
313 movel d1,a0@(GCW_LG2) | line draw
314 movel d0,a0@(GCW_LG1) | line draw
315 movel d2,a0@(GCW_LG2) | line draw
316 movel d3,a0@(GCW_LG3) | line draw
317 movel d4,a0@(GCW_LG4) | line draw
318 movel d5,a0@(GCW_PY) | pixel Y addr
319 movel d0,a0@(GCW_PX_SL) | pixel X addr, start line
320 addql #1,d5 | incr Y addr
327 movel d6,a0@(GCW_PSEL) | plane select
328 tstl a0@(524) | 0x20064c - CMD reg but inhibit cmd
337 movel d0,a0@(GCW_CMD) | command
338 movel d2,a0@(GCW_PY_SM) | pixel Y addr, start mem cycle
340 movel d1,a0@(GCW_CMD) | command
341 movel d3,a0@(GCW_PY_SM) | pixel Y addr, start mem cycle
347 | in-lined version of ldraw
353 moveml d0-d7/a0-a6,sp@-
354 lea gr_data,a1 | point to data space
356 movel a6@(12),d3 | y1
357 movel a6@(16),d1 | x2
358 movel a6@(20),d0 | y2
359 moveb #0x03,line_flag | magic number ?
362 movel d5,a1@(40) | set x direction flag
363 movel d5,a1@(44) | set y direction flag
364 subl d2,d1 | (d1-d2)->d1, (x2 - x1) -> d1
365 movel d1,a1@(16) | delta-x
367 subl d3,d0 | (y2 - y1) -> d0
368 movel d0,a1@(20) | delta-y
369 cmpl d1,d0 | delta-y - delta-x
370 bgt ldraw4_6 | bra if delta-y > delta-x
371 movel d5,d0 | set d0 to 1
374 clrl d0 | set d0 to 0
376 movel d0,a1@(48) | set to 0 if delta-y > delta-x, else set to 1
377 beq ldraw4_8 | bra if delta-y > delta-x
378 movel a1@(20),d5 | delta-y to d5
379 lsll #1,d5 | shift left (mul by 2)
380 movel d5,d4 | copy to d4
381 subl a1@(16),d4 | (2 * dy) - dx -> d4
382 subl a1@(40),d4 | d4 - xdir -> d4
383 movel a1@(16),d6 | dx -> d6
384 movel a1@(20),d7 | dy -> d7
385 subl d6,d7 | dy - dx -> d7
386 lsll #1,d7 | shift left, d7 = ND/NA
389 movel a1@(16),d5 | dx
390 lsll #1,d5 | shift left (mul by 2)
392 subl a1@(20),d4 | (2 * dx) - dy
393 subl a1@(44),d4 | ydir
394 movel a1@(20),d6 | dy
395 movel a1@(16),d7 | dx
397 lsll #1,d7 | shift left, d7 = ND/NA
400 | by this point, d4 = ND/NA, d5 = NB
402 subql #1,d6 | d6 = NC
403 movel a1@(40),d0 | xdir
405 orl a1@(44),d0 | ydir
407 orl a1@(48),d0 | SX/SY
409 lea GC_BASE,a0 | point to video control registers
410 movel a6@(24),a0@(GCW_INTEN) | intensity
411 movel a6@(28),a0@(GCW_PSEL) | plane select
412 movel #0x0e,a0@(GCW_CMD) | write, 4x5, 1 of 20
417 movel d3,a0@(GCW_PY) | pixel Y addr
418 movel d2,a0@(GCW_PX_SM) | pixel X addr, start single mem
421 movel d4,a0@(GCW_LG2) | line gen, ND15-ND0
422 movel d5,a0@(GCW_LG1) | line gen, NB15-NB0
423 movel d7,a0@(GCW_LG2) | line gen, ND15-ND0
424 movel d6,a0@(GCW_LG3) | line-gen, NC11-NC0
425 movel d0,a0@(GCW_LG4) | line-gen, SX, SY, XMAJ
426 movel d3,a0@(GCW_PY) | pixel Y
427 movel d2,a0@(GCW_PX_SL) | pixel X, start line
429 moveml sp@+,d0-d7/a0-a6
433 | in-lined version of ldraw including y loop counter
439 moveml d0-d7/a0-a2,sp@-
440 lea gr_data,a1 | point to data space
442 movel a6@(12),d3 | y1
443 movel a6@(20),a2 | y3
449 movel a6@(16),d1 | x2
450 movel a6@(12),d0 | y2 = y1
451 moveb #0x03,line_flag | magic number ?
454 movel d5,a1@(40) | set x direction flag
455 movel d5,a1@(44) | set y direction flag
456 subl d2,d1 | (d1-d2)->d1, (x2 - x1) -> d1
457 movel d1,a1@(16) | delta-x
459 subl d3,d0 | (y2 - y1) -> d0
460 movel d0,a1@(20) | delta-y
461 cmpl d1,d0 | delta-y - delta-x
462 bgt ldraw4y_6 | bra if delta-y > delta-x
463 movel d5,d0 | set d0 to 1
466 clrl d0 | set d0 to 0
468 movel d0,a1@(48) | set to 0 if delta-y > delta-x, else set to 1
469 beq ldraw4y_8 | bra if delta-y > delta-x
470 movel a1@(20),d5 | delta-y to d5
471 lsll #1,d5 | shift left (mul by 2)
472 movel d5,d4 | copy to d4
473 subl a1@(16),d4 | (2 * dy) - dx -> d4
474 subl a1@(40),d4 | d4 - xdir -> d4
475 movel a1@(16),d6 | dx -> d6
476 movel a1@(20),d7 | dy -> d7
477 subl d6,d7 | dy - dx -> d7
478 lsll #1,d7 | shift left, d7 = ND/NA
481 movel a1@(16),d5 | dx
482 lsll #1,d5 | shift left (mul by 2)
484 subl a1@(20),d4 | (2 * dx) - dy
485 subl a1@(44),d4 | ydir
486 movel a1@(20),d6 | dy
487 movel a1@(16),d7 | dx
489 lsll #1,d7 | shift left, d7 = ND/NA
492 | by this point, d4 = ND/NA, d5 = NB
494 subql #1,d6 | d6 = NC
495 movel a1@(40),d0 | xdir
497 orl a1@(44),d0 | ydir
499 orl a1@(48),d0 | SX/SY
501 lea GC_BASE,a0 | point to video control registers
502 movel a6@(24),a0@(GCW_INTEN) | intensity
503 movel #0xff,a0@(GCW_PSEL) | plane select
504 movel #0x0e,a0@(GCW_CMD) | write, 4x5, 1 of 20
509 movel d3,a0@(GCW_PY) | pixel Y addr
510 movel d2,a0@(GCW_PX_SM) | pixel X addr, start single mem
513 movel d4,a0@(GCW_LG2) | line gen, ND15-ND0
514 movel d5,a0@(GCW_LG1) | line gen, NB15-NB0
515 movel d7,a0@(GCW_LG2) | line gen, ND15-ND0
516 movel d6,a0@(GCW_LG3) | line-gen, NC11-NC0
517 movel d0,a0@(GCW_LG4) | line-gen, SX, SY, XMAJ
518 movel d3,a0@(GCW_PY) | pixel Y
519 movel d2,a0@(GCW_PX_SL) | pixel X, start line
524 moveml sp@+,d0-d7/a0-a2
529 | in-lined version of ldraw including y loop counter
530 | this version optimised for horizontal lines
536 moveml d0-d7/a0-a2,sp@-
537 lea gr_data,a1 | point to data space
538 lea GC_BASE,a0 | base of video control registers
539 movel a6@(24),a0@(GCW_INTEN) | intensity
540 movel #0xff,a0@(GCW_PSEL) | plane select
542 movel a6@(12),d3 | y1
543 movel a6@(16),d1 | x2
544 movel a6@(20),a2 | y2
546 subl d2,d1 | (x2 - x1) -> d1
547 clrl d4 | d4 = (2 * dy) = NA
548 clrl d5 | d5 = (2 * dy) = NB
549 subl d1,d4 | (2 * dy) - dx -> d4
550 subql #1,d4 | d4 - SX -> d4
551 movel d1,d6 | dx -> d6
552 movel d5,d7 | dy -> d7
553 subl d6,d7 | dy - dx -> d7
554 lsll #1,d7 | shift left, d7 = ND
556 | by this point, d4 = ND, d5 = NB
558 subql #1,d6 | d6 = NC
559 moveq #7,d0 | SX, SY, XMAJ
561 | we are drawing a series of horizontal lines, all the same length
562 | so no need to re-calculate all the magic numbers each time
565 cmpl d3,a2 | y1 <= y2
569 movel #0x0e,a0@(GCW_CMD) | write, 4x5, 1 of 20
572 movel d3,a0@(GCW_PY) | pixel Y addr
573 movel d2,a0@(GCW_PX_SM) | pixel X addr, start single mem
576 movel d4,a0@(GCW_LG2) | NA
577 movel d5,a0@(GCW_LG1) | NB
578 movel d7,a0@(GCW_LG2) | ND
579 movel d6,a0@(GCW_LG3) | NC
580 movel d0,a0@(GCW_LG4) | SX, SY, XMAJ
581 movel d3,a0@(GCW_PY) | pixel Y
582 movel d2,a0@(GCW_PX_SL) | pixel X, start line
587 moveml sp@+,d0-d7/a0-a2
591 | in-lined version of ldraw including x loop counter
592 | this version optimised for vertical lines
598 moveml d0-d7/a0-a2,sp@-
599 lea gr_data,a1 | point to data space
600 lea GC_BASE,a0 | base of video control registers
601 movel a6@(24),a0@(GCW_INTEN) | intensity
602 movel #0xff,a0@(GCW_PSEL) | plane select
604 movel a6@(12),d3 | y1
605 movel a6@(20),d1 | y2
606 movel a6@(16),a2 | x2
608 subl d3,d1 | (y2 - y1) -> d1
609 clrl d4 | d4 = (2 * dx) = NA
610 clrl d5 | d5 = (2 * dx) = NB
611 subl d1,d4 | (2 * dx) - dy -> d4
612 subql #1,d4 | d4 - SY -> d4
613 movel d1,d6 | dy -> d6
614 movel d5,d7 | dx -> d7
615 subl d6,d7 | dx - dy -> d7
616 lsll #1,d7 | shift left, d7 = ND
618 | by this point, d4 = ND, d5 = NB
620 subql #1,d6 | d6 = NC
621 moveq #6,d0 | SX, SY, XMAJ
623 | we are drawing a series of vertical lines, all the same length
624 | so no need to re-calculate all the magic numbers each time
627 cmpl d2,a2 | x1 <= x2
631 movel #0x0e,a0@(GCW_CMD) | write, 4x5, 1 of 20
634 movel d3,a0@(GCW_PY) | pixel Y addr
635 movel d2,a0@(GCW_PX_SM) | pixel X addr, start single mem
638 movel d4,a0@(GCW_LG2) | NA
639 movel d5,a0@(GCW_LG1) | NB
640 movel d7,a0@(GCW_LG2) | ND
641 movel d6,a0@(GCW_LG3) | NC
642 movel d0,a0@(GCW_LG4) | SX, SY, XMAJ
643 movel d3,a0@(GCW_PY) | pixel Y
644 movel d2,a0@(GCW_PX_SL) | pixel X, start line
649 moveml sp@+,d0-d7/a0-a2
653 | read 1 pixel from the screen, handle the bizarre layout
661 subw a6@(14),d5 | d5 is y as 16-bit value
663 andib #0xfc,d4 | d4 is y0
666 movel #3,d3 | ensure top word is clear
667 subw d0,d3 | 3 - (y & 3)
670 divuw #20,d0 | x % 20
671 clrw d0 | clear quotient
672 swap d0 | put remainder in lower 16 bits
673 divuw #5,d0 | (x % 20) / 5
675 addw d0,d3 | ys in d3
682 lea GC_BASE,a0 | base of video control registers
683 movel a6@(16),a0@(GCW_PSEL) | plane select mask
684 movel #0x07,a0@(GCW_LG4)
685 movel #0x66,a0@(GCW_CMD)
686 movel a6@(8),a0@(GCW_PX) | x
687 movel d4,a0@(GCW_PY) | y
688 movel a0@(GCR_IN_SM),d0 | read intensity, start single mem cycle
689 movel a0@(GCR_IN_SM),d0
694 andl d1,d0 | (ic & (0xff << fs)
701 | read a rectangular array of pixels from the screen
702 | void rd_rect(int x1, int y1, int x2, int y2, char *buf)
708 moveml d1-d7/a0-a1,sp@-
710 subl a6@(20),d7 | d7 is y2 as 16-bit value
713 subl a6@(12),d6 | d6 is y1 as 16-bit value
715 movel a6@(8),d5 | d5 is x
716 lea GC_BASE,a0 | base of video control registers
717 movel a6@(24),a1 | buf
719 cmpw a6@(18),d5 | x < x2
723 movel d5,d4 | d4 is xs
724 divuw #20,d4 | x % 20
725 clrw d4 | clear quotient
726 swap d4 | remainder in lower word
727 divuw #5,d4 | (x % 20) / 5
728 aslw #3,d4 | ((x % 20) / 5) << 3
734 movel d6,d3 | d3 is y0
735 andib #0xfc,d3 | y & 0xfffc
738 moveq #3,d2 | ensure top word is clear
739 subw d0,d2 | 3 - (y & 3)
741 addw d4,d2 | ys in d2
748 movel #0xff,a0@(GCW_PSEL) | plane select mask
749 movel #0x07,a0@(GCW_LG4)
750 movel #0x66,a0@(GCW_CMD)
751 movel d5,a0@(GCW_PX) | x
752 movel d3,a0@(GCW_PY) | y0
753 movel a0@(GCR_IN_SM),d1 | read intensity, start single mem cycle
754 movel a0@(GCR_IN_SM),d1
758 andl d1,d0 | (ic & (0xff << fs)
761 moveb d0,a1@+ | *buf++
767 movel a6@(12),d6 | y = y1
770 moveml sp@+,d1-d7/a0-a1
775 | write a rectangular array of pixels to the screen
776 | void wr_rect(int x1, int y1, int x2, int y2, char *buf)
782 moveml d1-d7/a0-a1,sp@-
784 subl a6@(20),d7 | d7 is y2 as 16-bit value
787 subl a6@(12),d6 | d6 is y1 as 16-bit value
789 movel a6@(8),d5 | d5 is x
790 lea GC_BASE,a0 | base of video control registers
791 movel a6@(24),a1 | buf
793 cmpw a6@(18),d5 | x < x2
797 movel d5,d4 | d4 is xs
798 divuw #20,d4 | x % 20
799 clrw d4 | clear quotient
800 swap d4 | remainder in lower word
801 divuw #5,d4 | (x % 20) / 5
802 aslw #3,d4 | ((x % 20) / 5) << 3
808 movel d6,d3 | d3 is y0
809 andib #0xfc,d3 | y & 0xfffc
810 movel #0xff,a0@(GCW_PSEL) | plane select mask
811 movel #0x07,a0@(GCW_LG4)
812 movel #0x66,a0@(GCW_CMD)
813 movel d5,a0@(GCW_PX) | x
814 movel d3,a0@(GCW_PY) | y0
815 movel a0@(GCR_IN_SM),d1 | read intensity, start single mem cycle
816 movel a0@(GCR_IN_SM),d1 | d1 is ic
819 moveq #3,d2 | ensure top word is clear
820 subw d0,d2 | 3 - (y & 3)
822 addw d4,d2 | ys in d2
833 andl d1,d0 | (ic & (0cff << ys))
835 moveb a1@+,d1 | *buf++
838 movel #0xff,a0@(GCW_PSEL) | plane select mask
839 movel #0x07,a0@(GCW_LG4)
840 movel #0x6e,a0@(GCW_CMD)
841 movel d5,a0@(GCW_PX) | x
842 movel d3,a0@(GCW_PY) | y0
843 movel d0,a0@(GCW_IN_SM) | write inten, start single mem cycle
849 movel a6@(12),d6 | y = y1
852 moveml sp@+,d1-d7/a0-a1
856 | write a rectangular array of pixels to the screen
857 | void wr_rect4(int x1, int y1, int x2, int y2, char *buf)
859 | This version writes the block with the x axis as the inner loop,
860 | this is slower than wr_rect2() but is necessary for the VNC
861 | CopyDataToScreen() function.
867 moveml d1-d7/a0-a1,sp@-
869 subl a6@(20),d7 | d7 is y2 as 16-bit value
872 subl a6@(12),d6 | d6 is y1 as 16-bit value
874 movel a6@(8),d5 | d5 is x
875 lea GC_BASE,a0 | base of video control registers
876 movel a6@(24),a1 | buf
882 movel d6,d3 | d3 is y0
883 andib #0xfc,d3 | y & 0xfffc
886 moveq #3,d2 | ensure top word is clear
887 subw d0,d2 | 3 - (y & 3)
890 cmpw a6@(18),d5 | x < x2
894 movel #0xff,a0@(GCW_PSEL) | plane select mask
895 movel #0x07,a0@(GCW_LG4)
896 movel #0x66,a0@(GCW_CMD)
897 movel d5,a0@(GCW_PX) | x
898 movel d3,a0@(GCW_PY) | y0
899 movel a0@(GCR_IN_SM),d1 | read intensity, start single mem cycle
900 movel a0@(GCR_IN_SM),d1 | d1 is ic
901 movel d5,d4 | d4 is xs
902 divuw #20,d4 | x % 20
903 clrw d4 | clear quotient
904 swap d4 | remainder in lower word
905 divuw #5,d4 | (x % 20) / 5
906 aslw #3,d4 | ((x % 20) / 5) << 3
907 addw d2,d4 | ys in d2, xs in d4
918 andl d1,d0 | (ic & (0cff << ys))
920 moveb a1@+,d1 | *buf++
923 movel #0xff,a0@(GCW_PSEL) | plane select mask
924 movel #0x07,a0@(GCW_LG4)
925 movel #0x6e,a0@(GCW_CMD)
926 movel d5,a0@(GCW_PX) | x
927 movel d3,a0@(GCW_PY) | y0
928 movel d0,a0@(GCW_IN_SM) | write inten, start single mem cycle
934 movel a6@(8),d5 | x = x1
937 moveml sp@+,d1-d7/a0-a1
941 | write a rectangular array of pixels to the screen
942 | void wr_rect5(int x1, int y1, int x2, int y2, char *buf)
944 | This version writes the block with the x axis as the inner loop,
945 | this is slower than wr_rect2() but is necessary for the VNC
946 | CopyDataToScreen() function.
948 | This version uses a lookup table for the pixel mask and shift count.
949 | This removes one of the divide instructions (divides are slow).
955 moveml d1-d7/a0-a2,sp@-
957 subl a6@(20),d7 | d7 is y2
959 subl a6@(12),d6 | d6 is y1
960 movel a6@(8),d5 | d5 is x
961 lea GC_BASE,a0 | base of video control registers
962 movel a6@(24),a1 | buf
963 lea pm_tab,a2 | base of lookup table
964 movel #0xff,a0@(GCW_PSEL) | plane select mask
968 movel d6,d3 | d3 is y0
969 andib #0xfc,d3 | y & 0xfffc
972 asll #3,d2 | (y & 3) * 8
974 cmpl a6@(16),d5 | x < x2
976 movel #0x07,a0@(GCW_LG4)
977 movel #0x66,a0@(GCW_CMD)
978 movel d5,a0@(GCW_PX) | x
979 movel d3,a0@(GCW_PY) | y0
980 movel a0@(GCR_IN_SM),d1 | read intensity, start single mem cycle
981 movel a0@(GCR_IN_SM),d1 | d1 is ic
982 movel d5,d4 | d4 is xs
983 divuw #20,d4 | x % 20
984 clrw d4 | clear quotient
985 swap d4 | remainder in lower word
987 addl d2,d4 | ((x % 20) * 32) + ((y % 4) * 8)
988 movel a2@(d4:w:1),d0 | fetch mask
989 andl d1,d0 | (ic & mask)
990 | andl a2@(d4:w:1),d0 | (ic & mask)
992 moveb a1@+,d1 | *buf++
994 movel a2@(d4:w:1),d4 | fetch shift count
997 movel #0x07,a0@(GCW_LG4)
998 movel #0x6e,a0@(GCW_CMD)
999 movel d5,a0@(GCW_PX) | x
1000 movel d3,a0@(GCW_PY) | y0
1001 movel d0,a0@(GCW_IN_SM) | write inten, start single mem cycle
1007 movel a6@(8),d5 | x = x1
1010 moveml sp@+,d1-d7/a0-a2
1014 | write 1 pixel to the screen, handle the bizarre layout
1020 moveml d1-d5/a0,sp@-
1022 subw a6@(14),d5 | d5 is y as 16-bit value
1024 andib #0xfc,d4 | d4 is y0
1025 lea GC_BASE,a0 | base of video control registers
1026 movel a6@(16),a0@(GCW_PSEL) | plane select mask
1027 movel #0x07,a0@(GCW_LG4)
1028 movel #0x66,a0@(GCW_CMD)
1029 movel a6@(8),a0@(GCW_PX) | x
1030 movel d4,a0@(GCW_PY) | y0
1031 movel a0@(GCR_IN_SM),d0 | read intensity, start single mem cycle
1032 movel a0@(GCR_IN_SM),d0 | 4 pixels in d0
1033 movel d0,d3 | ic in d3
1036 movel #3,d2 | ensure top word is clear
1037 subw d0,d2 | 3 - (y & 3)
1040 divuw #20,d0 | x % 20
1041 clrw d0 | clear quotient
1042 swap d0 | put remainder in lower 16 bits
1043 divuw #5,d0 | (x % 20) / 5
1045 addw d0,d2 | ys in d2
1056 andl d3,d0 | (ic & (0xff << ys)
1057 movel a6@(20),d1 | i
1058 asll d2,d1 | i << ys
1060 movel a6@(16),a0@(GCW_PSEL) | plane select mask
1061 movel #0x07,a0@(GCW_LG4)
1062 movel #0x6e,a0@(GCW_CMD)
1063 movel a6@(8),a0@(GCW_PX) | x
1064 movel d4,a0@(GCW_PY) | y0
1065 movel d0,a0@(GCW_IN_SM) | write inten, start single mem cycle
1066 moveml sp@+,d1-d5/a0
1074 | lookup table for wr_rect5()
1075 | this gives the pixel mask and shift count to locate each pixel in
1076 | the 4 x 20 array pattern used by the Prisma video board
1078 pm_tab: .long 0x00ffffff, 24 | 0,0
1079 .long 0xff00ffff, 16 | 0,1
1080 .long 0xffff00ff, 8 | 0,2
1081 .long 0xffffff00, 0 | 0,3
1082 .long 0x00ffffff, 24 | 1,0
1083 .long 0xff00ffff, 16 | 1,1
1084 .long 0xffff00ff, 8 | 1,2
1085 .long 0xffffff00, 0 | 1,3
1086 .long 0x00ffffff, 24 | 2,0
1087 .long 0xff00ffff, 16 | 2,1
1088 .long 0xffff00ff, 8 | 2,2
1089 .long 0xffffff00, 0 | 2,3
1090 .long 0x00ffffff, 24 | 3,0
1091 .long 0xff00ffff, 16 | 3,1
1092 .long 0xffff00ff, 8 | 3,2
1093 .long 0xffffff00, 0 | 3,3
1094 .long 0x00ffffff, 24 | 4,0
1095 .long 0xff00ffff, 16 | 4,1
1096 .long 0xffff00ff, 8 | 4,2
1097 .long 0xffffff00, 0 | 4,3
1098 .long 0xffffff00, 0 | 5,0
1099 .long 0x00ffffff, 24 | 5,1
1100 .long 0xff00ffff, 16 | 5,2
1101 .long 0xffff00ff, 8 | 5,3
1102 .long 0xffffff00, 0 | 6,0
1103 .long 0x00ffffff, 24 | 6,1
1104 .long 0xff00ffff, 16 | 6,2
1105 .long 0xffff00ff, 8 | 6,3
1106 .long 0xffffff00, 0 | 7,0
1107 .long 0x00ffffff, 24 | 7,1
1108 .long 0xff00ffff, 16 | 7,2
1109 .long 0xffff00ff, 8 | 7,3
1110 .long 0xffffff00, 0 | 8,0
1111 .long 0x00ffffff, 24 | 8,1
1112 .long 0xff00ffff, 16 | 8,2
1113 .long 0xffff00ff, 8 | 8,3
1114 .long 0xffffff00, 0 | 9,0
1115 .long 0x00ffffff, 24 | 9,1
1116 .long 0xff00ffff, 16 | 9,2
1117 .long 0xffff00ff, 8 | 9,3
1118 .long 0xffff00ff, 8 | 10,0
1119 .long 0xffffff00, 0 | 10,1
1120 .long 0x00ffffff, 24 | 10,2
1121 .long 0xff00ffff, 16 | 10,3
1122 .long 0xffff00ff, 8 | 11,0
1123 .long 0xffffff00, 0 | 11,1
1124 .long 0x00ffffff, 24 | 11,2
1125 .long 0xff00ffff, 16 | 11,3
1126 .long 0xffff00ff, 8 | 12,0
1127 .long 0xffffff00, 0 | 12,1
1128 .long 0x00ffffff, 24 | 12,2
1129 .long 0xff00ffff, 16 | 12,3
1130 .long 0xffff00ff, 8 | 13,0
1131 .long 0xffffff00, 0 | 13,1
1132 .long 0x00ffffff, 24 | 13,2
1133 .long 0xff00ffff, 16 | 13,3
1134 .long 0xffff00ff, 8 | 14,0
1135 .long 0xffffff00, 0 | 14,1
1136 .long 0x00ffffff, 24 | 14,2
1137 .long 0xff00ffff, 16 | 14,3
1138 .long 0xff00ffff, 16 | 15,0
1139 .long 0xffff00ff, 8 | 15,1
1140 .long 0xffffff00, 0 | 15,2
1141 .long 0x00ffffff, 24 | 15,3
1142 .long 0xff00ffff, 16 | 16,0
1143 .long 0xffff00ff, 8 | 16,1
1144 .long 0xffffff00, 0 | 16,2
1145 .long 0x00ffffff, 24 | 16,3
1146 .long 0xff00ffff, 16 | 17,0
1147 .long 0xffff00ff, 8 | 17,1
1148 .long 0xffffff00, 0 | 17,2
1149 .long 0x00ffffff, 24 | 17,3
1150 .long 0xff00ffff, 16 | 18,0
1151 .long 0xffff00ff, 8 | 18,1
1152 .long 0xffffff00, 0 | 18,2
1153 .long 0x00ffffff, 24 | 18,3
1154 .long 0xff00ffff, 16 | 19,0
1155 .long 0xffff00ff, 8 | 19,1
1156 .long 0xffffff00, 0 | 19,2
1157 .long 0x00ffffff, 24 | 19,3
1160 | temporary storage for line drawing routine
1163 line_x1: .long 0 | 0 (668)
1164 line_y1: .long 0 | 4 (66c)
1165 line_x2: .long 0 | 8 (670)
1166 line_y2: .long 0 | 12 (674)
1173 line_xdir: .long 0 | 40 (690)
1174 line_ydir: .long 0 | 44 (694)
1176 line_selmask: .long 0 | 52 (69c)
1177 line_inten: .long 0 | 56 (6A0)
1178 line_flag: .word 0 | 60 (6a4)
1179 init_flag1: .word 0 | 62 (6a6)
1182 init_flag4: .long 0 | 64 (6b0)
1198 init_flag6: .long 0 | 64 (6f0)
1199 init_flag5: .word 0 | 64 (6f4)
1200 init_flag2: .word 0 | 64 (6f6)
1201 init_flag3: .word 0 | 64 (6f8)