; > NewModes.PSSrc
; 08-Nov-89

        GET     &.Hdr.ListOpts
        GET     &.Hdr.Macros
        GET     &.Hdr.System
        GET     &.Hdr.NewSpace
        GET     &.Hdr.ModHand
        GET     &.Hdr.Services
        GET     &.Hdr.Proc
        GET     &.Hdr.File
        GET     &.Hdr.NewErrors
        GET     &.Hdr.VduExt
        GET     &.Hdr.Debug
        GET     &.Hdr.CMOS

        LEADR   Module_LoadAddr

        GBLL    Debug
Debug   SETL    {FALSE}

        GBLL    Module
Module  SETL    {TRUE}         ; Really !

TAB     *       9
LF      *       10
FF      *       12
CR      *       13

MonitorType_Normal * 0
MonitorType_MultiSync * 1
MonitorType_HiResMono * 2
MonitorType_VGA * 3
MonitorType_DontCare * -1

Normal          *       1 :SHL: MonitorType_Normal
MultiSync       *       1 :SHL: MonitorType_MultiSync
HiResMono       *       1 :SHL: MonitorType_HiResMono
VGA             *       1 :SHL: MonitorType_VGA

ScreenEndAdr    *       &02000000
Vinit           *       &03600000
Interlace       *       &40

        MACRO
        NewMode $modeno, $monitors, $vidclist, $wslist
        &       $modeno
        &       $monitors
99
        &       ($vidclist)-%BT99
        &       ($wslist)-%BT99
        MEND

; Module workspace allocation

        ^ 0, R12

ModeExt_WorkspaceSize * :INDEX: @

; **************** Module code starts here **********************

Module_BaseAddr

        DCD     0
        DCD     ModeExt_Init    -Module_BaseAddr
        DCD     ModeExt_Die     -Module_BaseAddr
        DCD     ModeExt_Service -Module_BaseAddr
        DCD     ModeExt_Title   -Module_BaseAddr
        DCD     ModeExt_HelpStr -Module_BaseAddr
        DCD     ModeExt_HC_Table-Module_BaseAddr

ModeExt_Title
        =       "NewModes", 0

ModeExt_HelpStr
        =       "NewModes"
        =       TAB
        =       "1.3 (08 Nov 1989) test Multisync Modes", 0
        ALIGN

; *****************************************************************************

ModeExt_HC_Table * Module_BaseAddr

; *****************************************************************************
;
;       ModeExt_Init - Initialisation entry point
;

ModeExt_Init ENTRY

        MOV     R0, #EventV
        ADRL    R1, EventRoutine
        MOV     R2, R12
        SWI     XOS_Claim
        MOVVC   R0, #14
        MOVVC   R1, #Event_VSync
        SWIVC   XOS_Byte
        EXIT

; *****************************************************************************
;
;       ModeExt_Die - Die entry
;

ModeExt_Die ENTRY

        MOV     R0, #13
        MOV     R1, #Event_VSync
        SWI     XOS_Byte
        MOV     R0, #EventV
        ADRL    R1, EventRoutine
        MOV     R2, R12
        SWI     XOS_Release
        EXITS

; *****************************************************************************
;
;       ModeExt_Service - Main entry point for services
;
; in:   R1 = service reason code
;

ModeExt_Service ENTRY
        TEQ     R1, #Service_ModeExtension
        TEQNE   R1, #Service_PreModeChange
        TEQNE   R1, #Service_ModeChange
        TEQNE   R1, #Service_Reset
        TEQNE   R1, #Service_ModeTranslation
        EXIT    NE

        TEQ     R1, #Service_PreModeChange
        MOVEQ   R14, #0                 ; zero the word
        STREQ   R14, [R12]
        EXIT    EQ

        TEQ     R1, #Service_ModeChange
        BEQ     ModeChangeService

        TEQ     R1, #Service_Reset
        BEQ     ResetCode

        TEQ     R1, #Service_ModeTranslation
        BEQ     ModeTranslation

        [ Debug
        DREG    R2, "Mode = "
        DREG    R3, "Monitor type = "
        ]

        Push    "R5-R8"

        ADR     R5, NewModesList-8
        MOV     R8, #1
10
        ADD     R5, R5, #8              ; skip VidC, WS
        LDMIA   R5!, {R6, R7}           ; R6 = mode, R7 = OK monitor types
        CMP     R6, #-1
        Pull    "R5-R8, PC", EQ         ; mode not in list, exit
        TEQ     R2, R6                  ; if not this mode
        BNE     %BT10                   ; then loop
        CMP     R3, #MonitorType_DontCare ; if any monitor type
        BEQ     %FT20                   ; then found one
        TST     R7, R8, LSL R3          ; else if not appropriate monitor
        BEQ     %BT10                   ; then loop
20
        LDMIA   R5, {R3, R4}            ; load offsets to VidCList, WSList
        ADD     R3, R3, R5              ; convert to addresses
        ADD     R4, R4, R5              ; convert to addresses
        MOV     R1, #0                  ; claim service
        Pull    "R5-R8, PC"

; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

NewModesList

        NewMode  0,  MultiSync, Multi100VIDCList, Multi100WSList           ; rshifted Mode 0
        NewMode  1,  MultiSync, Multi101VIDCList, Multi101WSList           ; rshifted Mode 1
        NewMode  2,  MultiSync, Multi102VIDCList, Multi102WSList           ; rshifted Mode 2
        NewMode  3,  MultiSync, Multi103VIDCList, Multi103WSList           ; rshifted Mode 3
        NewMode  4,  MultiSync, Multi104VIDCList, Multi104WSList           ; rshifted Mode 4
        NewMode  5,  MultiSync, Multi105VIDCList, Multi105WSList           ; rshifted Mode 5
        NewMode  6,  MultiSync, Multi106VIDCList, Multi106WSList           ; rshifted Mode 6
        NewMode  7,  MultiSync, Multi107VIDCList, Multi107WSList           ; rshifted Mode 7
        NewMode  8,  MultiSync, Multi108VIDCList, Multi108WSList           ; rshifted Mode 8
        NewMode  9,  MultiSync, Multi109VIDCList, Multi109WSList           ; rshifted Mode 9
        NewMode 10,  MultiSync, Multi110VIDCList, Multi110WSList           ; rshifted Mode 10
        NewMode 11,  MultiSync, Multi111VIDCList, Multi111WSList           ; rshifted Mode 11
        NewMode 12,  MultiSync, Multi112VIDCList, Multi112WSList           ; rshifted Mode 12
        NewMode 13,  MultiSync, Multi113VIDCList, Multi113WSList           ; rshifted Mode 13
        NewMode 14,  MultiSync, Multi114VIDCList, Multi114WSList           ; rshifted Mode 14
        NewMode 15,  MultiSync, Multi115VIDCList, Multi115WSList           ; rshifted Mode 15
        NewMode 16,  MultiSync, Multi116VIDCList, Multi116WSList           ; rshifted Mode 16
        NewMode 17,  MultiSync, Multi117VIDCList, Multi117WSList           ; rshifted Mode 17
        NewMode 18,  MultiSync, Multi118VIDCList, Multi118WSList           ; rshifted Mode 18
        NewMode 19,  MultiSync, Multi119VIDCList, Multi119WSList           ; rshifted Mode 19
        NewMode 20,  MultiSync, Multi120VIDCList, Multi120WSList           ; rshifted Mode 20
        NewMode 21,  MultiSync, Multi121VIDCList, Multi121WSList           ; rshifted Mode 21

        NewMode 24,  MultiSync, Multi124VIDCList, Multi124WSList           ; rshifted Mode 24

        NewMode 25,  VGA :OR: MultiSync, VGA1VIDCList, VGA1WSList2         ; VGA 1bp 640x480
        NewMode 26,  VGA :OR: MultiSync, VGA2VIDCList, VGA2WSList2         ; VGA 2bp 640x480
        NewMode 27,  VGA :OR: MultiSync, VGA4VIDCList, VGA4WSList2         ; VGA 4bp 640x480
        NewMode 28,  VGA :OR: MultiSync, VGA8VIDCList, VGA8WSList2         ; VGA 8bp 640x480

        NewMode 31, MultiSync, sVGA4_VIDCList, sVGA4_WSList                ; super VGA 4bp 800x600 
        NewMode 32, MultiSync, sVGA8_VIDCList, sVGA8_WSList                ; super VGA 8bp 800x600

        NewMode 33, Normal :OR: MultiSync, Mode33VIDCList, Mode33WSList    ; overscan 768x288 
        NewMode 34, Normal :OR: MultiSync, Mode34VIDCList, Mode34WSList    ; overscan 832x288

;        NewMode 45, VGA :OR: MultiSync, VGA11VIDCList, VGA11WSList2        ; VGA 1bp 640x350
;        NewMode 46, VGA :OR: MultiSync, VGA12VIDCList, VGA12WSList2        ; VGA 2bp 640x350
;        NewMode 47, VGA :OR: MultiSync, VGA14VIDCList, VGA14WSList2        ; VGA 4bp 640x350
;        NewMode 48, VGA :OR: MultiSync, VGA18VIDCList, VGA18WSList2        ; VGA 8bp 640x350

;        NewMode 55, VGA :OR: MultiSync, VGA21VIDCList, VGA21WSList2        ; VGA 1bp 720x400
;        NewMode 56, VGA :OR: MultiSync, VGA22VIDCList, VGA22WSList2        ; VGA 2bp 720x400
;        NewMode 57, VGA :OR: MultiSync, VGA24VIDCList, VGA24WSList2        ; VGA 4bp 720x400
;        NewMode 58, VGA :OR: MultiSync, VGA28VIDCList, VGA28WSList2        ; VGA 8bp 720x400

;        NewMode 60, MultiSync, Multi350VIDCList, Multi350WSList            ; MDA 640x350
;        NewMode 61, MultiSync, Multi200VIDCList, Multi200WSList            ; CGA 640x200
;        NewMode 62, MultiSync, Multi351VIDCList, Multi351WSList            ; EGA 640x350

;        NewMode 66, MultiSync, Multi66VIDCList, Multi66WSList             ; DTP 960x384 4bpp
;        NewMode 67, MultiSync, Multi67VIDCList, Multi67WSList             ; DTP 960x384 8bpp

;        NewMode 76, MultiSync, Multi76VIDCList, Multi76WSList             ; DTP 1280x384 4bpp
;        NewMode 77, MultiSync, Multi77VIDCList, Multi77WSList             ; DTP 1280x384 8bpp

        &       -1, 0

; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; general purpose mode macros

ClockShift * 9
SyncShift * 11

; pixel rate specifiers

CRPix_24000 * 3 :OR: (0 :SHL: ClockShift)
CRPix_16000 * 2 :OR: (0 :SHL: ClockShift)
CRPix_12000 * 1 :OR: (0 :SHL: ClockShift)
CRPix_8000  * 0 :OR: (0 :SHL: ClockShift)
CRPix_25175 * 3 :OR: (1 :SHL: ClockShift)
CRPix_36000 * 3 :OR: (2 :SHL: ClockShift)

        MACRO
        VIDC_List $bpp,$hsync,$hbpch,$hlbdr,$hdisp,$hrbdr,$hfpch, $vsync,$vbpch,$vlbdr,$vdisp,$vrbdr,$vfpch,$pixrate,$sp
        LCLA    sub
        LCLA    lbpp
        LCLA    syncpol
 [ $bpp = 8
sub     SETA    5
lbpp    SETA    3
 ]
 [ $bpp = 4
sub     SETA    7
lbpp    SETA    2
 ]
 [ $bpp = 2
sub     SETA    11
lbpp    SETA    1
 ]
 [ $bpp = 1
sub     SETA    19
lbpp    SETA    0
 ]
 [ "$sp"="" :LOR: "$sp"="0"
syncpol SETA    0 :SHL: SyncShift               ; normal sync polarity
 |
  [ "$sp"="1"
syncpol SETA    3 :SHL: SyncShift               ; inverted H and V sync
  |
        ! 1,"Sync polarity must be null string or 0 (for normal syncs) or 1 (for inverted H and V syncs)"
  ]
 ]
        ASSERT  ($hsync :AND: 1)=0
        ASSERT  ($hbpch :AND: 1)=1
        ASSERT  ($hlbdr :AND: 1)=0
        ASSERT  ($hdisp :AND: 1)=0
        ASSERT  ($hrbdr :AND: 1)=0
        ASSERT  ($hfpch :AND: 1)=1
; Horizontal
        &       (&80:SHL:24) :OR: ((($hsync+$hbpch+$hlbdr+$hdisp+$hrbdr+$hfpch -2  )/2) :SHL: 14) ; HCR
        &       (&84:SHL:24) :OR: ((($hsync                                    -2  )/2) :SHL: 14) ; HSWR
        &       (&88:SHL:24) :OR: ((($hsync+$hbpch                             -1  )/2) :SHL: 14) ; HBSR
        &       (&8C:SHL:24) :OR: ((($hsync+$hbpch+$hlbdr                      -sub)/2) :SHL: 14) ; HDSR
        &       (&90:SHL:24) :OR: ((($hsync+$hbpch+$hlbdr+$hdisp               -sub)/2) :SHL: 14) ; HDER
        &       (&94:SHL:24) :OR: ((($hsync+$hbpch+$hlbdr+$hdisp+$hrbdr        -1  )/2) :SHL: 14) ; HBER
; Vertical
        &       (&A0:SHL:24) :OR: (($vsync+$vbpch+$vlbdr+$vdisp+$vrbdr+$vfpch    -1)    :SHL: 14) ; VCR
        &       (&A4:SHL:24) :OR: (($vsync                                       -1)    :SHL: 14) ; VSWR
        &       (&A8:SHL:24) :OR: (($vsync+$vbpch                                -1)    :SHL: 14) ; VBSR
        &       (&AC:SHL:24) :OR: (($vsync+$vbpch+$vlbdr                         -1)    :SHL: 14) ; VDSR
        &       (&B0:SHL:24) :OR: (($vsync+$vbpch+$vlbdr+$vdisp                  -1)    :SHL: 14) ; VDER
        &       (&B4:SHL:24) :OR: (($vsync+$vbpch+$vlbdr+$vdisp+$vrbdr           -1)    :SHL: 14) ; VBER
; Control Register
        &       (&E0:SHL:24) :OR: (CRPix_$pixrate) :OR: (lbpp :SHL: 2) :OR: syncpol
        MEND

        MACRO
        VIDC_WS  $bpp,$hpix,$vpix,$multx,$multy, $dht

        &       VduExt_XWindLimit, $hpix-1
        &       VduExt_ScrRCol, ($hpix/8)-1
        &       VduExt_LineLength, $hpix*$bpp/8
 [ "$dht" <> ""
        &       VduExt_ModeFlags, ModeFlag_DoubleVertical
        &       VduExt_ScrBRow, ($vpix/16)-1
 |
        &       VduExt_ScrBRow, ($vpix/8)-1
 ]
        &       VduExt_YWindLimit, $vpix-1
        &       VduExt_ScreenSize, $hpix*$vpix*$bpp/8

        &       VduExt_XEigFactor, $multx
        &       VduExt_YEigFactor, $multy
        MEND

; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

;  Start of multi sync archy modes

; Mode 0, multiscan mode 0
Multi100VIDCList
        &         0
        &         0
        VIDC_List 1,72,63,88,640,88,73, 3,16,17,256,17,3,16000
        &        -1
Multi100WSList
        &         0
        &         0
        &        -1

; Mode 1, multiscan mode 1
Multi101VIDCList
        &         0
        &         1
        VIDC_List 2,36,33,44,320,44,35, 3,16,17,256,17,3,8000
        &        -1
Multi101WSList
        &         0
        &         1
        &        -1

; Mode 2, multiscan mode 2
Multi102VIDCList
        &         0
        &         2
        VIDC_List 4,36,33,44,320,44,35, 3,16,17,256,17,3,8000
        &        -1
Multi102WSList
        &         0
        &         2
        &        -1

; Mode 3, multiscan mode 3
Multi103VIDCList
        &         0
        &         3
        VIDC_List 2,72,63,88,640,88,73, 3,16,20,250,20,3,16000
        &        -1
Multi103WSList
        &         0
        &         3
        &        -1

; Mode 4, multiscan mode 4
Multi104VIDCList
        &         0
        &         4
        VIDC_List 1,72,63,88,640,88,73, 3,16,17,256,17,3,16000
        &        -1
Multi104WSList
        &         0
        &         4
        &        -1

; Mode 5, multiscan mode 5
Multi105VIDCList
        &         0
        &         5
        VIDC_List 2,36,51,24,320,24,57, 3,16,17,256,17,3,8000
        &        -1
Multi105WSList
        &         0
        &         5
        &        -1

; Mode 6, multiscan mode 6
Multi106VIDCList
        &         0
        &         6
        VIDC_List 2,36,33,44,320,44,35, 3,16,20,250,20,3,8000
        &        -1
Multi106WSList
        &         0
        &         6
        &        -1

; Mode 7, multiscan mode 7
Multi107VIDCList
        &         0
        &         7
        VIDC_List 4,36,31,44,320,44,37, 3,18,22,250,16,3,8000
        &        -1
Multi107WSList
        &         0
        &         7
        &        -1

; Mode 8, multiscan mode 8
Multi108VIDCList
        &         0
        &         8
        VIDC_List 2,72,63,88,640,88,73, 3,16,17,256,17,3,16000
        &        -1
Multi108WSList
        &         0
        &         8
        &        -1

; Mode 9, multiscan mode 9
Multi109VIDCList
        &         0
        &         9
        VIDC_List 4,36,33,44,320,44,35, 3,16,17,256,17,3,8000
        &        -1
Multi109WSList
        &         0
        &         9
        &        -1

; Mode 10, multiscan mode 10
Multi110VIDCList
        &         0
        &         10
        VIDC_List 8,36,33,44,320,44,35, 3,16,17,256,17,3,8000
        &        -1
Multi110WSList
        &         0
        &         10
        &        -1

; Mode 11, multiscan mode 11
Multi111VIDCList
        &         0
        &         11
        VIDC_List 2,72,63,88,640,88,73, 3,16,20,250,20,3,16000
        &        -1
Multi111WSList
        &         0
        &         11
        &        -1

; Mode 12, multiscan mode 12
Multi112VIDCList
        &         0
        &         12
        VIDC_List 4,72,63,88,640,88,73, 3,16,17,256,17,3,16000
        &        -1
Multi112WSList
        &         0
        &         12
        &        -1

; Mode 13, multiscan mode 13
Multi113VIDCList
        &         0
        &         13
        VIDC_List 8,36,33,44,320,44,35, 3,16,17,256,17,3,8000
        &        -1
Multi113WSList
        &         0
        &         13
        &        -1

; Mode 14, multiscan mode 14
Multi114VIDCList
        &         0
        &         14
        VIDC_List 4,72,63,88,640,88,73, 3,16,20,250,20,3,16000
        &        -1
Multi114WSList
        &         0
        &         14
        &        -1

; Mode 15, multiscan mode 15
Multi115VIDCList
        &         0
        &         15
        VIDC_List 8,72,63,88,640,88,73, 3,16,17,256,17,3,16000
        &        -1
Multi115WSList
        &         0
        &         15
        &        -1

; Mode 16, multiscan mode 16
Multi116VIDCList
        &         0
        &         16
        VIDC_List 4,112,47,132,1056,132,57, 3,16,17,256,17,3,24000
;
; tv blanking!      112,139, 76,1056,114, 39,   ,3,18,16,256,16,3
;                  4u67,5u79,3u2,44u,4u7,1u62,  21r           3r
;         should be  =10u4              =1u65   22r           3r(2r5) 
;philips needs bprch > 57 or goes dark (sync at 112)
; can inc sync to 10u0, more and screen starts to wobble
        &        -1
Multi116WSList
        &         0
        &         16
        &        -1

; Mode 17, multiscan mode 17
Multi117VIDCList
        &         0
        &         17
        VIDC_List 4,112,47,132,1056,132,57, 3,16,20,250,20,3,24000
        &        -1
Multi117WSList
        &         0
        &         17
        &        -1

; Mode 18, multiscan mode 18
Multi118VIDCList
        &         0
        &         18
        VIDC_List 1,56,111,2,640,2,85, 3,17,1,512,1,0,24000
        &        -1
Multi118WSList
        &         0
        &         18
        &        -1

; Mode 19, multiscan mode 19
Multi119VIDCList
        &         0
        &         19
        VIDC_List 2,56,111,2,640,2,85, 3,17,1,512,1,0,24000
        &        -1
Multi119WSList
        &         0
        &         19
        &        -1

; Mode 20, multiscan mode 20
Multi120VIDCList
        &         0
        &         20
        VIDC_List 4,56,111,2,640,2,85, 3,17,1,512,1,0,24000
        &        -1
Multi120WSList
        &         0
        &         20
        &        -1

; Mode 21, multiscan mode 21
Multi121VIDCList
        &         0
        &         21
        VIDC_List 8,56,111,2,640,2,85, 3,17,1,512,1,0,24000
        &        -1
Multi121WSList
        &         0
        &         21
        &        -1

; Mode 24, multiscan mode 24
Multi124VIDCList
        &         0
        &         24
        VIDC_List 8,112,47,132,1056,132,57, 3,16,17,256,17,3,24000
        &        -1
Multi124WSList
        &         0
        &         24
        &        -1


; MODE 25 (VGA or multisync monitors, 640x480)
VGA1VIDCList
        &         0
        &         18
        VIDC_List 1,96,47,0,640,0,15, 2,32,0,480,0,11,25175,1
        &        -1
VGA1WSList2
        &         0
        &         18
        &        -1

; MODE 26 (VGA or multisync monitors, 640x480)
VGA2VIDCList
        &         0
        &         19
        VIDC_List 2,96,47,0,640,0,15, 2,32,0,480,0,11,25175,1
        &        -1
VGA2WSList2
        &         0
        &         19
        &        -1

; MODE 27 (VGA or multisync monitors,  640x480)
VGA4VIDCList
        &         0
        &         20
        VIDC_List 4,96,47,0,640,0,15, 2,32,0,480,0,11,25175,1
        &        -1
VGA4WSList2
        &         0
        &         20
        &        -1

; MODE 28 (VGA or multisync monitors,  640x480)
VGA8VIDCList
        &         0
        &         21
        VIDC_List 8,96,47,0,640,0,15, 2,32,0,480,0,11,25175,1
        &        -1
VGA8WSList2
        &         0
        &         21
        &        -1

; MODE 31 (800x600 by 4 bits per pixel)
sVGA4_VIDCList
        &         0
        &         20
        VIDC_List 4,72,129,0,800,0,23, 2,22,0,600,0,1,36000
        &         &E000042B
        &        -1
sVGA4_WSList
        &       0
        &       20
        VIDC_WS 4,800,600,1,1
        &      -1

; MODE 32 (800x600 by 8 bits per pixel)
sVGA8_VIDCList
        &         0
        &         24
        VIDC_List 8,72,129,0,800,0,23, 2,22,0,600,0,1,36000
        &         &E000040F
        &        -1
sVGA8_WSList
        &       0
        &       24
        VIDC_WS 8,800,600,1,1
        &      -1

; MODE 33 (768x288 by 8 bits per pixel)
Mode33VIDCList

        &         0
        &         15
        VIDC_List 8,74,127,0,768,0,55, 3,18,0,288,0,3,16000
        &        -1
Mode33WSList
        &         0
        &         15
        VIDC_WS 8,768,288,1,2
        &        -1

; MODE 34 (832x288 by 8 bits per pixel)
Mode34VIDCList
        &         0
        &         15
        VIDC_List 8,74,87,0,832,0,31, 3,18,0,288,0,3,16000
        &        -1
Mode34WSList
        &        0
        &        15
        VIDC_WS  8,832,288,1,2
        &       -1

;; MODE 45 (VGA or multisync monitors, 640x350)
;VGA11VIDCList
;        &         0
;        &         18
;        VIDC_List 1,96,47,0,640,0,15, 2,59,0,350,0,38
;        &        -1
;VGA11WSList2
;        &        0
;        &        18
;        VIDC_WS  1,640,350,1,2
;        &       -1

;; MODE 46 (VGA or multisync monitors, 640x350)
;VGA12VIDCList
;        &         0
;        &         19
;        VIDC_List 2,96,47,0,640,0,15, 2,59,0,350,0,38
;        &        -1
;VGA12WSList2
;        &        0
;        &        19
;        VIDC_WS  2,640,350,1,2
;        &       -1

;; MODE 47 (VGA or multisync monitors, 640x350)
;VGA14VIDCList
;        &         0
;        &         20
;        VIDC_List 4,96,47,0,640,0,15, 2,59,0,350,0,38
;        &        -1
;VGA14WSList2
;        &        0
;        &        20
;        VIDC_WS  4,640,350,1,2
;        &       -1

;; MODE 48 (VGA or multisync monitors, 640x350)
;VGA18VIDCList
;        &         0
;        &         21
;        VIDC_List 8,96,47,0,640,0,15, 2,59,0,350,0,38
;        &         &E000020F
;        &        -1
;VGA18WSList2
;        &        0
;        &        21
;        VIDC_WS  8,640,350,1,2
;        &       -1

;; MODE 55 (VGA or multisync monitors, 720x400)
;VGA21VIDCList
;        &         0
;        &         18
;        VIDC_List 1,108,55,0,720,0,17, 2,34,0,400,0,13
;        &        -1
;VGA21WSList2
;        &        0
;        &        18
;        VIDC_WS  1,720,400,1,2
;        &       -1

;; MODE 56 (VGA or multisync monitors, 720x400)
;VGA22VIDCList
;        &       0
;        &       19
;        VIDC_List 2,108,55,0,720,0,17, 2,34,0,400,0,13
;        &       -1
;VGA22WSList2
;        &        0
;        &        19
;        VIDC_WS  2,720,400,1,2
;        &       -1

;; MODE 57 (VGA or multisync monitors, 720x400)
;VGA24VIDCList
;        &         0
;        &         20
;        VIDC_List 4,108,55,0,720,0,17, 2,34,0,400,0,13
;        &        -1
;VGA24WSList2
;        &        0
;        &        20
;        VIDC_WS  4,720,400,1,2
;        &       -1

;; MODE 58 (VGA or multisync monitors, 720x400)
;VGA28VIDCList
;        &         0
;        &         21
;        VIDC_List 8,108,55,0,720,0,17, 2,34,0,400,0,13
;        &         &E000020F
;        &        -1
;VGA28WSList2
;        &        0
;        &        21
;        VIDC_WS  8,720,400,1,2
;        &       -1

;; IBM standard form modes

;; Mode 60 MDA, multiscan
;Multi350VIDCList
;        &         0
;        &         12
;        VIDC_List 4,132,17,2,704,2,9, 17,4,0,350,0,0
;        &        -1
;Multi350WSList
;        &         0
;        &         12
;        VIDC_WS   4,704,350,1,2
;        &        -1

;; Mode 61 CGA, multiscan
;Multi200VIDCList
;        &         0
;        &         12
;        VIDC_List 4,68,115,0,720,0,105, 3,34,0,200,0,25
;        &        -1
;Multi200WSList
;        &         0
;        &         12
;        VIDC_WS   4,720,200,1,2
;        &        -1

;; Mode 62 EGA, multiscan
;Multi351VIDCList
;        &         0
;        &         12
;        VIDC_List 4,78,25,0,624,0,1, 13,2,0,350,0,1
;        &        -1
;Multi351WSList
;        &         0
;        &         12
;        VIDC_WS   4,624,350,1,2
;        &        -1


;; Mode 66 , DTP multiscan  960x384 4bpp
;Multi66VIDCList
;        &         0
;        &         20
;        VIDC_List 4,72,101,0,960,0,39, 3,18,0,384,0,2
;        &        -1
;Multi66WSList
;        &         0
;        &         20
;        VIDC_WS   4,960,384,1,2
;        &        -1

;; Mode 67 , DTP multiscan 960x384 8bpp
;Multi67VIDCList
;        &         0
;        &         21
;        VIDC_List 8,72,101,0,960,0,39, 3,18,0,384,0,2
;        &        -1
;Multi67WSList
;        &         0
;        &         21
;        VIDC_WS   8,960,384,1,2
;        &        -1

;; Mode 76 , DTP multiscan  1280x296 4bpp
;Multi76VIDCList
;        &         0
;        &         16
;        VIDC_List 4,48,111,0,1280,0,53, 3,14,0,296,0,4
;        &        -1
;Multi76WSList
;        &         0
;        &         16
;        VIDC_WS   4,1280,296,1,2
;        &        -1

;; Mode 77 , DTP multiscan 1280x296 8bpp
;Multi77VIDCList
;        &         0
;        &         24
;        VIDC_List 8,48,111,0,1280,0,53, 3,14,0,296,0,4
;        &        -1
;Multi77WSList
;        &         0
;        &         24
;        VIDC_WS   8,1280,296,1,2
;        &        -1

    [ Debug
    InsertDebugRoutines
    ]

; *****************************************************************************
;
;       Code to execute on reset
;
; in:   R14 already stacked
;

ResetCode ROUT
        Push    "R0-R6"
        BL      ModeExt_Init
        Pull    "R0-R6,PC"

; *****************************************************************************
;
;       EventRoutine - Routine called on Vsync
;

EventRoutine ROUT
        TEQ     R0, #Event_VSync
        MOVNE   PC, R14
        ENTRY   "R0-R6"
        LDR     R1, [R12]               ; load state flag, 0 => disabled
        RSBS    R1, R1, #0              ; change sign
        EXIT    EQ                      ; if zero then do nowt

        STR     R1, [R12]               ; store back
        VDWS    WsPtr
        LDR     R2, [WsPtr, #TotalScreenSize] ; needed later as well
        ADDMI   R1, R1, R2              ; if -ve then add TotalScreenSize

        STR     R1, [WsPtr, #TeletextOffset]

; now set VInit to this

        LDR     R0, [WsPtr, #DisplayStart]
        SUB     R0, R0, #ScreenEndAdr
        ADD     R0, R0, R2                      ; make start of screen 0
        ADD     R0, R0, R1                      ; add on teletext bank offset
        CMP     R0, R2                          ; if out of range
        SUBCS   R0, R0, R2                      ; then subtract total size
SetVinitPhys
        MOV     R1, #Vinit
        STR     R0, [WsPtr, #VinitCopy]
        MOV     R0, R0, LSR #4                  ; bottom 4 bits not valid
        ORR     R0, R1, R0, LSL #2              ; OR in at correct place
        STR     R0, [R0]                        ; any old data will do

        LDR     R0, [WsPtr, #VIDCControlCopy]
        ORR     R0, R0, #Interlace              ; turn interlace on
        STR     R0, [WsPtr, #VIDCControlCopy]
        MOV     R1, #VIDC
        STR     R0, [R1]

        EXIT

; *****************************************************************************

ModeChangeService
        Push    "R0-R6"
        MOV     R5, R12                 ; our workspace pointer
        VDWS    WsPtr
        MOV     R6, #0
        LDR     R0, [WsPtr, #DisplayModeNo]
        TEQ     R0, #18
        TEQNE   R0, #19
        TEQNE   R0, #20
        TEQNE   R0, #21
        TEQNE   R0, #26
        TEQNE   R0, #27
        BNE     %FT10
        MOV     R0, #&A1
        MOV     R1, #VduCMOS
        SWI     XOS_Byte
        ANDS    R2, R2, #MonitorTypeBits
        BNE     %FT10

        MOV     R0, #255
        STR     R0, [WsPtr, #DisplayYWindLimit]
        LDR     R0, [WsPtr, #YEigFactor]
        ADD     R0, R0, #1
        STR     R0, [WsPtr, #DisplayYEigFactor]
        LDR     R0, =541-6
        STR     R0, [WsPtr, #CursorFudgeFactor]

        LDR     R6, [WsPtr, #LineLength]
        MOV     R6, R6, LSR #1
        RSB     R6, R6, #0
10
        STR     R6, [R5]
        Pull    "R0-R6, PC"

; *****************************************************************************
;
;       ModeTranslation - Code to perform VGA mode number translation
;
; in:   R1 = Service_ModeTranslation
;       R2 = mode number
;       R3 = monitor type
;       return address stacked
;
; out:  R1 = 0 if claimed
;       R2 = substitute
;       R3 preserved

ModeTranslation ROUT
        TEQ     R3, #MonitorType_VGA
        Pull    PC, NE
        BIC     R1, R2, #&80    ; get rid of shadow bit
        CMP     R1, #32         ; if in range 32..39
        RSBCSS  R1, R1, #39
        BCS     %FT10           ; then don't modify

        [ {TRUE}
        MOV     R2, #0
        |
        Push    R0
        MOV     R0, R2
        MOV     R1, #9          ; log2bpp
        SWI     XOS_ReadModeVariable
        Pull    R0
        MOVVS   R2, #0          ; if error or invalid then use mode 32
        MOVCS   R2, #0
        CMP     R2, #4
        MOVCS   R2, #3
        ADD     R2, R2, #32
        ]
10
        MOV     R1, #0          ; claim service
        Pull    PC

        END