From f81f76eefb6b947af21745d639fcefcb32a38e3b Mon Sep 17 00:00:00 2001 From: Curtis F Kaylor Date: Mon, 23 Sep 2019 19:57:03 -0400 Subject: [PATCH] Created vera.a02 and vera.h02 --- x16/include/vera.a02 | 311 +++++++++++++++++++++++++++++++++++++++++++ x16/include/vera.h02 | 42 ++++++ x16/testvera.c02 | 176 ++++++++++++++++++++++++ 3 files changed, 529 insertions(+) create mode 100644 x16/include/vera.a02 create mode 100644 x16/include/vera.h02 create mode 100644 x16/testvera.c02 diff --git a/x16/include/vera.a02 b/x16/include/vera.a02 new file mode 100644 index 0000000..b4f55bd --- /dev/null +++ b/x16/include/vera.a02 @@ -0,0 +1,311 @@ +; C02 module vera.h02 assembly language subroutines +; Requires External Functions NYBCAT, NYBCUT +; and Variables TEMP0 + +;getvid() - Get Video Output Mode +;Returns: A = Video Mode +; Y = Chroma Disabled +; X = Current Field +GETVID: LDA #$00 ;Set Register Offset to Video Output + JSR GETDCR ;Read from Display Composer + LDY #$00 ;Set Chroma Disabled to FALSE + LDX #$00 ;Set Video Field to EVEN + BIT GETVIM ;Test Chroma Disabled Bit + BEQ GETVIE ;If Bit 3 is Set + DEY ; Set Chroma Disabled to TRUE + BIT GETVIM ;Test Chroma Disabled Bit +GETVIE: BCC GETVIF ;If Bit 7 is Set + DEX ; Set Video Field to ODD +GETVIF: AND #$03 ;Isolate Bits 0-2 (Video Output Mode) + RTS +GETVIM: .DC $04 ;Chroma Disable Bit Mask + +;getbdr() - Get Get Border Color +;Returns: A = Border Color Palette Index +GETBDR: LDA #$03 ;Set Register Offset to Border Color + +;getdcr() - Get Display Composer Register +;Args: A = Register Offset +;Affects: Y +;Returns: A = Contents of Register +; X = Current Data Port +GETDCR: LDY #$00 ;Set MSB to Display Composer Page + TAX ;Set LSB to Register Offset + ;and Execute GETREG +;getreg(addr); +;Args: Y,X = Address +;Returns: A = Mode +; X = Current Data Port +GETREG: LDA #$0F ;Set Bank to Registers +GETBYT: JSR SETADR ;Set Vera Address + LDX $9F25 ;Get Current Data Port + LDA $9F23,X ;Read LSB from Data Port + RTS + +;getvsp() - Get Vertical Stop +;Destroys: TEMP0 +;Affects: A +;Returns: Y,X = Vertical Stop +GETVSP: LDA #3 ;Set Lookup Index to Vertical Stop + .DC $2C ;Skip to GETHVS (BIT Absolute) + +;getvsr() - Get Vertical Start +;Destroys: TEMP0 +;Affects: A +;Returns: Y,X = Vertical Start +GETVSR: LDA #2 ;Set Lookup Index to Vertical Start + .DC $2C ;Skip to GETHVS (BIT Absolute) + +;gethsp() - Get Horizontal Stop +;Destroys: TEMP0 +;Affects: A +;Returns: Y,X = Horizontal Start +GETHSP: LDA #1 ;Set Lookup Index to Horizontal Start + .DC $2C ;Skip to GETHVS (BIT Absolute) + +;gethsr() - Get Horizontal Start +;Destroys: TEMP0 +;Affects: A +;Returns: Y,X = Horizontal Start +GETHSR: LDA #0 ;Set Lookup Index to Horizontal Start + +GETHVS: LDY GETHVM,X ;Get High Bits Mask + STY TEMP0 ;and Save It + LDY GETHVO,X ;Get High Bits Rotation Count + .DC $5A ;PHY ;And Save it on Stack + ORA #4 ;Convert Index to Register Offset + JSR GETDCR ;Read LSB from Register + PHA ;and Save It + LDA #8 ;Load Register Offset for High Bits + STA $9F20 ;Set As Address LSB + LDA $9F23,X ;and Read High Byte from Data Port + AND TEMP0 ;and Isolate High Bits + .DC $FA ;PLX ;Restore LSB into X Register + .DC $7A ;PLY ;Restore Rotation Count into Y + BEQ GETHVY ;If Not Zero +GETHVR: LSR ;Shift Right One Bit + DEY ;Decrement Counter + BNE GETHVR ;and Loop if Not Zero +GETHVY: TYA ;Return MSB in Y Register + RTS +GETHVM: .DC $03,$C0,$10,$20 +GETHVO: .DC 0,2,4,5 + +;getiql() - Get Interrupt Line +;Affects: A +;Returns: Y,X = Interrupt Line# +GETIQL: LDA #9 ;Set Register Offset to HSCALE,VSCALE + .DC $2C ;Skip to SETDCX (BIT Absolute) + +;getscl() - Get Horizontal and Vertical Scale +;Returns: A,X = Horizontal Scale +; Y = Vertical Scale +GETSCL: LDA #1 ;Set Register Offset to HSCALE,VSCALE + +;getdci() - Get Display Composer Register Pair +;Args: A = Register Offset +;Affects: Y +;Returns: A,X = Integer LSB +; Y = Integer LSB +GETDCI: LDY #$00 ;Set MSB to Display Composer Page + TAX ;Set LSB to Register Offset + ;and Execute GETREG + +;getrei(addr); Read Vera Register Pair +;Args: Y,X = Address +;Returns: A,X = Integer LSB +; Y = Integer LSB +GETREI: LDA #$0F ;Set Bank to Registers + +;getint(addr); Read Integer from Vera Memory +;Args: A = Bank +; Y,X = Address +;Returns: A,X = Integer LSB +; Y = Integer LSB +GETINT: ORA #$10 ;Set Auto-Increment to 1 + JSR SETADR ;Set Vera Address + LDX $9F25 ;Get Current Data Port + LDA $9F23,X ;Read LSB from Data Port + LDY $9F23,X ;Read MSB Data Port + TAX ;Copy LSB to X + RTS + +;setvid() - Set Video Output Mode +;Args: A = Video Mode +; Y = Chroma Disabled +;Destroys: TEMP0 +SETVID: AND #3 ;Isolate Video Mode Bits + CPY #0 ;Set Chroma Mask to + BEQ SETVIF ; 0 if Y is Zero or + LDY #4 ; 4 if it is not +SETVIF: STY TEMP0 ;Save Chroma Bit + ORA TEMP0 ;Combine with Video Mode Bits + LDX #0 ;Set Register Offset to Video Mode + BEQ SETDCX ;Write to Register + +;setbdr() - Set Border Color +;Args: A = Border Color Palette Index +SETBDR: LDX #3 ;Set Register Offset to Border Color + .DC $2C ;Skip to SETDCX (BIT Absolute) + +;setdcr() - Set Display Composer Register +;Args: A = Register Offset +; Y = Value to Write +;Affects: Y +;Returns: A = Value Written +; X = Current Data Port +SETDCR: TAX ;Set LSB to Register Offset + TYA ;Move Write Value to Accumulator +SETDCX: LDY #$00 ;Set MSB to Display Composer Page + +;setreg(addr) - Set Register +;Args: A = Value to Write +; Y,X = Address +;Sets: TEMP0 = Value to Write +;Affects: Y +;Returns: A = Value Written +; X = Current Data Port +SETREG: STA TEMP0 ;Save Value to Write +SETREH: LDA #$0F ;Set Bank, Auto-Increment + +;setbyt(addr) - Write Byte to Vera Memory +;Args: A = Bank +; Y,X = Address +;Uses: TEMP0 = Value to Write +;Affects: Y +;Returns: A = Value Written +; X = Current Data Port +SETBYT: JSR SETADR ;Set Vera Address + LDA TEMP0 ;Retrieve Value to Write + LDX $9F25 ;Get Current Data Port + STA $9F23,X ;Write Value to Data Port + RTS + + +;setiql() - Set IRQ Line +;Args: Y,X = IRQ Line Number` +;Sets: TEMP1,TEMP2 = IRQ Line Number +;Affecta: A,Y,X +SETIQL: TXA ;Copy LSB to Accumulator + LDX #9 ;Set Register Offset to HSCALE,VSCALE + .DC $2C ;Skip to SETDCP (BIT Absolute) + +;setscl() - Set Horizontal and Vertical Scale +;Args: A = Horizontal Scale +; Y = Vertical Scale +SETSCL: LDX #1 ;Set Register Offset to HSCALE,VSCALE + +;setdcp() - Set Display Composer Register Pair +;Args: A = First Register Value +; Y = Second Register Value +; X = Register Offset +;Affects: A,Y +;Returns: X = Current Data Port +SETDCP: STA TEMP1 ;Store First Value as LSB + STY TEMP2 ;Store Second Value as MSB + LDY #$00 ;Set MSB to Display Composer Page + +;setrei(addr); Set Vera Register to Integer +;Args: Y,X = Address +;Uses: TEMP1,TEMP2 = Integer Value +;Affects: A,Y +;Returns: X = Current Data Port +SETREI: LDA #$0F ;Set Bank to Registers + +;setint(addr); Write Integer to Vera Memory +;Args: A = Bank +; Y,X = Address +;Uses: TEMP1,TEMP2 = Integer Value +;Affects: A,Y +;Returns: X = Current Data Port +SETINT: ORA #$10 ;Set Auto-Increment to 1 + JSR SETADR ;Set Vera Address + LDX $9F25 ;Get Current Data Port + LDA TEMP1 ;Get LSB + STA $9F23,X ;Write to Data Port + LDA TEMP2 ;Get MSB + STA $9F23,X ;Write to Data Port + RTS + + +;rgbclr(r,g,b) - Convert RGB Values to Palette Color +;Args: A = Red Value (0-15) +; Y = Green Value (0-15) +; X = Blue Value (0-15) +;Affects: A +;Returns: Y = Color MSB (0000RRRR) +; X = Color LSB (GGGGBBBB) +RGBCLR: PHA ;Save Red Value + TYA ;Copy Green Value to Left Nybble + .DC $DA ;PHX Copy Blue Value + .DC $7A ;PLY to Right Nybble + JSR NYBCAT ;Concatanate Green and Blue + TAX ;and Return as LSB + .DC $7A ;PLY Return Red as MSB + RTS + +;clrrgb(c) - Convert Palette Color to RGB Values +;Args: Y = Color MSB (0000RRRR) +; X = Color LSB (GGGGBBBB) +;Returns: A = Red Value (0-15) +; Y = Green Value (0-15) +; X = Blue Value (0-15) +CLRRGB: .DC $5A ;PHY Save MSB + TXA ;Copy LSB into Accumulator + JSR NYBCUT ;and Split into Nybbles + .DC $5A ;PHY Return Blue Value + .DC $FA ;PLX in X Register + TAY ;Green Value in Y Register + PLA ;and Red Value in Accumulator + RTS + +;getclr(idx) - Get Color Entry idx from Palette +;Args: A = Color Entry Index +;Affects: A +;Returns: Y = Color MSB (0000RRRR) +; X = Color LSB (GGGGBBBB) +GETCLR: JSR SETIDX ;Set Vera Address to Palette Index + LDX $9F25 ;Get Current Data Port + LDA $9F23,X ;Read LSB from Data Port + LDY $9F23,X ;Read MSB from Data Port + TAX ;Copy LSB to X Register + RTS + +;setclr(idx) - Set Color Entry idx in Palette +;Args: A = Color Entry Index +; Y = Color MSB (0000RRRR) +; X = Color LSB (GGGGBBBB) +;Affects: A +;Returns: Y,X = Color Entry Address +SETCLR: JSR SAVRXY ;Save Color Value + JSR SETIDX ;Set Vera Address to Palette Index + LDX $9F25 ;Get Current Data Port + LDA TEMP1 ;Retrieve Color Value LSB + STA $9F23,X ;and Write to Data Port + LDA TEMP2 ;Retrieve Color Value MSB + STA $9F23,X ;Read MSB from Data Port + RTS + +;setidx(idx) - Set Vera Address to Palette Index +;Args: A = Index +;Returns: A = Bank + Auto-Increment +; Y,X = Address +SETIDX: ASL ;Multiply Index by 2 + TAX ;and Set as LSB + LDA #$10 ;Get Palette Page + ADC #$00 ;Add Carry from Multiply + TAY ;and Set as MSB + + +;regadr(opts,addr) - Set Vera Address to Internal Register +;Args: Y,X = Register Address +;Returns: A= Bank + Auto-Increment +REGADR: LDA #$1F ;Set Bank and Auto-Increment + +;setadr(opts,addr) - Set Vera Address +;Args: A = Bank + Auto-Increment +; Y,X = Address +SETADR: STX $9F20 ;Store Address LSB + STY $9F21 ;Store Address MSB + STA $9F22 ;Store Bank & Auto-Increment + RTS diff --git a/x16/include/vera.h02 b/x16/include/vera.h02 new file mode 100644 index 0000000..1cadea6 --- /dev/null +++ b/x16/include/vera.h02 @@ -0,0 +1,42 @@ +/*************************************************** + * vera.h02 - Commander X16 Routines for Vera chip * + ***************************************************/ + +/* Convert Palette Color Value * + * to R, G, and B Values * + * Args: int c - Color Value * + * Returns: Red Value (0-15) * + * Green Value (0-15) * + * Blue Value (0-15) */ +char clrrgb(); + +/* Read Color Value from Palette * + * Args: char i - Palette Index * + * Returns: int c - Color Value */ +char getclr(); + +/* Read Display Controller Register * + * Args: char r - Register Offset * + * Returns: char v - Register Value */ +char getdcr(); + +/* Read Video Output Mode * + * Returns: m - Output Mode * + * c - Chroma Disabled * + * f - Current Field */ +char getvid(); + +/* Convert R, G, and B Values * + * to Palette Color Value * + * Args: r - Red Value (0-15) * + * g - Green Value (0-15) * + * b - Blue Value (0-15) * + * Returns: int c - Color Value */ +char rgbclr(); + +/* Write Color Value to Palette * + * Args: i - Index into Palette * + * int c - Color Value * + * Returns: int d = Entry Address */ +char setclr(); + diff --git a/x16/testvera.c02 b/x16/testvera.c02 new file mode 100644 index 0000000..601481d --- /dev/null +++ b/x16/testvera.c02 @@ -0,0 +1,176 @@ +/***************************************************** + * HELLO - Test/Demo program for C02 Standard Header * + * Prints "HELLO WORLD" and exits * + *****************************************************/ + +//Specify System Header using -H option +#include +#include +#include +#include +#include +#include +#include "include/vera.h02" + +char hscale,vscale; //Video Scaling +char index; //Color Palette Index +char mode,mono,field; //Video Output Mode, Monochrome Flag, Current Field +char red,green,blue; //Color Components +char i,j,k,l; + +int c,d,s; +int hstart,hstop; //Horizontal Start and Stop +int vstart,vstop; //Vertical Start and Stop +int irqlin; //IRQ Line# +char aa,xx,yy; + +void passed() { + putln(" PASSED"); + newlin(); +} + +void prtayx(aa,yy,xx) {prhex(aa); prhex(yy); prhex(xx); putspc(); putspc();} + +void prthvs() { + setdst(hstart);printf("HSTART=%w, "); + setdst(hstop);printf("HSTOP=%w, "); + setdst(vstart);printf("VSTART=%w, "); + setdst(vstop);printf("VSTOP=%w%n"); +} + +void prttmp() { + printf(temp0, "TEMP0=$%h%n"); + printf(temp1, "TEMP1=$%h%n"); + printf(temp2, "TEMP2=$%h%n"); + printf(temp3, "TEMP3=$%h%n"); +} + +void prtscl() { + printf(hscale, "HSCALE=%h, "); + printf(vscale, "VSCALE=%h%n"); +} + +void prtvid() { + select (mode) { + case 0: puts("DISABLED"); + case 1: puts("VGA"); + case 2: puts("NTSC"); + case 3: puts("RGB"); + default: puts("UNDEFINED"); + } + if (mono) puts(" MONOCHROME"); else puts(" COLOR"); + puts(", "); + if (field) puts("ODD"); else puts("EVEN"); + putln(" FIELD"); +} + +void xerror() { + putln("ERROR ENCOUNTERED"); + goto exit; +} + +main: + newlin(); + + putln("TESTING GETVID() AND SETVID()"); + for (i=0;i<4;i++) { + for (j=1;j:+;j--) { + //inline $ff; + setvid(i,j); + mode,mono,field = getvid(); + //prtvid(); + if (mode<>i or mono&j<>j) xerror(); + } + } + passed(); + + putln("TESTING GETBDR() AND SETBDR()"); + i = 0; + do { + setbdr(i); + index = getbdr(); + if (index<>i) xerror(); + //printf(index, "BORDER=%h%n"); + i++; + } while(i); + passed(); + + putln("TESTING GETSCL() AND SETSCL()"); + i=1; + do { + j=1; + do { + setscl(i,j); + hscale,vscale = getscl(); + //prtscl(); + if (hscale<>i or vscale<>j) xerror("ERROR IN GETSCL()/SETSCL()"); + j<<; + } while (j); + i<<; + } while (i); + passed(); + + putln("TESTING GETHST(), GETHSP()"); + hstart = gethsr(); + hstop = gethsp(); + vstart = getvsr(); + vstop = getvsp(); + prthvs(); + newlin(); + + putln("TESTING GETIRL() AND SETIRL()"); + for (i=0;i<2;i++) { + j=0; + do { + setiql(0,i,j); + irqlin = getiql(); + //setdst(); printf("IRQ LINE=%w%n"); + if (>irqlin<>i or j) xerror(); + j++; + } while (j); + } + passed(); + + putln("TESTING RGBCLR() AND CLRRGB()"); + for (red=0;red<16;red++) { + for (green=0;green<16;green++) { + for (blue=0;blue<16;blue++) { + //prtayx(red,green,blue); + c = rgbclr(red,green,blue); + //putwrd(c); putspc(); + i,j,k = clrrgb(); + //prtayx(i,j,k); + if (i<>red or j<>green or blue<>k) xerror(); + } + } + //if (anykey()==#ESCKEY) goto exit; + } + passed(); + + putln("TESTING GETCLR()"); + for (i=16; i<32; i++) { + //puthex(i); putspc(); + c = getclr(i); + //putwrd(c); putspc(); + if (i&15<>>c or nybdup(i)<>d<>>c) xerror(); + //if (i&7==7) newlin(); + } + passed(); + + goto exit;