changeset 4:2b6e6b827bd7

Additional Coco 3 build adjustments Shift the interrupt vectors to top of ROM for Coco3 build. Also add GIME definitions and initialization to startup sequence.
author William Astle <lost@l-w.ca>
date Thu, 03 Nov 2022 22:27:06 -0600
parents 05ef3a3b6d65
children 80c18925436d
files src/lwbasic.s
diffstat 1 files changed, 142 insertions(+), 11 deletions(-) [+]
line wrap: on
line diff
--- a/src/lwbasic.s	Thu Nov 03 21:48:55 2022 -0600
+++ b/src/lwbasic.s	Thu Nov 03 22:27:06 2022 -0600
@@ -29,6 +29,64 @@
                 endm
                 *pragmapop list
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; Various constants
+                ifdef COCO3
+; GIME INIT0
+GIME_COCO       equ 0x80                        ; Set for coco2 compatible mode (video display)
+GIME_MMUEN      equ 0x40                        ; Set to enable MMU
+GIME_IEN        equ 0x20                        ; GIME IRQ enable
+GIME_FEN        equ 0x10                        ; GIME FIRQ enable
+GIME_FExx       equ 0x08                        ; Enable constant RAM at 0xFExx (comes from block 0x3f)
+GIME_SCS        equ 0x04                        ; Set to enable standard SCS (switches 0xFF5x)
+GIME_ROME16     equ 0x00                        ; 16K internal, 16K external ROM mode
+GIME_ROME32     equ 0x03                        ; 32K external ROM
+GIME_ROMI32     equ 0x02                        ; 32K internal ROM
+; GIME INIT1
+GIME_TMRFAT     equ 0x20                        ; TIMER ticks approx every 279.365 ns
+GIME_TMRSLOW    equ 0x00                        ; TIMER ticks approx every 63.695 µs
+GIME_TASK0      equ 0x00                        ; MMU task 0
+GIME_TASK1      equ 0x01                        ; MMU task 1
+; GIME interrupt enable/status bits
+GIME_ITIMER     equ 0x20                        ; TIMER interrupt (timer reaches 0)
+GIME_IHBORD     equ 0x10                        ; HSYNC interrupt (falling edge)
+GIME_IVBORD     equ 0x08                        ; VSYNC interrupt (falling edge)
+GIME_ISERIAL    equ 0x04                        ; Falling edge of signal on pin 4 of serial port
+GIME_IKEYBOARD  equ 0x02                        ; Interrupt if a 0 bit appears on bits 6-0 of PIA0.DA
+GIME_ICART      equ 0x01                        ; Interrupt on falling edge of pin 8 of cartridge port
+; GIME VMODE
+GIME_BP         equ 0x80                        ; enable bit plane mode
+GIME_BPI        equ 0x20                        ; colour burst phase inversion (composite output only)
+GIME_MONO       equ 0x10                        ; disable colour burst (composite output only)
+GIME_H50        equ 0x08                        ; set to 50Hz operation
+GIME_LPR1       equ 0x00                        ; one line per row
+GIME_LPR2       equ 0x02                        ; two lines per row (also works on graphics)
+GIME_LPR8       equ 0x03                        ; 8 lines per row
+GIME_LPR9       equ 0x04                        ; 9 lines per row
+GIME_LPR10      equ 0x05                        ; 10 lines per row
+GIME_LPR11      equ 0x06                        ; 11 lines per row
+GIME_LPRINF     equ 0x07                        ; "infinite" lines per row
+; GIME VRES
+GIME_LPF192     equ 0x00                        ; 192 lines on screen
+GIME_LPF200     equ 0x40                        ; 200 lines on screen (actually 199 due to hardware bug)
+GIME_LPF225     equ 0x60                        ; 225 lines on screen
+GIME_BPR16      equ 0x00                        ; 16 bytes per row
+GIME_BPR20      equ 0x04                        ; 20 bytes per row
+GIME_BPR32      equ 0x08                        ; 32 bytes per row
+GIME_BPR40      equ 0x0c                        ; 40 bytes per row
+GIME_BPR64      equ 0x10                        ; 64 bytes per row
+GIME_BPR80      equ 0x14                        ; 80 bytes per row
+GIME_BPR128     equ 0x18                        ; 128 bytes per row
+GIME_BPR160     equ 0x1c                        ; 160 bytes per row
+GIME_TXT32      equ 0x00                        ; 32 characters per row
+GIME_TXT40      equ 0x04                        ; 40 characters per row
+GIME_TXT64      equ 0x10                        ; 64 characters per row
+GIME_TXT80      equ 0x14                        ; 80 characters per row
+GIME_BPP1       equ 0x00                        ; 1 bit per pixel
+GIME_BPP2       equ 0x01                        ; 2 bits per pixel
+GIME_BPP4       equ 0x02                        ; 4 bits per pixel
+GIME_TXTATTR    equ 0x01                        ; text attributes enabled
+                endc
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ; Hardware definitions for the I/O page
                 org 0xff00
 PIA0            equ *                           ; Keyboard PIA
@@ -46,7 +104,28 @@
                 rmb 16                          ; SCS/Disk controller
                 rmb 16                          ; second half of SCS area
                 rmb 32                          ; miscelaneous hardware
+                ifdef COCO3
+                rmb 16                          ; *reserved* (unused but the GIME drives them)
+GIME.INIT0      rmb 1                           ; basic GIME system config
+GIME.INIT1      rmb 1                           ; MMU task and timer rate
+GIME.IRQ        rmb 1                           ; GIME IRQ enable/status register
+GIME.FIRQ       rmb 1                           ; GIME FIRQ enable/status register
+GIME.TIMER      rmb 2                           ; GIME programmable timer
+                rmb 2                           ; *reserved*
+GIME.VMODE      rmb 1                           ; GIME video mode setting
+GIME.VRES       rmb 1                           ; GIME video resolution setting
+                rmb 1                           ; *reserved* (used for MMU expansion on some memory boards)
+GIME.BORDER     rmb 1                           ; GIME border colour
+GIME.VSCROLL    rmb 1                           ; vertical scroll offset register/VDG screen mode variation
+GIME.VOFFSET    rmb 2                           ; address of video memory (8 byte increments)
+GIME.HOFFSET    rmb 1                           ; horizontal scroll offset
+GIME.MMU        equ *                           ; MMU registers (two tasks)
+GIME.MMU0       rmb 8                           ; MMU task 0
+GIME.MMU1       rmb 8                           ; MMU task 1
+GIME.PALETTE    rmb 16                          ; Palette registers
+                else
                 rmb 64                          ; unused on Coco 1/2 (GIME on Coco 3)
+                endc
 SAMREG          equ *                           ; the SAM configuration register
 SAM.V0CLR       rmb 1                           ; SAM video mode bits
 SAM.V0SET       rmb 1
@@ -70,11 +149,11 @@
 SAM.F6SET       rmb 1
 SAM.P1CLR       rmb 1                           ; SAM "page 1" selection (or extra memory type flag)
 SAM.P1SET       rmb 1
-SAM.R0CLR       rmb 1                           ; SAM R0 bit (address dependent speedup)
+SAM.R0CLR       rmb 1                           ; SAM R0 bit (address dependent speedup, not used on Coco3)
 SAM.R0SET       rmb 1
 SAM.R1CLR       rmb 1                           ; SAM R1 bit (full speedup/coco 3 speedup)
 SAM.R1SET       rmb 1
-SAM.M0CLR       rmb 1                           ; SAM M0/M1 bits (memory type)
+SAM.M0CLR       rmb 1                           ; SAM M0/M1 bits (memory type, not used on Coco3)
 SAM.M0SET       rmb 1
 SAM.M1CLR       rmb 1
 SAM.M1SET       rmb 1
@@ -91,19 +170,29 @@
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ; Start of memory which has the direct page and other data.
                 org 0
-                rmb 0x100                       ; make sure the stuff that isn't direct page is outside of it
+                rmb 0x71-*                      ; align RSTFLG/RSTVEC for stock ROM compatibility
+RSTFLG          rmb 1                           ; 0x55 if RSTVEC is valid
+RSTVEC          rmb 2                           ; points to warm start routine (must start with NOP)
+                rmb 0x100-*                     ; make sure the stuff that isn't direct page is outside of it
                 rmb 0x100                       ; non direct page stuff
-textscreen      rmb 0x200                       ; the actual text screen
-
-
+textscreen      rmb 0x200                       ; the actual text screen (must be on 512 byte alignment)
                 org 0x8000                      ; the hardware puts the ROMs here; it's not negotiable
-START           lda #0xff                       ; set DP to the IO page
-                tfr a,dp
+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)
-                ldd #0xff34                     ; initiazer for later
                 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
@@ -179,6 +268,37 @@
 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
+                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_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
+                fcb 0xfff                       ; set timer to max value
+                fdb 0                           ; *reserved placeholder*
+                fcb 0,0,0,0                     ; SG4 screen settings with black border
+                fcb 0x0f,0x00,0x00,0x00         ; (puts screen in bottom 64K of memory)
+                fcb 0x00,0x01,0x02,0x03         ; MMU task 0 (non-ROM area at bottom of RAM)
+                fcb 0x3c,0x3d,0x3e,0x3f         ; (ROM shadow must be in 3c...3f)
+                fcb 0x00,0x01,0x02,0x03         ; 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 *
+                endc
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; Cold start handling
+coldstart
+                ifndef COCO3
 ; Need to ensure the vectors are at 0xbff2
                 zmb 0xbff2-*                    ; pad ROM up to the vector point
                 fdb 0                           ; SWI3 vector
@@ -188,5 +308,16 @@
                 fdb 0                           ; SWI vector
                 fdb 0                           ; NMI vector
                 fdb START                       ; RESET vector (ROM entry point)
-; pad rom to full size
-                zmb 0x10000-*
+                endc
+                ifdef COCO3
+                zmb 0xfff2-*                    ; pad ROM to bottom of vectors
+                fdb 0                           ; SWI3 vector
+                fdb 0                           ; SWI2 vector
+                fdb 0                           ; FIRQ vector
+                fdb 0                           ; IRQ vector
+                fdb 0                           ; SWI vector
+                fdb 0                           ; NMI vector
+                fdb START                       ; RESET vector (ROM entry point)
+                else
+                zmb 0x10000-*                   ; pad ROM to full size
+                endc