view src/init.s @ 136:e49bd0493baf

Checkpoint updates to immediate mode program editing and some memory handling
author William Astle <lost@l-w.ca>
date Fri, 12 Jul 2024 23:29:45 -0600
parents c7f2f63cbcfe
children 18940aa42dcf
line wrap: on
line source

                *pragmapush list
                *pragma list
START           orcc #0x50                      ; make sure interrupts are disabled if we come here in an unusual way
                ifdef COCO3
                ldu #gime_inite                 ; point to end of GIME initializer
                ldx #GIME.INIT0+(gime_inite-gime_init) ; point to end of GIME registers
                ldb #gime_inite-gime_init       ; number of bytes to transfer
initc0          lda ,-u                         ; copy byte to GIME (count down so we init MMU before turning it on)
                sta ,-x
                decb                            ; done?
                bne initc0                      ; brif not
                endc
                ldd #0xff34                     ; initizer for below
                tfr a,dp                        ; set DP to I/O page
                setdp 0xff                      ; tell assembler about DP value
                clr PIA0.CA                     ; set PIA0 A to direction mode
                clr PIA0.CB                     ; set PIA0 B to direction mode
                clr PIA0.DA                     ; set PIA0 A to all inputs (comparator, keyboard rows)
                sta PIA0.DB                     ; set PIA0 B to all outputs (keyboard columns)
                stb PIA0.CA                     ; set PIA0 A to data mode, interrupt disabled, MUX to source 0
                stb PIA0.CB                     ; set PIA0 B to data mode, interrupt disabled, MUX to source 0
                clr PIA1.CA                     ; set PIA1 A to direction mode
                clr PIA1.CB                     ; set PIA1 B to direction mode
                deca                            ; set PIA1 A bits 7-1 output (DAC, RS232), 0 input (cassette)
                sta PIA1.DA
                lda #0xf8                       ;* set PIA1 B bits 7-3 output (VDG stuff), 2-0 input (single bit sound,
                sta PIA1.DB                     ;* RS232 input, ram size input)
                stb PIA1.CA                     ; set PIA1 A to data mode, interrupt disabled, cassette motor off
                stb PIA1.CB                     ; set PIA1 B to data mode, interrupt disabled, sound off
                lda #2                          ; set RS232 output to "marking" (stop bit)
                sta PIA1.DA
                lda #16                         ; clear 16 SAM register bits
                ldu #SAMREG                     ; point to SAM register bits
init0           sta ,u++                        ; clear SAM bit
                deca                            ; done all?
                bne init0                       ; brif not
; set the SAM to point to the text screen, which the code will handle at any
; arbitrary 512 byte aligned address in memory
                ifne (textscreen)&0x200
                sta SAM.F0SET
                endc
                ifne (textscreen)&0x400
                sta SAM.F1SET
                endc
                ifne (textscreen)&0x800
                sta SAM.F2SET
                endc
                ifne (textscreen)&0x1000
                sta SAM.F3SET
                endc
                ifne (textscreen)&0x2000
                sta SAM.F4SET
                endc
                ifne (textscreen)&0x4000
                sta SAM.F5SET
                endc
                ifne (textscreen)&0x8000
                sta SAM.F6SET
                endc
                ifdef COCO2B
; The following SAM configuration sequence is different from the one in the usual
; one used by the earlier models of the Coco because the Coco2B has the '785 variant
; of the SAM instead of the '783 variant. The '785 variant supports 16Kx4 RAMs which
; are used in Coco2B systems. Hence why there is a different version of this ROM
; just for the Coco2B.
                clr PIA0.DB                     ; strobe RAM size low
                ldb #4                          ; is input low?
                bitb PIA1.DB
                beq init1                       ; brif not
                sta SAM.M0SET                   ; program SAM for 16Kx4 RAMs
                sta SAM.P1SET
                skip2
init1           sta SAM.M1SET                   ; program SAM for 64Kx1 RAMs
                else
                ifndef COCO3
; Detect the installed memory size so the SAM ('783 variant) can be correctly
; programmed for the installed memory. Note that this sequence is replaced with
; a different one for the Coco2B which has the '785 variant of the SAM.
                ldb #0xff                       ; strobe RAM size high
                stb PIA0.DB
                ldb #4                          ; mask for ram size check
                bitb PIA1.DB                    ; is the bit set on ram size input?
                beq init2                       ; brif not - 4Kx1 RAMs
                sta PIA0.DB                     ; clear RAM size output to see what happens (A is 0 from above)
                bitb PIA1.DB                    ; is it set now?
                beq init1                       ; brif not - 64Kx1 RAMs
                leau -2,u                       ; adjust pointer so we set the other RAM size bit for the SAM (16Kx1)
init1           sta -3,u                        ; set M0 (16Kx1) or M1 (64Kx1)
                endc
                endc
init2           tfr a,dp                        ; set DP to bottom of memory (A is 0 from above)
                setdp 0                         ; tell assembler about it
                lds #textscreen                 ; put the stack just below the text screen
                ifdef COCO3
; Check if we need to do a ROM/RAM copy, which will happen if the interrupt vectors are
; not flagged valid OR the reset vector isn't valid
                ldb INT.FLAG                    ; are the bounce vectors valid?
                cmpb #0x55
                bne initc4                      ; brif not - do ROM/RAM copy
                ldb RSTFLG                      ; is reset vector valid?
                bne initc2                      ; brif not - check secondary location
                ldx RSTVEC                      ; get reset vector
                ldb ,x                          ; is it valid?\
                cmpb #0x12
                bne initc2                      ; brif not
initc1          jmp ,x                          ; transfer control to warm start routine
initc2          clr GIME.MMU0                   ; check again with block 0 in the direct page
                ldb RSTFLG                      ; get new RSTFLG
                cmpb #0x55                      ; valid?
                bne initc3                      ; brif not
                ldx RSTVEC                      ; get new RSTVEC
                ldb ,x                          ; is it valid?
                cmpb #0x12
                beq initc1                      ; brif so - transfer control
initc3          ldb #0x38                       ; restore MMU
                stb GIME.MMU0
initc4          ldx #initc6                     ; point to helper
                ldu #textscreen                 ; point to text screen
                ldb #initc7-initc6              ; bytes to copy
initc5          lda ,x+                         ; copy byte
                sta ,u+
                decb                            ; done?
                bne initc5                      ; brif not
                ldu #0x8000                     ; point to start of ROM
                jmp textscreen                  ; transfer control to helper in RAM
initc6          sta SAM.TYCLR                   ; drop to ROM mode
                pulu d,x,y,s                    ; grab 8 bytes
                sta SAM.TYSET                   ; go to RAM mode
                pshu d,x,y,s                    ; stick the bytes in RAM
                leau 8,u                        ; move to next 8 bytes
                cmpu #0xfe00                    ; end of stuff to copy?
                blo initc6                      ; brif not
                jmp initc7                      ; go back to mainline
initc7          lds #textscreen                 ; reset stack to somewhere safe
                lda #0x12                       ; activate ROM warm start handler
                sta warmstart
                ldx #INT.FLAG                   ; point to bounce vector destination
                ldu #int_init                   ; point to initializer for bounce vectors
                ldb #int_inite-int_init         ; number of bytes to copy
initc8          lda ,u+                         ; copy byte
                sta ,x+
                decb                            ; done?
                bne initc8                      ; brif not
; now recheck for warm start in case ROM/RAM copy made things valid
                endc
                ldb RSTFLG                      ; is the reset vector valid?
                cmpb #0x55
                bne coldstart                   ; brif not - do cold start
                ldx RSTVEC                      ; get warm start routine pointer
                ldb ,x                          ; does it start with NOP?
                cmpb #0x12
                bne coldstart                   ; brif not - do cold start
                jmp ,x                          ; transfer control to warm start routine
                ifdef COCO3
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; GIME register initializer
gime_init       fcb GIME_COCO|GIME_MMUEN|GIME_FExx|GIME_SCS|GIME_ROMI32 ; enable MMU, SCS, constant page, internal ROM
                fcb GIME_TASK0                  ; use MMU task 0
                fcb 0                           ; do not enable IRQ sources
                fcb 0                           ; do not enable FIRQ sources
                fdb 0xfff                       ; set timer to max value
                fdb 0                           ; *reserved placeholder*
                fcb 0,0,0,0                     ; SG4 screen settings with black border
                fcb 0x0f,0xe0,0x00,0x00         ; (puts screen in bottom 64K of memory)
                fcb 0x38,0x39,0x3a,0x3b         ; MMU task 0 (bottom of top 64K of RAM)
                fcb 0x3c,0x3d,0x3e,0x3f         ; (ROM shadow must be in 3c...3f)
                fcb 0x38,0x39,0x3a,0x3b         ; MMU task 1 (copy of task 0)
                fcb 0x3c,0x3d,0x3e,0x3f
                fcb 18,54,9,36,63,27,45,38      ; palette values (RGB)
                fcb 0,18,0,63,0,18,0,38
gime_inite      equ *
int_init        fcb 0x55                        ; vectors valid flag
                jmp SW3VEC                      ; bounce to stock ROM compatibility vector
                jmp SW2VEC                      ; bounce to stock ROM compatibility vector
                jmp FRQVEC                      ; bounce to stock ROM compatibility vector
                jmp IRQVEC                      ; bounce to stock ROM compatibility vector
                jmp SWIVEC                      ; bounce to stock ROM compatibility vector
                jmp NMIVEC                      ; bounce to stock ROM compatibility vector
int_inite       equ *
                endc
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Cold start handling
coldstart       ldx #dpstart                    ; point to start of direct page
                ldd #0                          ; set up for blanking
coldstart0      std ,x++                        ; blank a couple of bytes
                cmpx #textscreen                ; end of low memory?
                blo coldstart0                  ; brif not
                ifndef COCO3
; This is the memory size detection sequence. This runs through memory starting at the bottom of memory
; and stops when it reaches something that can't be modified successfully. This is basically the same
; algorithm used by the stock ROM. It takes less space than doing a more pointed set of probes. The end
; result will be X pointing to the byte one below the top of RAM. This is intentional to ensure there
; is one writeable byte at the top of string space. Note that X will point to the byte after the end
; of the text screen when we get here.
                ldx #heapstart                  ; point to start of heap
coldstart1      lda 2,x                         ; get original value at test location
                coma                            ; invert all bits
                sta 2,x                         ; write it to the memory location
                cmpa 2,x                        ; did it take?
                bne coldstart2                  ; brif not
                com 2,x                         ; restore memory byte
                leax 1,x                        ; move pointer forward
                bra coldstart1                  ; go check next byte
                else
; For the Coco3, we do not need to concern ourselves about where the top actual memory is so we don't
; bother doing a memory scan in the default 64K memory map. Because we always run from RAM, we can actually
; set the top of memory to the actual top of the 32K space without having to ensure there is an extra byte
; available above the string space.
                ldx #ROMSTART-1                 ; point to top of memory
                endc
coldstart2      stx memtop                      ; save absolute top of memory
                stx memsize                     ; save top of unreserved memory
                stx stringtab                   ; mark string space as empty
                leax -200,x                     ; allocate 200 bytes of string space
                stx freetop                     ; save top of free memory
                clr ,-x                         ; make a hole for the "end of call stack" flag
                stx cstackptr                   ; save the new call stack pointer
                leas ,x                         ; put the actual stack below the above
                ldx #heapstart                  ; point to start of free memory
                clr ,x+                         ; put a NUL before the start of the program
                stx prog_text                   ; put the start of the program there
                clr ,x+                         ; put a NULL pointer to mark end of program
                clr ,x+
                stx vartab                      ; put start of integer variables at end of program
                stx objecttab                   ; also put the start of large objects there
                stx freestart                   ; mark the start of free memory
                lda #keyb_caps                  ; enable caps lock but disable all other shift states
                sta keyb_flags
                ldx #warmstart                  ; set up warm start handler
                stx RSTVEC
                lda #0x55                       ; activate warm start handler
                sta RSTFLG
                ldd #0x7e3b                     ; opcodes for JMP extended and RTI
                ldx #irqhandler                 ; enable IRQ handler with a JMP at the vector
                sta IRQVEC
                stx IRQVEC+1
                sta FRQVEC                      ; initialize FIRQ handler with JMP
                ldx #firqhandler
                stx FRQVEC+1
                stb NMIVEC                      ; initialize NMI to RTI
                stb SW3VEC                      ; initialize SWI3 to RTI
                stb SW2VEC                      ; initialize SWI2 to RTI
                stb SWIVEC                      ; initialize SWI to RTI
                ldx #greeting                   ; display greeting
                jsr console_outstr
                bra warmstartb                  ; finish up initialization
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Warm start handling
                ifdef COCO3
warmstart       fcb 0xff                        ; set to 0xff to force ROM/RAM copy on reset
                else
warmstart       nop                             ; flag warm start routine as valid
                endc
                jsr console_clear               ; clear screen
                clr filenum                     ; reset I/O channel to the screen
warmstartb      jsr keyb_reset                  ; reset the keyboard
                lda #0x35                       ; enable VSYNC interrupt in PIA
                sta PIA0.CB
                lda PIA0.DA                     ;* clear any spurious interrupts which should work around weird bugs
                lda PIA0.DB                     ;* in emulators
                lda PIA1.DA
                lda PIA1.DB
                ifdef COCO3
                lda GIME.IRQ
                lda GIME.FIRQ
                endc
                andcc #0xaf                     ; enable interrupts at the cpu
                jmp immediate                   ; go start immediate mode
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; System startup message
; (start with form feed to clear screen; saves 2 bytes over 'jsr console_clear' in cold start)
greeting        fcc '\fLWBASIC VERSION 2022.0\r\n'
                fcc 'COPYRIGHT (C) 2022 BY LOST\r\n'
                fcc 'WIZARD ENTERPRISES INC.\r\n'
                fcn '\n'
                *pragmapop list