]> 4ch.mooo.com Git - 16.git/blob - 16/scrasm/PAGE.INC
i am too damn tired\! and i will not have anytime at all to even work on 16_sd and...
[16.git] / 16 / scrasm / PAGE.INC
1 ;; ====================================================================\r
2 ;; (Code follows)\r
3 ;; ====================================================================\r
4 \r
5 EVEN\r
6 upper_left      dw      0               ; Stores upper left corner offset\r
7                                         ; relative to page offset.\r
8 pages           dw      0               ; for counting frame-per-sec\r
9 \r
10 PAGE_INFO       STRUCT 2,NONUNIQUE\r
11                 Address         dw      0\r
12                 UpperLeftAddress dw     0\r
13                 MapPosX         dw      0\r
14                 MapPosY         dw      0\r
15                 Alignment       db      0\r
16                 AlignmentMask   db      0\r
17                 ScrollOffset    dw      0\r
18                 Rectangles      dw      0\r
19                 Valid           db      0\r
20 PAGE_INFO       ENDS\r
21 \r
22 DrawPage        PAGE_INFO <PAGE_0,PAGE_0>\r
23 ShowPage        PAGE_INFO <PAGE_1,PAGE_1>\r
24 BlankPage       PAGE_INFO <PAGE_2,PAGE_2>\r
25 \r
26 ROTATE3         MACRO   reg,item\r
27                 mov     reg,cs:ShowPage.item\r
28                 xchg    reg,cs:BlankPage.item\r
29                 xchg    reg,cs:DrawPage.item\r
30                 mov     cs:ShowPage.item,reg\r
31                 ENDM    ; Leaves ShowPage.item in reg!\r
32 \r
33 ;; This procedure is used to flip between the three available pages.\r
34 ;; Originally from Dr. Dobb's Journal's Graphics Programming column by\r
35 ;; Michael Abrash, I've reworked the code to be more specific to my\r
36 ;; own purposes, and commented it more.\r
37 EVEN\r
38 FlipPage        PROC    near\r
39         ; This series of instructions circles the show_page, blank_page,\r
40         ; and draw page appropriately and leaves the current page to show\r
41         ; in AX.  Note that it's a lot more instructions than it looks like,\r
42         ; but I unrolled the copy loop for speed.  So-so good idea, because\r
43         ; if you add a field and forget to rotate it, it could mean trouble!\r
44                 ROTATE3 ax,Rectangles\r
45                 ROTATE3 ax,ScrollOffset\r
46                 ROTATE3 ax,MapPosX\r
47                 ROTATE3 ax,MapPosY\r
48 ;               ROTATE3 al,AlignmentMask        SPRITES ...\r
49                 ROTATE3 al,Alignment\r
50                 mov     di,ax           ; DI = scroll offset low, and\r
51                                         ; garbage in the high bits...\r
52                 and     di,3            ; DI = pixel pan, 0 to 3.\r
53                 shl     di,1            ; Mode X requires 0 2 4 or 6.\r
54                 ROTATE3 ax,Address\r
55                 ROTATE3 al,Valid\r
56                 ROTATE3 ax,UpperLeftAddress ; Leaves AX=ShowPage.ULAddr\r
57 \r
58                 add     ax,cs:ShowPage.ScrollOffset\r
59 \r
60         ; AX is set up to be the current show page already.\r
61         ; By pre-loading BX with the low-address set code, and CX with\r
62         ; the high-address set code, we can more quickly flip the page\r
63         ; after the vertical retrace period.\r
64                 mov     bl,START_ADDRESS_LOW    ;preload for fastest\r
65                 mov     bh,al                   ; flipping once display\r
66                 mov     cl,START_ADDRESS_HIGH   ; enable is detected\r
67                 mov     ch,ah\r
68 \r
69         ; Wait for display enable to be active (status is active low), to be\r
70         ; sure both halves of the start address will take in the same frame.\r
71                 mov     dx,INPUT_STATUS_1\r
72 WaitDE:         in      al,dx\r
73                 test    al,01h\r
74                 jnz     WaitDE  ;display enable is active low (0 = active)\r
75 \r
76         ; Set the start offset in display memory of the page to display.\r
77                 mov     dx,CRTC_INDEX\r
78                 mov     ax,bx\r
79                 out     dx,ax   ;start address low\r
80                 mov     ax,cx\r
81                 out     dx,ax   ;start address high\r
82 \r
83         ; Now wait for vertical sync, so the other page will be invisible when\r
84         ; we start drawing to it.\r
85                 mov     dx,INPUT_STATUS_1\r
86 WaitVS:         in      al,dx\r
87                 test    al,08h\r
88                 jz      WaitVS  ;vertical sync is active high (1 = active)\r
89 \r
90         ; Finally, have to adjust the pixel panning register in order\r
91         ; to fine-tune the starting address on a pixel level.\r
92         ; This pixel pan value is the scroll offset mod 4 -- but since\r
93         ; Mode X's pixel pan works by values of 2 (0, 2, 4 or 6) we\r
94         ; have to shift appropriately.\r
95                 mov     dx,ATC_INDEX\r
96                 mov     al,13h  ; 13h = set pixel pan\r
97                 out     dx,al\r
98                 mov     ax,di   ; DI = pixel pan calculated above\r
99                 out     dx,al\r
100                 mov     dx,ATC_INDEX\r
101                 mov     al,32   ; Allows the computer to use this register\r
102                 out     dx,al   ; again.  Without this OUT, the screen will\r
103                                 ; remain blank!\r
104 \r
105         ; Increment the page counter now!\r
106                 inc     cs:pages\r
107                 ret\r
108 FlipPage        ENDP\r
109 \1a