From 4ceeb9c4abd1d689114b28ea1b4ef1f0069e888f Mon Sep 17 00:00:00 2001 From: Dave Plummer Date: Tue, 10 Oct 2023 17:09:32 -0700 Subject: [PATCH] Drawing text --- samples/kim1/kimGFX.bin | Bin 7472 -> 7529 bytes samples/kim1/kimGFX.c | 36 +++---- samples/kim1/kimGFX.lst | 226 ++++++++++++++++------------------------ samples/kim1/subs.asm | 129 ++++++++++++++++++++--- samples/kim1/subs.o | Bin 11504 -> 12938 bytes 5 files changed, 218 insertions(+), 173 deletions(-) diff --git a/samples/kim1/kimGFX.bin b/samples/kim1/kimGFX.bin index 37f00cc195fade91a97c6e49586cd3f1113310c0..94a9e8d6feb8dc6fdb8206485e7f7de08dfb5fe2 100644 GIT binary patch delta 3824 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 E26CFIzyJUM diff --git a/samples/kim1/kimGFX.c b/samples/kim1/kimGFX.c index 74540c561..a461e639c 100644 --- a/samples/kim1/kimGFX.c +++ b/samples/kim1/kimGFX.c @@ -20,6 +20,7 @@ extern void DrawCircle(void); extern void SetPixel(void); extern void ClearPixel(void); extern void DrawChar(void); +extern void Demo(void); extern byte __fastcall__ AscToPet(byte in); extern byte __fastcall__ ReverseBits(byte in); extern unsigned char font8x8_basic[256][8]; @@ -28,6 +29,8 @@ extern int x1cord; extern int y1cord; extern int x2cord; extern int y2cord; +extern int cursorX; +extern int cursorY; // If in zeropage: // @@ -42,9 +45,6 @@ byte * screen = (byte *) 0xA000; // Cursor position -int CursorX = 0; -int CursorY = 0; - #define SCREEN_WIDTH 320 #define SCREEN_HEIGHT 200 #define CHARWIDTH 8 @@ -92,17 +92,17 @@ void DrawText(char * psz) { while (*psz) { - while (CursorX >= CHARSPERROW) + while (cursorX >= CHARSPERROW) { - CursorX -= CHARSPERROW; - CursorY += 1; + cursorX -= CHARSPERROW; + cursorY += 1; } // If we've gone off the bottom of the screen, we scroll the screen and back up to the last line again - if (CursorY >= ROWSPERCOLUMN) + if (cursorY >= ROWSPERCOLUMN) { - CursorY = ROWSPERCOLUMN - 1; + cursorY = ROWSPERCOLUMN - 1; ScrollScreen(); } @@ -110,19 +110,19 @@ void DrawText(char * psz) if (*psz == 0x0A) { - CursorX = 0; - CursorY++; + cursorX = 0; + cursorY++; psz++; } else { c = *psz; - __asm__ ("ldx %v", CursorX); - __asm__ ("ldy %v", CursorY); + __asm__ ("ldx %v", cursorX); + __asm__ ("ldy %v", cursorY); __asm__ ("lda %v", c); DrawChar(); - CursorX++; + cursorX++; psz++; } } @@ -130,8 +130,8 @@ void DrawText(char * psz) void DrawTextAt(int x, int y, char * psz) { - CursorX = x; - CursorY = y; + cursorX = x; + cursorY = y; DrawText(psz); } @@ -218,11 +218,9 @@ int main (void) // Clear the screen memory ClearScreen(); + Demo(); - // Draw the welcome banner at the top of the screen - DrawTextAt(0, 0, " *** COMMODORE KIM-1 SHELL v1.1 ***"); - DrawTextAt(0, 2, " 60K RAM SYSTEM. 49152 BYTES FREE."); - DrawTextAt(0, 4, "READY.\n"); + //DrawTextAt(184, 192, "TEST"); // DrawScreenMoire(0,30, 319, 199); diff --git a/samples/kim1/kimGFX.lst b/samples/kim1/kimGFX.lst index 2429ab087..27ce591ba 100644 --- a/samples/kim1/kimGFX.lst +++ b/samples/kim1/kimGFX.lst @@ -112,14 +112,15 @@ Current file: kimGFX.s 000000r 1 .import _SetPixel 000000r 1 .import _ClearPixel 000000r 1 .import _DrawChar +000000r 1 .import _Demo 000000r 1 .import _ReverseBits 000000r 1 .import _font8x8_basic 000000r 1 .import _x1cord 000000r 1 .import _y1cord 000000r 1 .import _y2cord +000000r 1 .import _cursorX +000000r 1 .import _cursorY 000000r 1 .export _screen -000000r 1 .export _CursorX -000000r 1 .export _CursorY 000000r 1 .export _SETPIXEL 000000r 1 .export _DRAWPIXEL 000000r 1 .export _c @@ -135,41 +136,16 @@ Current file: kimGFX.s 000000r 1 000000r 1 _screen: 000000r 1 00 A0 .word $A000 -000002r 1 _CursorX: -000002r 1 00 00 .word $0000 -000004r 1 _CursorY: -000004r 1 00 00 .word $0000 -000006r 1 -000006r 1 .segment "RODATA" +000002r 1 +000002r 1 .segment "RODATA" 000000r 1 -000000r 1 S0005: -000000r 1 20 20 20 36 .byte $20,$20,$20,$36,$30,$4B,$20,$52,$41,$4D,$20,$53,$59,$53,$54,$45 -000004r 1 30 4B 20 52 -000008r 1 41 4D 20 53 -000010r 1 4D 2E 20 20 .byte $4D,$2E,$20,$20,$34,$39,$31,$35,$32,$20,$42,$59,$54,$45,$53,$20 -000014r 1 34 39 31 35 -000018r 1 32 20 42 59 -000020r 1 46 52 45 45 .byte $46,$52,$45,$45,$2E,$00 -000024r 1 2E 00 -000026r 1 S0004: -000026r 1 20 20 2A 2A .byte $20,$20,$2A,$2A,$2A,$20,$43,$4F,$4D,$4D,$4F,$44,$4F,$52,$45,$20 -00002Ar 1 2A 20 43 4F -00002Er 1 4D 4D 4F 44 -000036r 1 4B 49 4D 2D .byte $4B,$49,$4D,$2D,$31,$20,$53,$48,$45,$4C,$4C,$20,$76,$31,$2E,$31 -00003Ar 1 31 20 53 48 -00003Er 1 45 4C 4C 20 -000046r 1 20 2A 2A 2A .byte $20,$2A,$2A,$2A,$00 -00004Ar 1 00 -00004Br 1 S0007: -00004Br 1 44 6F 6E 65 .byte $44,$6F,$6E,$65,$2C,$20,$65,$78,$69,$74,$69,$6E,$67,$2E,$2E,$2E -00004Fr 1 2C 20 65 78 -000053r 1 69 74 69 6E -00005Br 1 0D 0A 00 .byte $0D,$0A,$00 -00005Er 1 S0006: -00005Er 1 52 45 41 44 .byte $52,$45,$41,$44,$59,$2E,$0A,$00 -000062r 1 59 2E 0A 00 -000066r 1 -000066r 1 .segment "BSS" +000000r 1 S0004: +000000r 1 44 6F 6E 65 .byte $44,$6F,$6E,$65,$2C,$20,$65,$78,$69,$74,$69,$6E,$67,$2E,$2E,$2E +000004r 1 2C 20 65 78 +000008r 1 69 74 69 6E +000010r 1 0D 0A 00 .byte $0D,$0A,$00 +000013r 1 +000013r 1 .segment "BSS" 000000r 1 000000r 1 _c: 000000r 1 00 00 .res 2,$00 @@ -243,20 +219,20 @@ Current file: kimGFX.s 00004Fr 1 20 rr rr jsr pushax 000052r 1 4C rr rr jmp L000F 000055r 1 4C rr rr L0002: jmp L0007 -000058r 1 AD rr rr L0005: lda _CursorX +000058r 1 AD rr rr L0005: lda _cursorX 00005Br 1 38 sec 00005Cr 1 E9 28 sbc #$28 -00005Er 1 8D rr rr sta _CursorX +00005Er 1 8D rr rr sta _cursorX 000061r 1 B0 03 bcs L0009 -000063r 1 CE rr rr dec _CursorX+1 -000066r 1 AE rr rr L0009: ldx _CursorX+1 -000069r 1 EE rr rr inc _CursorY +000063r 1 CE rr rr dec _cursorX+1 +000066r 1 AE rr rr L0009: ldx _cursorX+1 +000069r 1 EE rr rr inc _cursorY 00006Cr 1 D0 03 bne L000A -00006Er 1 EE rr rr inc _CursorY+1 -000071r 1 AD rr rr L000A: lda _CursorY -000074r 1 AE rr rr ldx _CursorY+1 -000077r 1 AD rr rr L0007: lda _CursorX -00007Ar 1 AE rr rr ldx _CursorX+1 +00006Er 1 EE rr rr inc _cursorY+1 +000071r 1 AD rr rr L000A: lda _cursorY +000074r 1 AE rr rr ldx _cursorY+1 +000077r 1 AD rr rr L0007: lda _cursorX +00007Ar 1 AE rr rr ldx _cursorX+1 00007Dr 1 C9 28 cmp #$28 00007Fr 1 8A txa 000080r 1 E9 00 sbc #$00 @@ -267,8 +243,8 @@ Current file: kimGFX.s 000089r 1 A2 00 ldx #$00 00008Br 1 2A rol a 00008Cr 1 D0 CA jne L0005 -00008Er 1 AD rr rr lda _CursorY -000091r 1 AE rr rr ldx _CursorY+1 +00008Er 1 AD rr rr lda _cursorY +000091r 1 AE rr rr ldx _cursorY+1 000094r 1 C9 19 cmp #$19 000096r 1 8A txa 000097r 1 E9 00 sbc #$00 @@ -282,8 +258,8 @@ Current file: kimGFX.s 0000A7r 1 rr 0000A8r 1 A2 00 ldx #$00 0000AAr 1 A9 18 lda #$18 -0000ACr 1 8D rr rr sta _CursorY -0000AFr 1 8E rr rr stx _CursorY+1 +0000ACr 1 8D rr rr sta _cursorY +0000AFr 1 8E rr rr stx _cursorY+1 0000B2r 1 20 rr rr jsr _ScrollScreen 0000B5r 1 A0 01 L000B: ldy #$01 0000B7r 1 20 rr rr jsr ldaxysp @@ -295,11 +271,11 @@ Current file: kimGFX.s 0000C8r 1 rr 0000C9r 1 A2 00 ldx #$00 0000CBr 1 A9 00 lda #$00 -0000CDr 1 8D rr rr sta _CursorX -0000D0r 1 8E rr rr stx _CursorX+1 -0000D3r 1 EE rr rr inc _CursorY +0000CDr 1 8D rr rr sta _cursorX +0000D0r 1 8E rr rr stx _cursorX+1 +0000D3r 1 EE rr rr inc _cursorY 0000D6r 1 D0 03 bne L000E -0000D8r 1 EE rr rr inc _CursorY+1 +0000D8r 1 EE rr rr inc _cursorY+1 0000DBr 1 A0 00 L000E: ldy #$00 0000DDr 1 A2 00 ldx #$00 0000DFr 1 A9 01 lda #$01 @@ -311,13 +287,13 @@ Current file: kimGFX.s 0000EEr 1 20 rr rr jsr ldauidx 0000F1r 1 8D rr rr sta _c 0000F4r 1 8E rr rr stx _c+1 -0000F7r 1 AE rr rr ldx _CursorX -0000FAr 1 AC rr rr ldy _CursorY +0000F7r 1 AE rr rr ldx _cursorX +0000FAr 1 AC rr rr ldy _cursorY 0000FDr 1 AD rr rr lda _c 000100r 1 20 rr rr jsr _DrawChar -000103r 1 EE rr rr inc _CursorX +000103r 1 EE rr rr inc _cursorX 000106r 1 D0 03 bne L0010 -000108r 1 EE rr rr inc _CursorX+1 +000108r 1 EE rr rr inc _cursorX+1 00010Br 1 A0 00 L0010: ldy #$00 00010Dr 1 A2 00 ldx #$00 00010Fr 1 A9 01 lda #$01 @@ -346,12 +322,12 @@ Current file: kimGFX.s 000127r 1 20 rr rr jsr pushax 00012Ar 1 A0 05 ldy #$05 00012Cr 1 20 rr rr jsr ldaxysp -00012Fr 1 8D rr rr sta _CursorX -000132r 1 8E rr rr stx _CursorX+1 +00012Fr 1 8D rr rr sta _cursorX +000132r 1 8E rr rr stx _cursorX+1 000135r 1 A0 03 ldy #$03 000137r 1 20 rr rr jsr ldaxysp -00013Ar 1 8D rr rr sta _CursorY -00013Dr 1 8E rr rr stx _CursorY+1 +00013Ar 1 8D rr rr sta _cursorY +00013Dr 1 8E rr rr stx _cursorY+1 000140r 1 A0 01 ldy #$01 000142r 1 20 rr rr jsr ldaxysp 000145r 1 20 rr rr jsr _DrawText @@ -776,79 +752,53 @@ Current file: kimGFX.s 0004D1r 1 0004D1r 1 20 rr rr jsr decsp2 0004D4r 1 20 rr rr jsr _ClearScreen -0004D7r 1 A2 00 ldx #$00 -0004D9r 1 A9 00 lda #$00 -0004DBr 1 20 rr rr jsr pushax -0004DEr 1 A2 00 ldx #$00 -0004E0r 1 A9 00 lda #$00 -0004E2r 1 20 rr rr jsr pushax -0004E5r 1 A9 rr lda #<(S0004) -0004E7r 1 A2 rr ldx #>(S0004) -0004E9r 1 20 rr rr jsr _DrawTextAt -0004ECr 1 A2 00 ldx #$00 -0004EEr 1 A9 00 lda #$00 -0004F0r 1 20 rr rr jsr pushax -0004F3r 1 A2 00 ldx #$00 -0004F5r 1 A9 02 lda #$02 -0004F7r 1 20 rr rr jsr pushax -0004FAr 1 A9 rr lda #<(S0005) -0004FCr 1 A2 rr ldx #>(S0005) -0004FEr 1 20 rr rr jsr _DrawTextAt -000501r 1 A2 00 ldx #$00 -000503r 1 A9 00 lda #$00 -000505r 1 20 rr rr jsr pushax -000508r 1 A2 00 ldx #$00 -00050Ar 1 A9 04 lda #$04 -00050Cr 1 20 rr rr jsr pushax -00050Fr 1 A9 rr lda #<(S0006) -000511r 1 A2 rr ldx #>(S0006) -000513r 1 20 rr rr jsr _DrawTextAt -000516r 1 A2 00 ldx #$00 -000518r 1 A9 05 lda #$05 -00051Ar 1 A0 00 ldy #$00 -00051Cr 1 20 rr rr jsr staxysp -00051Fr 1 A0 01 L0002: ldy #$01 -000521r 1 20 rr rr jsr ldaxysp -000524r 1 C9 50 cmp #$50 -000526r 1 8A txa -000527r 1 E9 00 sbc #$00 -000529r 1 50 02 bvc L0006 -00052Br 1 49 80 eor #$80 -00052Dr 1 0A L0006: asl a -00052Er 1 A9 00 lda #$00 -000530r 1 A2 00 ldx #$00 -000532r 1 2A rol a -000533r 1 F0 03 4C rr jne L0005 -000537r 1 rr -000538r 1 4C rr rr jmp L0003 -00053Br 1 A2 00 L0005: ldx #$00 -00053Dr 1 A9 A0 lda #$A0 -00053Fr 1 20 rr rr jsr pushax -000542r 1 A2 00 ldx #$00 -000544r 1 A9 78 lda #$78 -000546r 1 20 rr rr jsr pushax -000549r 1 A0 05 ldy #$05 -00054Br 1 20 rr rr jsr ldaxysp -00054Er 1 20 rr rr jsr pushax -000551r 1 A2 00 ldx #$00 -000553r 1 A9 01 lda #$01 -000555r 1 20 rr rr jsr _DrawCircleC -000558r 1 A0 00 ldy #$00 -00055Ar 1 A2 00 ldx #$00 -00055Cr 1 A9 05 lda #$05 -00055Er 1 20 rr rr jsr addeqysp -000561r 1 4C rr rr jmp L0002 -000564r 1 A9 rr L0003: lda #<(S0007) -000566r 1 A2 rr ldx #>(S0007) -000568r 1 20 rr rr jsr pushax -00056Br 1 A0 02 ldy #$02 -00056Dr 1 20 rr rr jsr _printf -000570r 1 A2 00 ldx #$00 -000572r 1 A9 00 lda #$00 -000574r 1 4C rr rr jmp L0001 -000577r 1 20 rr rr L0001: jsr incsp2 -00057Ar 1 60 rts -00057Br 1 -00057Br 1 .endproc -00057Br 1 -00057Br 1 +0004D7r 1 20 rr rr jsr _Demo +0004DAr 1 A2 00 ldx #$00 +0004DCr 1 A9 05 lda #$05 +0004DEr 1 A0 00 ldy #$00 +0004E0r 1 20 rr rr jsr staxysp +0004E3r 1 A0 01 L0002: ldy #$01 +0004E5r 1 20 rr rr jsr ldaxysp +0004E8r 1 C9 50 cmp #$50 +0004EAr 1 8A txa +0004EBr 1 E9 00 sbc #$00 +0004EDr 1 50 02 bvc L0006 +0004EFr 1 49 80 eor #$80 +0004F1r 1 0A L0006: asl a +0004F2r 1 A9 00 lda #$00 +0004F4r 1 A2 00 ldx #$00 +0004F6r 1 2A rol a +0004F7r 1 F0 03 4C rr jne L0005 +0004FBr 1 rr +0004FCr 1 4C rr rr jmp L0003 +0004FFr 1 A2 00 L0005: ldx #$00 +000501r 1 A9 A0 lda #$A0 +000503r 1 20 rr rr jsr pushax +000506r 1 A2 00 ldx #$00 +000508r 1 A9 78 lda #$78 +00050Ar 1 20 rr rr jsr pushax +00050Dr 1 A0 05 ldy #$05 +00050Fr 1 20 rr rr jsr ldaxysp +000512r 1 20 rr rr jsr pushax +000515r 1 A2 00 ldx #$00 +000517r 1 A9 01 lda #$01 +000519r 1 20 rr rr jsr _DrawCircleC +00051Cr 1 A0 00 ldy #$00 +00051Er 1 A2 00 ldx #$00 +000520r 1 A9 05 lda #$05 +000522r 1 20 rr rr jsr addeqysp +000525r 1 4C rr rr jmp L0002 +000528r 1 A9 rr L0003: lda #<(S0004) +00052Ar 1 A2 rr ldx #>(S0004) +00052Cr 1 20 rr rr jsr pushax +00052Fr 1 A0 02 ldy #$02 +000531r 1 20 rr rr jsr _printf +000534r 1 A2 00 ldx #$00 +000536r 1 A9 00 lda #$00 +000538r 1 4C rr rr jmp L0001 +00053Br 1 20 rr rr L0001: jsr incsp2 +00053Er 1 60 rts +00053Fr 1 +00053Fr 1 .endproc +00053Fr 1 +00053Fr 1 diff --git a/samples/kim1/subs.asm b/samples/kim1/subs.asm index c55e34fa7..4796f116b 100644 --- a/samples/kim1/subs.asm +++ b/samples/kim1/subs.asm @@ -20,6 +20,7 @@ .export _AscToPet .export _ReverseBits .export _DrawChar +.export _Demo .import _font8x8_basic @@ -59,6 +60,9 @@ _x1cord: .res 2 _x2cord: .res 2 _y1cord: .res 2 _y2cord: .res 2 +_cursorX: .res 1 +_cursorY: .res 1 +tempchar: .res 1 xval: .res 2 ; These could move to zeropage for perf, but presume we yval: .res 2 ; we want to minimize the amount we grow zero page use err: .res 2 @@ -71,6 +75,8 @@ y0: .res 2 .export _x2cord .export _y1cord .export _y2cord +.export _cursorX +.export _cursorY .segment "CODE" @@ -202,7 +208,12 @@ _ClearScreen: ; ScrollScreen - Scrolls the entire video memory (and thus the screen) up one row ;----------------------------------------------------------------------------------- -_ScrollScreen: +_ScrollScreen: pha + tya + pha + txa + pha + ; Load the source (A140) and destination (A000) addresses. Each row of characters ; occupies 320 bytes, so we start source as being one line ahead of the destination ; which will have the effect of scrolling the screen up one text line. @@ -235,6 +246,12 @@ _ScrollScreen: sta SCREEN+$1E00, y dey bne :- + + pla + txa + pla + tya + pla rts ;----------------------------------------------------------------------------------- @@ -617,50 +634,130 @@ ScreenLineAddresses: ;----------------------------------------------------------------------------------- ; 0 <= x < 40 ; 0 <= y < 25 +; Preserves all registers ;----------------------------------------------------------------------------------- _DrawChar: pha + tya ; Get the address in screen memory where this asl ; character X/Y cursor pos should be drawn tay txa clc adc ScreenLineAddresses, y - sta adp1_lo + sta dest_lo lda ScreenLineAddresses+1, y adc #0 - sta adp1_hi + sta dest_hi lda #0 ; Get the address in font memory where this - sta adp2_hi ; Petscii chracter lives (after conversion from + sta src_hi ; Petscii chracter lives (after conversion from + pla ; ascii) + + sty temp2 jsr _AscToPet + ldy temp2 + asl - rol adp2_hi + rol src_hi asl - rol adp2_hi + rol src_hi asl - rol adp2_hi + rol src_hi clc adc #<_font8x8_basic ; Add the base address of the font table to the offset - sta adp2_lo - lda adp2_hi + sta src_lo + lda src_hi adc #>_font8x8_basic - sta adp2_hi + sta src_hi ldy #0 ; opy the character def to the screen, one byte at a time ldx #0 -: lda (adp2), y ; Copy this byte from the character def to the screen target - sta (adp1, x) - lda adp1_lo ; Advance to the next "scanline", or pixel row, down +: lda (src), y ; Copy this byte from the character def to the screen target + sta (dest, x) + lda dest_lo ; Advance to the next "scanline", or pixel row, down clc adc #BYTESPERROW - sta adp1_hi + sta dest_hi iny cpy #8 bne :- + rts + + + +;----------------------------------------------------------------------------------- +; DrawText - Draws an ASCII string at the current cursor position +;----------------------------------------------------------------------------------- +; XY - Pointer to the string to draw, stops on NUL or 255 chars later +;----------------------------------------------------------------------------------- + +_DrawText: stx adp1_lo + sty adp1_hi + ldy #0 +@char: lda (adp1), y + sta tempchar + beq doneText + + lda _cursorX ; if X >= CHARSPERROW, we need to advance to the next line + cmp #CHARSPERROW-1 + bcc :+ + + lda #0 ; Back to the left edge + sta _cursorX + inc _cursorY ; Advance to the next line + +: lda _cursorY + cmp #ROWSPERCOLUMN - 1 ; Check to see if we've gone off the bottom of the screen + bcc :+ + + lda #ROWSPERCOLUMN - 1 ; If we have, we scroll the screen and back up to the last line again + sta _cursorY + jsr _ScrollScreen + +: lda tempchar ; If the character is 0A, we advance to the next line + cmp #$0a + bne :+ + + lda #0 ; Back to the left edge + sta _cursorX + inc _cursorY ; Advance to the next line + iny + bne @char + +: tya + pha + lda tempchar + ldx _cursorX + ldy _cursorY + jsr _DrawChar + pla + tay + + inc _cursorX + iny + bne @char + +doneText: rts + +demoText1: .byte " *** COMMODORE KIM-1 SHELL V0.1 ***", $0A, $0A + .byte " 60K RAM SYSTEM. 49152 BYTES FREE.", $0A, $0A + .byte "READY.", $0A, 00 + +_Demo: lda #0 + sta _cursorX + sta _cursorY + ldx #demoText1 + jsr _DrawText + rts + + + + diff --git a/samples/kim1/subs.o b/samples/kim1/subs.o index 18de07cca55be684b9b211b2ee4709e9b911c7e5..8c35b2213ce501c9d360d6ed97cfdb1f7478847a 100644 GIT binary patch literal 12938 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 U%kt3?j(jw$mvs49dONNE1AhprjsO4v literal 11504 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