Mercurial > hg > index.cgi
view src/lwbasic.s @ 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 |
line wrap: on
line source
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; LWBasic Version 0.1 ; Copyright © 2022 Lost Wizard Enterprises Incorporated ; ; This is LWBasic, a replacement Basic ROM system for the TRS-80 Color Computer which ; is most definitely not binary compatible with the stock ROMs. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; *pragmapush list *pragma nolist *pragma noexpandcond ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Utility macros ; ; skip next byte; flags preserved skip1 macro noexpand fcb 0x21 ; opcode for BRN endm ; skip next byte and load nonzero to A skip1lda macro noexpand fcb 0x86 ; opcode for LDA immediate endm ; skip next byte and load nonzero to B skip1ldb macro noexpand fcb 0xc6 ; opcoe for LDB immediate endm ; skip next 2 bytes; clobbers flags skip2 macro noexpand fcb 0x8c ; opcode for CMPX immediate 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 PIA0.DA rmb 1 ; PIA0 data/direction A PIA0.CA rmb 1 ; PIA0 control A PIA0.DB rmb 1 ; PIA0 data/direction B PIA0.CB rmb 1 ; PIA0 control B rmb 28 ; mirror images of PIA0 PIA1 equ * ; DA/misc stuff PIA1.DA rmb 1 ; PIA1 data/direction A PIA1.CA rmb 1 ; PIA1 control A PIA1.DB rmb 1 ; PIA1 data/direction B PIA1.CB rmb 1 ; PIA1 control B rmb 28 ; mirror images of PIA1 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 SAM.V1CLR rmb 1 SAM.V1SET rmb 1 SAM.V2CLR rmb 1 SAM.V2SET rmb 1 SAM.F0CLR rmb 1 ; SAM screen address bits SAM.F0SET rmb 1 SAM.F1CLR rmb 1 SAM.F1SET rmb 1 SAM.F2CLR rmb 1 SAM.F2SET rmb 1 SAM.F3CLR rmb 1 SAM.F3SET rmb 1 SAM.F4CLR rmb 1 SAM.F4SET rmb 1 SAM.F5CLR rmb 1 SAM.F5SET rmb 1 SAM.F6CLR rmb 1 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, 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, not used on Coco3) SAM.M0SET rmb 1 SAM.M1CLR rmb 1 SAM.M1SET rmb 1 SAM.TYCLR rmb 1 ; force ROM mode (map type 0) SAM.TYSET rmb 1 ; set RAM mode (map type 1) rmb 18 ; *MPU reserved* CPU.SWI3 rmb 2 ; CPU SWI3 vector CPU.SWI2 rmb 2 ; CPU SWI2 vector CPU.FIRQ rmb 2 ; CPU FIRQ vector CPU.IRQ rmb 2 ; CPU IRQ vector CPU.SWI rmb 2 ; CPU SWI vector CPU.NMI rmb 2 ; CPU NMI vector CPU.RESET rmb 2 ; CPU RESET/startup vector ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Start of memory which has the direct page and other data. org 0 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 (must be on 512 byte alignment) org 0x8000 ; the hardware puts the ROMs here; it's not negotiable 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-SAMREG)-16,u endc ifne (textscreen)&0x400 sta (SAM.F1SET-SAMREG)-16,u endc ifne (textscreen)&0x800 sta (SAM.F2SET-SAMREG)-16,u endc ifne (textscreen)&0x1000 sta (SAM.F3SET-SAMREG)-16,u endc ifne (textscreen)&0x2000 sta (SAM.F4SET-SAMREG)-16,u endc ifne (textscreen)&0x4000 sta (SAM.F5SET-SAMREG)-16,u endc ifne (textscreen)&0x8000 sta (SAM.F6SET-SAMREG)-16,u 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 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 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) 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