MODE change code; OSWORD 10; Clear screen - 475 bytes (2.8%)


§1. Initialise VDU variables and change MODE.

 This is called at reset time

 On Entry:
       A = screen MODE number
.initialiseVDUVariablesAndSetMODE = $cb1d
    PHA                                                 save A (screen mode number)

    Clear all VDU variables (0-126)
    LDX #.vduVariablesEnd - .vduVariablesStart          loop counter
    LDA #0                                              A=0
    STA .vduStatusByte                                  VDU status byte to set default
                                                        conditions (zero)
-
    STA .vduVariablesStart-1,X                          zero VDU variables (0-126)
    DEX                                                 with this loop
    BNE -                                               

    implode character definitions
    JSR .osbyte20EntryPoint                             implode character definitions (A = 0)
    PLA                                                 get back A (screen mode number)

    Set teletext cursor
    LDX #$7F                                            X=$7F
    STX .vduTeletextCharacterForCursor                  set mode 7 cursor character
    fall through...

§2. Set MODE.

 On Entry:
       A = screen MODE number
.setMODE = $cb33
    BIT .systemAvailableRAM                             test available RAM pages ($40 = 16k;
                                                        $80 = 32k)
    BMI +                                               if (32k available) then branch
    ORA #4                                              ensure only modes 4-7 are available
+
    AND #7                                              X = A AND 7 (to ensure a legal mode)
    TAX                                                 X = mode

    Set characteristic vdu variables for the new mode
    STX .vduCurrentScreenMODE                           set screen mode
    LDA .numberOfColoursMinusOneInMODETable,X           get number of colours -1 in mode
                                                        from table
    STA .vduNumberOfLogicalColoursMinusOne              set number of logical colours less 1
    LDA .bytesPerCharacter,X                            get number of bytes /character from
                                                        table
    STA .vduBytesPerCharacter                           set bytes per character
    LDA .pixelsPerByteMinusOneInMODETable,X             get display mode pixels/byte from
                                                        table
    STA .vduPixelsPerByteMinusOne                       set pixels per byte-1
    BNE +                                               if (in a graphics mode) then branch
    LDA #7                                              this is a text mode; set A = 7
+
    ASL                                                 A = A * 2
    TAY                                                 Y = 2 * (pixels per byte-1), index
                                                        into a table of colour masks
    LDA .sixteenColourMODEMaskTable - 1,Y               mask table
    STA .vduColourMaskRight                             store as colour mask right
-
    ASL                                                 shift A left
    BPL -                                               until the top bit becomes set
    STA .vduColourMaskLeft                              store as colour mask left

    LDY .screenDisplayMemoryIndexTable,X                screen display memory index table
    STY .vduCurrentScreenMODEGroup                      MODE group = screen memory size:
                                                              0 = 20k (MODE 0,1,2)
                                                              1 = 16k (MODE 3)
                                                              2 = 10k (MODE 4,5)
                                                              3 = 8k (MODE 6)
                                                              4 = 1k (MODE 7)

    LDA .systemVIAHardwareScrollTable2,Y                get system VIA parameter for setting
                                                        hardware scrolling value
    JSR .writeAToSystemVIARegisterB                     write hardware scrolling value to
                                                        System VIA
    LDA .systemVIAHardwareScrollTable1,Y                get system VIA parameter for setting
                                                        hardware scrolling value
    JSR .writeAToSystemVIARegisterB                     write hardware scrolling value to
                                                        System VIA

    LDA .screenMemorySizeInBytesHigh,Y                  screen RAM size high byte table
    STA .vduScreenSizeHighByte                          screen RAM size high byte

    LDA .screenMemoryStartHigh,Y                        screen ram address high byte
    STA .vduStartScreenAddressHighByte                  high byte of screen RAM address

                                                        A=Y=the screen memory type
    TYA                                                 A = Y           A = 0 1 2 3 4
    ADC #2                                              A = A + 2       A = 2 3 4 5 6
    EOR #7                                              A = A EOR 7     A = 5 4 3 2 1
    LSR                                                 A = A / 2       A = 2 2 1 1 0

    TAX                                                 X=A Index into multiplication table
                                                        (0 = MODE 7
                                                         1 = MODE 4,5,6
                                                         2 = MODE 0,1,2,3)

    LDA .multiplicationTabletoUseLow,X                  load the low byte of the
                                                        multiplication table to use
    STA .vduMultiplicationTableLow                      store
    LDA #>.multiplyBy640Table                           high byte of multiplication tables
    STA .vduMultiplicationTableHigh                     store. Now
                                                        (.vduMultiplicationTableLow) points
                                                        to 640x multiplication table or 40x.
    LDA .bytesPerRowLow,X                               get number of bytes per row (low
                                                        byte) from table

    STA .vduBytesPerCharacterRowLow                     store bytes per character row
    STX .vduBytesPerCharacterRowHigh                    bytes per character row (high byte)
    LDA #%01000011                                      
    JSR .clearVDUStatusByteFlags                        clear bits 2,3,4,5,7 in
                                                        .vduStatusByteFlags:
                                                        bit 2 = paged scrolling selected
                                                        bit 3 = software scrolling (text
                                                        window)
                                                        bit 4 = not used
                                                        bit 5 = graphics cursor enabled (VDU
                                                        5)
                                                        bit 7 = VDU disabled


    LDX .vduCurrentScreenMODE                           screen mode
    LDA .videoULAVideoControlRegisterDefaultValuesPerMODE,X get video ULA control setting
    JSR .setVideoULA                                    set video ULA using OSBYTE 154

    Set CRTC registers for the current mode
    PHP                                                 push flags
    SEI                                                 disable interrupts
    LDX .crtcCursorEndRegisterTable,Y                   get cursor end register data from
                                                        table
    LDY #11                                             Y = 11
-
    LDA .crtcRegisters0to11ForMODEs012,X                get entry from CRTC table
    JSR .setCRTCRegisterAY                              set CRTC Register Y to A
    DEX                                                 reduce pointers
    DEY                                                 
    BPL -                                               if (still >=0) then branch (loop
                                                        back)
    PLP                                                 pull flags
    JSR .vdu20EntryPoint                                set default colours
    JSR .vdu26EntryPoint                                set default windows

.initializeDisplayAndHomeCursor = $cbc1
    LDX #0                                              X = 0
    LDA .vduStartScreenAddressHighByte                  high byte of screen RAM address
    STX .vduScreenTopLeftAddressLow                     screen start address low
    STA .vduScreenTopLeftAddressHigh                    screen start address high
    JSR .setTextCursorCRTCAddress                       use X and Y to set new cursor address
    LDY #.crtcStartScreenAddressHighRegister            
    JSR .setTwoCRTCRegisters                            set registers 12 and 13 in CRTC
    LDA .vduBackgroundTextColour                        background text colour
    LDX .vduCurrentScreenMODEGroup                      MODE group = screen memory size
                                                        0=20k (MODE 0,1,2)
                                                        1=16k (MODE 3)
                                                        2=10k (MODE 4,5)
                                                        3=8k (MODE 6)
                                                        4=1k (MODE 7)
    LDY .clearScreenRoutineEntryPointLow,X              get section control number
    STY .vduJumpVectorLow                               set it in jump vector low
    LDY #>.clearScreenRoutineEntryPointMODE012          high byte of address of screen
                                                        clearing routine
    STY .vduJumpVectorHigh                              upper byte of link address
    LDX #0                                              X = 0
    STX .pagedModeCounter                               paged mode counter
    STX .vduTextCursorXPosition                         text column
    STX .vduTextCursorYPosition                         current text line
    JMP (.vduJumpVectorLow)                             jump indirect - this calls the
                                                        screen clearing routine

§3. OSWORD 10 - Read character definition.

 On Entry:
       A          = character to read
       .oswordX/Y = address of buffer to store the eight bytes of results
.osword10EntryPoint = $cbf3
    JSR .getCharacterDefinitionAddress                  set up character definition pointers
    LDY #0                                              Y=0
-
    LDA (.vduTempStoreDE),Y                             get first byte
    INY                                                 Y=Y+1
    STA (.oswordX),Y                                    store it in YX
    CPY #8                                              until Y=8
    BNE -                                               
    RTS                                                 

§4. Screen clear routine.

 On Entry:
       A contains byte for the background colour which is set in every byte of the screen

 To visualise the pattern of bytes that are cleared see:

.clearScreenRoutineEntryPointMODE012 = $cc02
    STA $3000,X                                         
    STA $3100,X                                         
    STA $3200,X                                         
    STA $3300,X                                         
    STA $3400,X                                         
    STA $3500,X                                         
    STA $3600,X                                         
    STA $3700,X                                         
    STA $3800,X                                         
    STA $3900,X                                         
    STA $3A00,X                                         
    STA $3B00,X                                         
    STA $3C00,X                                         
    STA $3D00,X                                         
    STA $3E00,X                                         
    STA $3F00,X                                         

.clearScreenRoutineEntryPointMODE3 = $cc32
    STA $4000,X                                         
    STA $4100,X                                         
    STA $4200,X                                         
    STA $4300,X                                         
    STA $4400,X                                         
    STA $4500,X                                         
    STA $4600,X                                         
    STA $4700,X                                         
    STA $4800,X                                         
    STA $4900,X                                         
    STA $4A00,X                                         
    STA $4B00,X                                         
    STA $4C00,X                                         
    STA $4D00,X                                         
    STA $4E00,X                                         
    STA $4F00,X                                         
    STA $5000,X                                         
    STA $5100,X                                         
    STA $5200,X                                         
    STA $5300,X                                         
    STA $5400,X                                         
    STA $5500,X                                         
    STA $5600,X                                         
    STA $5700,X                                         

.clearScreenRoutineEntryPointMODE45 = $cc7a
    STA $5800,X                                         
    STA $5900,X                                         
    STA $5A00,X                                         
    STA $5B00,X                                         
    STA $5C00,X                                         
    STA $5D00,X                                         
    STA $5E00,X                                         
    STA $5F00,X                                         

.clearScreenRoutineEntryPointMODE6 = $cc92
    STA $6000,X                                         
    STA $6100,X                                         
    STA $6200,X                                         
    STA $6300,X                                         
    STA $6400,X                                         
    STA $6500,X                                         
    STA $6600,X                                         
    STA $6700,X                                         
    STA $6800,X                                         
    STA $6900,X                                         
    STA $6A00,X                                         
    STA $6B00,X                                         
    STA $6C00,X                                         
    STA $6D00,X                                         
    STA $6E00,X                                         
    STA $6F00,X                                         
    STA $7000,X                                         
    STA $7100,X                                         
    STA $7200,X                                         
    STA $7300,X                                         
    STA $7400,X                                         
    STA $7500,X                                         
    STA $7600,X                                         
    STA $7700,X                                         
    STA $7800,X                                         
    STA $7900,X                                         
    STA $7A00,X                                         
    STA $7B00,X                                         

.clearScreenRoutineEntryPointMODE7 = $cce6
    STA $7C00,X                                         
    STA $7D00,X                                         
    STA $7E00,X                                         
    STA $7F00,X                                         
    INX                                                 
    BEQ .exit7                                          if (all done) then branch (exit)
    fall through...

§5. executeRequiredVDUFunction.

.executeRequiredVDUFunction = $ccf5
    JMP (.vduJumpVectorLow)                             loop back (using the jump vector
                                                        set up previously) to the
                                                        appropriate address for the current
                                                        MODE.