home *** CD-ROM | disk | FTP | other *** search
/ The Unsorted BBS Collection / thegreatunsorted.tar / thegreatunsorted / programming / asm_programming / VERTSCR.ZIP / MODEX.INC next >
Text File  |  1993-07-16  |  18KB  |  638 lines

  1. LABEL X320Y200 word 
  2.     db      00      ; 0e3h    ; dot clock
  3.     db      02      ; Number of CRTC Registers to update
  4.     dw      00014h  ; turn off dword mode
  5.     dw      0e317h  ; turn on byte mode
  6.     dw      320     ; width
  7.     dw      200     ; height
  8.  
  9. LABEL X320Y200s word 
  10.     db      0e3h    ; dot clock
  11.     db      02      ; Number of CRTC Registers to update
  12.     dw      00014h  ; turn off dword mode
  13.     dw      0e317h  ; turn on byte mode
  14.     dw      320     ; width
  15.     dw      200     ; height
  16.  
  17. LABEL X320Y240 word
  18.     db      0e3h    ; dot clock
  19.     db      10      ; Number of CRTC Registers to update
  20.     dw      00d06h  ; vertical total
  21.     dw      03e07h  ; overflow (bit 8 of vertical counts)
  22.     dw      04109h  ; cell height (2 to double-scan)
  23.     dw      0ea10h  ; v sync start
  24.     dw      0ac11h  ; v sync end and protect cr0-cr7
  25.     dw      0df12h  ; vertical displayed
  26.     dw      00014h  ; turn off dword mode
  27.     dw      0e715h  ; v blank start
  28.     dw      00616h  ; v blank end
  29.     dw      0e317h  ; turn on byte mode
  30.     dw      320     ; width
  31.     dw      240     ; height
  32.  
  33. LABEL X360Y200 word
  34.     db      0e7h    ; dot clock
  35.     db      08      ; Number of CRTC Registers to update
  36.     dw      06b00h  ; horz total
  37.     dw      05901h  ; horz displayed
  38.     dw      05a02h  ; start horz blanking
  39.     dw      08e03h  ; end horz blanking
  40.     dw      05e04h  ; start h sync
  41.     dw      08a05h  ; end h sync
  42.     dw      00014h  ; turn off dword mode
  43.     dw      0e317h  ; turn on byte mode
  44.     dw      360     ; width
  45.     dw      200     ; height
  46.  
  47. LABEL X360Y240 word
  48.     db      0e7h    ; dot clock
  49.     db      16      ; Number of CRTC Registers to update
  50.     dw      06b00h  ; horz total
  51.     dw      05901h  ; horz displayed
  52.     dw      05a02h  ; start horz blanking
  53.     dw      08e03h  ; end horz blanking
  54.     dw      05e04h  ; start h sync
  55.     dw      08a05h  ; end h sync
  56.     dw      00d06h  ; vertical total
  57.     dw      03e07h  ; overflow (bit 8 of vertical counts)
  58.     dw      04109h  ; cell height (2 to double-scan)
  59.     dw      0ea10h  ; v sync start
  60.     dw      0ac11h  ; v sync end and protect cr0-cr7
  61.     dw      0df12h  ; vertical displayed
  62.     dw      00014h  ; turn off dword mode
  63.     dw      0e715h  ; v blank start
  64.     dw      00616h  ; v blank end
  65.     dw      0e317h  ; turn on byte mode
  66.     dw      360
  67.     dw      240
  68.  
  69. LABEL X376Y282 word
  70.     db      0e7h
  71.     db      18
  72.     dw      06e00h  ; horz total
  73.     dw      05d01h  ; horz displayed
  74.     dw      05e02h  ; start horz blanking
  75.     dw      09103h  ; end horz blanking
  76.     dw      06204h  ; start h sync
  77.     dw      08f05h  ; end h sync
  78.     dw      06206h  ; vertical total
  79.     dw      0f007h  ; overflow
  80.     dw      06109h  ; cell height
  81.     dw      0310fh  ;
  82.     dw      03710h  ; v sync start
  83.     dw      08911h  ; v sync end and protect cr0-cr7
  84.     dw      03312h  ; vertical displayed
  85.     dw      02f13h  ; offset
  86.     dw      00014h  ; turn off dword mode
  87.     dw      03c15h  ; v blank start
  88.     dw      05c16h  ; v blank end
  89.     dw      0e317h  ; turn on byte mode
  90.     dw      376
  91.     dw      564
  92.  
  93. LABEL X320Y400 word
  94.     db      00      ;0e3h    ; dot clock
  95.     db      03      ; Number of CRTC Registers to update
  96.     dw      04009h  ; cell height
  97.     dw      00014h  ; turn off dword mode
  98.     dw      0e317h  ; turn on byte mode
  99.     dw      320     ; width
  100.     dw      400     ; height
  101.  
  102. LABEL X320Y480 word
  103.     db      0e3h    ; dotclock
  104.     db      10      ; Number of CRTC Registers to update
  105.     dw      00d06h  ; vertical total
  106.     dw      03e07h  ; overflow (bit 8 of vertical counts)
  107.     dw      04009h  ; cell height (2 to double-scan)
  108.     dw      0ea10h  ; v sync start
  109.     dw      0ac11h  ; v sync end and protect cr0-cr7
  110.     dw      0df12h  ; vertical displayed
  111.     dw      00014h  ; turn off dword mode
  112.     dw      0e715h  ; v blank start
  113.     dw      00616h  ; v blank end
  114.     dw      0e317h  ; turn on byte mode
  115.     dw      320     ; width
  116.     dw      480     ; height
  117.  
  118. LABEL X360Y400 word
  119.     db      0e7h    ; dot clock
  120.     db      09      ; Number of CRTC Registers to update
  121.     dw      06b00h  ; horz total
  122.     dw      05901h  ; horz displayed
  123.     dw      05a02h  ; start horz blanking
  124.     dw      08e03h  ; end horz blanking
  125.     dw      05e04h  ; start h sync
  126.     dw      08a05h  ; end h sync
  127.     dw      04009h  ; cell height
  128.     dw      00014h  ; turn off dword mode
  129.     dw      0e317h  ; turn on byte mode
  130.     dw      360     ; width
  131.     dw      400     ; height
  132.  
  133.  
  134. LABEL X360Y480 word
  135.     db      0e7h
  136.     db      17
  137.     dw      06b00h  ; horz total
  138.     dw      05901h  ; horz displayed
  139.     dw      05a02h  ; start horz blanking
  140.     dw      08e03h  ; end horz blanking
  141.     dw      05e04h  ; start h sync
  142.     dw      08a05h  ; end h sync
  143.     dw      00d06h  ; vertical total
  144.     dw      03e07h  ; overflow
  145.     dw      04009h  ; cell height
  146.     dw      0ea10h  ; v sync start
  147.     dw      0ac11h  ; v sync end and protect cr0-cr7
  148.     dw      0df12h  ; vertical displayed
  149.     dw      02d13h  ; offset
  150.     dw      00014h  ; turn off dword mode
  151.     dw      0e715h  ; v blank start
  152.     dw      00616h  ; v blank end
  153.     dw      0e317h  ; turn on byte mode
  154.     dw      360
  155.     dw      480
  156.  
  157. LABEL X360Y360 word
  158.     db      0e7h
  159.     db      15
  160.     dw      06b00h  ; horz total
  161.     dw      05901h  ; horz displayed
  162.     dw      05a02h  ; start horz blanking
  163.     dw      08e03h  ; end horz blanking
  164.     dw      05e04h  ; start h sync
  165.     dw      08a05h  ; end h sync
  166.     dw      04009h  ; cell height
  167.     dw      08810h  ; v sync start
  168.     dw      08511h  ; v sync end and protect cr0-cr7
  169.     dw      06712h  ; vertical displayed
  170.     dw      02d13h  ; offset
  171.     dw      00014h  ; turn off dword mode
  172.     dw      06d15h  ; v blank start
  173.     dw      0ba16h  ; v blank end
  174.     dw      0e317h  ; turn on byte mode
  175.     dw      360
  176.     dw      360
  177.  
  178. LABEL X376Y308 word
  179.     db      0e7h
  180.     db      18
  181.     dw      06e00h  ; horz total
  182.     dw      05d01h  ; horz displayed
  183.     dw      05e02h  ; start horz blanking
  184.     dw      09103h  ; end horz blanking
  185.     dw      06204h  ; start h sync
  186.     dw      08f05h  ; end h sync
  187.     dw      06206h  ; vertical total
  188.     dw      00f07h  ; overflow
  189.     dw      04009h  ;
  190.     dw      0310fh  ;
  191.     dw      03710h  ; v sync start
  192.     dw      08911h  ; v sync end and protect cr0-cr7
  193.     dw      03312h  ; vertical displayed
  194.     dw      02f13h  ; offset
  195.     dw      00014h  ; turn off dword mode
  196.     dw      03c15h  ; v blank start
  197.     dw      05c16h  ; v blank end
  198.     dw      0e317h  ; turn on byte mode
  199.     dw      376
  200.     dw      308
  201.  
  202. LABEL X376Y564 word
  203.     db      0e7h
  204.     db      18
  205.     dw      06e00h  ; horz total
  206.     dw      05d01h  ; horz displayed
  207.     dw      05e02h  ; start horz blanking
  208.     dw      09103h  ; end horz blanking
  209.     dw      06204h  ; start h sync
  210.     dw      08f05h  ; end h sync
  211.     dw      06206h  ; vertical total
  212.     dw      0f007h  ; overflow
  213.     dw      06009h  ;
  214.     dw      0310fh  ;
  215.     dw      03710h  ; v sync start
  216.     dw      08911h  ; v sync end and protect cr0-cr7
  217.     dw      03312h  ; vertical displayed
  218.     dw      02f13h  ; offset
  219.     dw      00014h  ; turn off dword mode
  220.     dw      03c15h  ; v blank start
  221.     dw      05c16h  ; v blank end
  222.     dw      0e317h  ; turn on byte mode
  223.     dw      376
  224.     dw      564
  225.  
  226. LABEL X256Y240 word
  227.     db      0e3h    ; dot clock
  228.     db      16      ; Number of CRTC Registers to update
  229.     dw      05f00h  ; horz total
  230.     dw      03f01h  ; horz displayed
  231.     dw      04202h  ; start horz blanking
  232.     dw      09f03h  ; end horz blanking
  233.     dw      04c04h  ; start h sync
  234.     dw      00005h  ; end h sync
  235.     dw      00d06h  ; vertical total
  236.     dw      03e07h  ; overflow (bit 8 of vertical counts)
  237.     dw      04109h  ; cell height (2 to double-scan)
  238.     dw      0ea10h  ; v sync start
  239.     dw      0ac11h  ; v sync end and protect cr0-cr7
  240.     dw      0df12h  ; vertical displayed
  241.     dw      00014h  ; turn off dword mode
  242.     dw      0e715h  ; v blank start
  243.     dw      00616h  ; v blank end
  244.     dw      0e317h  ; turn on byte mode
  245.     dw      256
  246.     dw      240
  247.     
  248. LABEL X256Y200 word
  249.     db      0e3h    ; dot clock
  250.     db      8       ; Number of CRTC Registers to update
  251.     dw      05f00h  ; horz total
  252.     dw      03f01h  ; horz displayed
  253.     dw      04202h  ; start horz blanking
  254.     dw      09f03h  ; end horz blanking
  255.     dw      04c04h  ; start h sync
  256.     dw      00005h  ; end h sync
  257.     dw      00014h  ; turn off dword mode
  258.     dw      0e317h  ; turn on byte mode
  259.     dw      256
  260.     dw      200
  261.  
  262. LAST_X_MODE         =     14
  263.  
  264. LABEL ModeTable word    ; Mode X tweak table
  265.     dw      offset X320Y200
  266.     dw      offset X320Y240
  267.     dw      offset X360Y200
  268.     dw      offset X360Y240
  269.     dw      offset X376Y282
  270.     dw      offset X320Y400
  271.     dw      offset X320Y480
  272.     dw      offset X360Y400
  273.     dw      offset X360Y480
  274.     dw      offset X360Y360
  275.     dw      offset X376Y308
  276.     dw      offset X376Y564
  277.     dw      offset X256Y240
  278.     dw      offset x256y200
  279.     dw      offset X320Y200s
  280.     
  281. M320x200x256 =0     ;constants for easy calling
  282. M320x240x256 =1
  283. M360x200x256 =2
  284. M360x240x256 =3
  285. M376x282x256 =4
  286. M320x400x256 =5
  287. M320x480x256 =6
  288. M360x400x256 =7
  289. M360x480x256 =8
  290. M360x360x256 =9
  291. M376x308x256 =10
  292. M376x564x256 =11
  293. M256x240x256 =12    ;GREAT modes - ypos is upper byte, xpos is lower
  294. M256x200x256 =13
  295. M320x200x256s=14
  296.  
  297. InputStatus1=   3dah
  298. MISC_OUTPUT =   3c2h
  299. SC_Index    =   3c4h
  300. CRTC_Index  =   3d4h
  301. Graph_Index =   3ceh
  302. Attr_Index  =   3c0h    ;don't forget to clear flipflop & set bit 5 on index
  303. PEL_Write   =   3c8h
  304. PEL_Read    =   3c7h
  305. PEL_Data    =   3c9h
  306.  
  307. VGASeg      dw  0a000h
  308. ModeXWidth  dw  0
  309. ModeXHeight dw  0
  310. ModeXLogWidth dw 0
  311.  
  312. ;-----------------------------------------------------------------------
  313. ;
  314. ;   Sets mode # in AX, returns ax=0 if successful, ax=-1 if failed
  315. ;   cx= width of screen 
  316. ;
  317. ; SetModeX Adapted for VLA by Draeden,
  318. ; Originally written by Themie Gouthas,
  319. ; who adapted parts from M. Abrash code.
  320. ; (Talk about code reuse!)
  321. ;------------------------------------------------------------------------
  322. _Mode   dw  0
  323. _Scrw   dw  0
  324.  
  325. MACRO @SetModeX DaMode,DaWidth
  326.     mov     ax,DaMode
  327.     mov     cx,DaWidth
  328.     call    _Set_X_Mode
  329. ENDM @SetModeX
  330.  
  331. PROC _Set_X_Mode NEAR
  332.     pusha
  333.     push    es ds
  334.  
  335.     cld
  336.     mov     bx,cs
  337.     mov     ds,bx
  338.     mov     es,bx
  339.  
  340.     cmp     ax,LAST_X_MODE      ; have we selected a valid mode?
  341.     jle     @@ValidMode         ; Yes !
  342.  
  343.     pop     ds es
  344.     popa
  345.     mov     ax,-1               ; idiot.
  346.     ret
  347.  
  348. @@ValidMode:
  349.     mov     [_Mode],ax
  350.     mov     [_Scrw],cx
  351.  
  352.     mov     ax,13h              ; let the BIOS set standard 256-color
  353.     int     10h                 ;  mode (320x200 linear)
  354.     
  355.     mov     dx,SC_INDEX
  356.     mov     ax,0604h
  357.     out     dx,ax               ; disable chain4 mode
  358.     mov     ax,0100h
  359.     out     dx,ax               ; synchronous reset while setting Misc
  360.                                 ;  Output for safety, even though clock
  361.                                 ;  unchanged
  362.     mov     bx,[_Mode]
  363.     add     bx,bx
  364.     mov     si,[bx + ModeTable]
  365.     lodsb
  366.  
  367.     or      al,al
  368.     jz      @@DontSetDot
  369.     mov     dx,MISC_OUTPUT
  370.     out     dx,al               ; select the dot clock and Horiz
  371.                                 ;  scanning rate
  372. @@DontSetDot:
  373.     mov     dx,SC_INDEX
  374.     mov     ax,0300h
  375.     out     dx,ax               ; undo reset (restart sequencer)
  376.  
  377.     mov     dx,CRTC_INDEX       ; reprogram the CRT Controller
  378.     mov     al,11h              ; VSync End reg contains register write
  379.     out     dx,al               ; protect bit
  380.     inc     dx                  ; CRT Controller Data register
  381.     in      al,dx               ; get current VSync End register setting
  382.     and     al,07fh             ; remove write protect on various
  383.     out     dx,al               ; CRTC registers
  384.     dec     dx                  ; CRT Controller Index
  385.     cld
  386.     xor     cx,cx
  387.     lodsb
  388.     mov     cl,al
  389.  
  390. @@SetCRTParmsLoop:
  391.     lodsw                       ; get the next CRT Index/Data pair
  392.     out     dx,ax               ; set the next CRT Index/Data pair
  393.     dec     cx
  394.     jne     @@SetCRTParmsLoop
  395.  
  396.     lodsw
  397.     mov     [cs:ModeXWidth],ax
  398.     lodsw
  399.     mov     [cs:ModeXHeight],ax
  400.  
  401.     mov     dx,SC_INDEX
  402.     mov     ax,0f02h
  403.     out     dx,ax               ; enable writes to all four planes
  404.  
  405.                                 ; now clear all display memory, 8 pixels
  406.     mov     es,[cs:VGAseg]      ; at a time
  407.     sub     di,di               ; point ES:DI to display memory
  408.     sub     ax,ax               ; clear to zero-value pixels
  409.     mov     cx,8000h            ; # of words in display memory
  410.     rep     stosw               ; clear all of display memory
  411.     
  412.     ;  Mode X is set, now set the required logical page width.
  413.  
  414.     mov     cx,[cs:_Scrw]
  415.     shr     cx,2
  416.     mov     [cs:ModeXLogWidth],cx
  417.     shr     cx,1            ;divide by 8
  418.     mov     dx,CRTC_INDEX
  419.     mov     al,13h
  420.     mov     ah,cl
  421.     out     dx,ax
  422.  
  423.     pop     ds es
  424.     popa
  425.     xor     ax,ax
  426.     ret
  427. ENDP _Set_X_Mode
  428.  
  429. ────────────────────────────────────────────────────────────────────────────
  430. ;*   MISC planar mode routines
  431. ────────────────────────────────────────────────────────────────────────────
  432.  
  433.     ;ah: 0000b : bit 0= plane 0, bit 1=plane 1, etc..
  434.     ;
  435.     ;DESTROYS: al, dx
  436.     ;
  437. MACRO  @Set_Write_Plane
  438.     mov     dx,SC_Index
  439.     mov     al,2
  440.     and     ah,1111b
  441.     out     dx,ax
  442. ENDM   @Set_Write_Plane
  443.  
  444.     ;ah: plane to latch for read (0-3)
  445.     ;
  446.     ;DESTROYS: al, dx
  447.     ;
  448. MACRO  @Set_Read_Plane
  449.     mov     dx,Graph_Index
  450.     mov     al,4
  451.     out     dx,ax
  452. ENDM   @Set_Read_Plane
  453.  
  454.     ;ah: write mode (0-3)
  455.     ;
  456.     ;DESTROYS: ax, dx
  457.     ;
  458. MACRO @Set_Write_Mode
  459.     mov     dx,Graph_Index
  460.     mov     al,5
  461.     out     dx,al
  462.     inc     dx
  463.     in      al,dx
  464.     and     al,11111100b    ;clear out write mode bits
  465.     and     ah,00000011b
  466.     or      al,ah
  467.     out     dx,al
  468. ENDM  @Set_Write_Mode
  469.  
  470.     ;ah: Read mode (0-1)
  471.     ;
  472.     ;DESTROYS: ax, dx
  473.     ;
  474. MACRO @Set_Read_Mode
  475.     mov     dx,Graph_Index
  476.     mov     al,5
  477.     out     dx,al
  478.     inc     dx
  479.     in      al,dx
  480.     and     al,11110111b    ;clear out write mode bits
  481.     shl     ah,3            ;move bit to correct position
  482.     and     ah,00001000b
  483.     or      al,ah
  484.     out     dx,al
  485. ENDM  @Set_Read_Mode
  486.  
  487.     ;bx: starting offset
  488.     ;
  489.     ;DESTROYS: ax, dx
  490.     ;
  491. MACRO @Set_Start_Offset
  492.     mov     dx,CRTC_Index
  493.     mov     al,0ch
  494.     mov     ah,bh       ;write the HIGH byte
  495.     out     dx,ax
  496.     inc     al
  497.     mov     ah,bl       ;write the LOW byte
  498.     out     dx,ax
  499. ENDM  @Set_Start_Offset
  500.  
  501.     ;ah = pelpan value
  502.     ;
  503.     ;DESTROYS: ax, dx
  504.     ;
  505. MACRO @Set_HPP
  506.     mov     dx,InputStatus1
  507.     in      al,dx           ;dummy input
  508.     mov     dx,Attr_Index
  509.     mov     al,33h
  510.     out     dx,al
  511.     mov     al,ah
  512.     out     dx,al
  513. ENDM
  514.     
  515.     ;DESTROYS: ax, dx   - sets pixel pan compatibility
  516.     ;
  517. MACRO @Set_PPC
  518.     mov     dx,InputStatus1
  519.     in      al,dx           ;dummy input
  520.     mov     dx,Attr_Index
  521.     mov     al,30h
  522.     out     dx,al
  523.     inc     dx
  524.     in      al,dx
  525.     dec     dx
  526.     or      al,00100000b
  527.     out     dx,al
  528. ENDM
  529.  
  530.     ;bx: scanline to set split screen at
  531.     ;
  532.     ;DESTROYS: ax, dx
  533.     ;
  534. MACRO @Set_Split
  535.     mov     al,18h
  536.     mov     ah,bl
  537.     mov     dx,CRTC_Index
  538.     out     dx,ax       ;set bits 0-7
  539.  
  540.     mov     al,09h
  541.     out     dx,al
  542.     inc     dx
  543.     in      al,dx
  544.     mov     ah,bh
  545.     and     ah,00000010b
  546.     shl     ah,5
  547.     and     al,10111111b
  548.     or      al,ah
  549.     out     dx,al       ;set bit 9
  550.  
  551.     dec     dx
  552.     mov     al,07h
  553.     out     dx,al
  554.     inc     dx
  555.     in      al,dx
  556.     and     al,11101111b
  557.     mov     ah,bh
  558.     and     ah,00000001b
  559.     shl     ah,4
  560.     or      al,ah
  561.     out     dx,al       ;set bit 8
  562. ENDM @Set_SPlit
  563.  
  564. MACRO @FullVertWait
  565.  LOCAL @@Vr, @@Nvr
  566.     mov     dx,InputStatus1
  567. @@Vr:
  568.     in      al,dx
  569.     test    al,8
  570.     jz      @@Vr                    ;wait until Verticle Retrace starts
  571. @@Nvr:
  572.     in      al,dx
  573.     test    al,8
  574.     jnz     @@Nvr                   ;wait until Verticle Retrace Ends
  575. ENDM @FullVertWait
  576.  
  577. MACRO @WaitVert
  578.  LOCAL @@Vr
  579.     mov     dx,InputStatus1
  580. @@VR:
  581.     in      al,dx
  582.     test    al,8
  583.     jz      @@VR                    ;wait until Verticle Retrace starts
  584. ENDM  @WaitVert
  585.  
  586. MACRO @WaitVertEnd
  587.   LOCAL @@NVr
  588.     mov     dx,InputStatus1
  589. @@NVR:
  590.     in      al,dx
  591.     test    al,8
  592.     jnz     @@NVR                   ;wait until Verticle Retrace Ends
  593. ENDM  @WaitVertEnd
  594.     
  595.     ;si = offset to palette
  596.     ;cx = number of colors to write
  597.     ;al = starting palette register
  598.     ;
  599.     ;DESTROYS: dx,si,cx
  600.     ;
  601. MACRO @WritePalette
  602.     mov     dx,cx
  603.     add     cx,cx
  604.     add     cx,dx
  605.     mov     dx,03c8h
  606.     out     dx,al
  607.     inc     dx
  608.     cld
  609.     rep outsb
  610. ENDM @WritePalette
  611.  
  612.     ;Changes the mode back to ModeX after a ResetLinear was called
  613. MACRO @ResetModeX
  614.     mov     dx,SC_INDEX
  615.     mov     ax,0604h
  616.     out     dx,ax               ; disable chain4 mode
  617.     
  618.     mov     dx,CRTC_INDEX
  619.     mov     ax,00014h           ; turn off dword mode
  620.     out     dx,ax
  621.     mov     ax,0e317h           ; turn on byte mode
  622.     out     dx,ax
  623. ENDM
  624.  
  625.     ;changes from ModeX to normal linear mode
  626.     ; only will work with an 320x200 screen w/ screenwidth of 80 bytes
  627. MACRO @ResetLinear
  628.     mov     dx,SC_INDEX
  629.     mov     ax,0E04h
  630.     out     dx,ax               ; enable chain4 mode
  631.  
  632.     mov     dx,CRTC_INDEX       ; reprogram the CRT Controller
  633.     mov     ax,04014h           ; turn on dword mode
  634.     out     dx,ax
  635.     mov     ax,0a317h           ; turn off byte mode
  636.     out     dx,ax
  637. ENDM
  638.