Tuesday, April 30, 2024

Raster Interrupts for C64

 


The VIC II chip (video IC) that gives the C64 a lot of its characters (pun intended), includes registers to set up interrupts at certain raster lines.  This allows for video tricks.  Above the background color is changed in the middle of the screen, and changed back when in the borders before drawing the screen again.


This code was leveraged from my character editor source for c64.  That project needed to display multiple different character sets (from ROM and RAM) on the screen simultaneously.   And that is described at the bottom of an earlier blog post.

My approach was to launch Vice x64sc (Commodore 64 emulator) and utilize its built in monitor (ALT-H) to craft prototype code.  The listings following are what I came up with.   Then I used the clipboard to move to a source editor, added labels, and further refined to change from background colors to font changes.

Written by Dave VW 2024-04-27

*** NOTE THIS IS THE ROUGH DRAFT
*** SOURCE CODE AT GITHUB IS MUCH CLEANER
*** ASSEMBLY SOURCE INSTEAD OF MONITOR LISTING

This part was created in the monitor...

>C:c000  2c 19 d0 10  44 ea ad 19  d0 29 01 f0  3b 2c 00 c1
>C:c010  30 16 10 60  ea a9 00 8d  12 d0 ad 11  d0 29 7f 8d
>C:c020  11 d0 0e 00  c1 4c 3b c0  ce 21 d0 a9  a4 8d 12 d0
>C:c030  ad 11 d0 29  7f 8d 11 d0  4e 00 c1 a9  01 8d 19 d0
>C:c040  ea 68 a8 68  aa 68 40 00  ea 4c 31 ea  a9 40 8d 00
>C:c050  c1 78 a9 80  8d 12 d0 ad  11 d0 29 7f  8d 11 d0 a9
>C:c060  00 8d 14 03  a9 c0 8d 15  03 ad 1a d0  09 01 8d 1a
>C:c070  d0 58 60 00  ad 12 d0 c9  c2 90 f9 a2  0a ca d0 fd
>C:c080  ee 21 d0 4c  15 c0                                

.C:c000  2C 19 D0    BIT $D019
.C:c003  10 44       BPL $C049
.C:c005  EA          NOP
.C:c006  AD 19 D0    LDA $D019
.C:c009  29 01       AND #$01
.C:c00b  F0 3B       BEQ $C048
.C:c00d  2C 00 C1    BIT $C100
.C:c010  30 16       BMI $C028
.C:c012  10 60       BPL $C074
.C:c014  EA          NOP
.C:c015  A9 00       LDA #$00
.C:c017  8D 12 D0    STA $D012
.C:c01a  AD 11 D0    LDA $D011
.C:c01d  29 7F       AND #$7F
.C:c01f  8D 11 D0    STA $D011
.C:c022  0E 00 C1    ASL $C100
.C:c025  4C 3B C0    JMP $C03B
.C:c028  CE 21 D0    DEC $D021
.C:c02b  A9 A4       LDA #$A4
.C:c02d  8D 12 D0    STA $D012
.C:c030  AD 11 D0    LDA $D011
.C:c033  29 7F       AND #$7F
.C:c035  8D 11 D0    STA $D011
.C:c038  4E 00 C1    LSR $C100
.C:c03b  A9 01       LDA #$01
.C:c03d  8D 19 D0    STA $D019
.C:c040  EA          NOP
.C:c041  68          PLA
.C:c042  A8          TAY
.C:c043  68          PLA
.C:c044  AA          TAX
.C:c045  68          PLA
.C:c046  40          RTI
.C:c047  00          BRK
.C:c048  EA          NOP
.C:c049  4C 31 EA    JMP $EA31
.C:c04c  A9 40       LDA #$40
.C:c04e  8D 00 C1    STA $C100
.C:c051  78          SEI
.C:c052  A9 80       LDA #$80
.C:c054  8D 12 D0    STA $D012
.C:c057  AD 11 D0    LDA $D011
.C:c05a  29 7F       AND #$7F
.C:c05c  8D 11 D0    STA $D011
.C:c05f  A9 00       LDA #$00
.C:c061  8D 14 03    STA $0314
.C:c064  A9 C0       LDA #$C0
.C:c066  8D 15 03    STA $0315
.C:c069  AD 1A D0    LDA $D01A
.C:c06c  09 01       ORA #$01
.C:c06e  8D 1A D0    STA $D01A
.C:c071  58          CLI
.C:c072  60          RTS
.C:c073  00          BRK
.C:c074  AD 12 D0    LDA $D012
.C:c077  C9 C2       CMP #$C2
.C:c079  90 F9       BCC $C074
.C:c07b  A2 0A       LDX #$0A
.C:c07d  CA          DEX
.C:c07e  D0 FD       BNE $C07D
.C:c080  EE 21 D0    INC $D021
.C:c083  4C 15 C0    JMP $C015

The initialization routine is at $c04c to install the new IRQ handler $c000.  The code jumps around a bit and has NOP (no instruction) as a by-product of patching the source in the monitor to get the desired functionality.   This is cleaned up a lot more in the sources to both repos.

Monday, April 29, 2024

MLX II Listing for C64 Character Sets Editor


Shown with 80s theme colors (key: 6)

Back in the day we would enter program listings from magazines.  That's how we got new utility and game software on a monthly basis.  It was a fun activity in front of my Commodore Vic-20 on Saturdays.

For nostalgia, and retro vibes, you can repeat the process to get this character editor program.   It's online elsewhere and pointed to in this blog, but if you have an air gapped C64, you can enter directly.

Note: Floppy drive 8 is required for loading/saving fonts and theme configuration.  This program does not support tape drives or alternate floppy drives.  So be prepared with a floppy drive 8 such as 1541, 1571, 1581.

Please enter the hex listing below using Compute's Gazette MLX II which includes a ninth checksum byte at the end of each line.  MLX will stop you from continuing if the checksum doesn't match it's internal algorithm.

e.g. I test entered using 64 MLX from Compute's Gazette disk from November 1993 

start:  0801
finish: 24b8

0801:0b 18 0a 00 9e 36 31 35 43
0809:37 00 00 00 00 00 00 00 b4

(gap of zeros or unused, use STOP+RESTORE if get stuck)

1800:00 0b 18 0a 00 9e 36 31 ae
1808:35 37 00 00 00 20 17 1f 6e
1810:18 66 a6 18 6e b1 24 a9 68
1818:00 85 22 a9 08 85 23 20 45
1820:a3 20 ad 18 d0 29 f0 8d fb
1828:b3 24 09 04 8d b4 24 20 44
1830:97 21 20 2b 20 a5 2c c9 e4
1838:18 f0 36 a9 01 a2 18 85 5a
1840:2b 86 2c a9 00 85 fb 85 5b
1848:fd a9 08 85 fc a2 d0 86 d5
1850:fe a9 10 85 ff a0 00 78 bf
1858:20 63 1f b1 fd 91 fb c8 67
1860:d0 f9 e6 fc e6 fe c6 ff e4
1868:d0 f1 20 5c 1f 58 20 7c 5e
1870:1f a9 93 20 d2 ff a9 13 0c
1878:20 d2 ff 2c b1 24 30 44 f2
1880:a9 a1 a2 22 20 8e 1d a9 83
1888:30 a2 23 85 b4 86 b5 20 81
1890:9f 1d 20 cc 1e a9 30 85 26
1898:fd a9 08 85 ff a9 be a2 52
18a0:23 20 8e 1d a5 fd 20 d2 46
18a8:ff a9 b3 a2 23 20 8e 1d b7
18b0:a9 20 20 d2 ff 20 9f 1d cb
18b8:e6 fd c6 ff d0 df 20 db d6
18c0:20 20 9f 1d 20 e1 1e a9 3d
18c8:00 85 27 a9 00 85 28 a9 e9
18d0:38 a2 04 85 29 86 2a a2 f8
18d8:d8 85 b2 86 b3 18 a5 a2 81
18e0:69 04 85 a3 20 b9 1d a0 74
18e8:00 b1 29 85 a7 ad 18 d0 f7
18f0:29 fe c9 10 d0 05 a9 12 af
18f8:8d 18 d0 20 8b 1e 20 e4 0c
1900:ff f0 ea 48 20 bb 1e 68 e4
1908:c9 4e d0 19 20 17 1f a5 9f
1910:22 69 07 85 22 90 c6 e6 ae
1918:23 a5 23 c9 10 90 be a9 30
1920:08 85 23 d0 b8 c9 2b d0 3d
1928:19 20 17 1f a5 22 69 7f cb
1930:85 22 90 a9 e6 23 a5 23 8c
1938:c9 10 90 a1 a9 08 85 23 1b
1940:d0 9b c9 42 d0 1a 20 17 65
1948:1f a5 22 e9 08 85 22 b0 a1
1950:8c c6 23 a5 23 c9 08 b0 3a
1958:84 a9 0f 85 23 4c dd 18 8f
1960:c9 2d d0 1a 20 17 1f a5 bf
1968:22 e9 80 85 22 b0 0c c6 41
1970:23 a5 23 c9 08 b0 04 a9 53
1978:0f 85 23 4c dd 18 c9 11 b0
1980:d0 31 a5 29 69 27 85 29 ca
1988:85 b2 90 05 e6 2a e6 b3 ed
1990:18 a5 28 69 01 29 07 85 14
1998:28 d0 15 38 a5 29 e9 40 1f
19a0:85 29 85 b2 a5 2a e9 01 66
19a8:85 2a a5 b3 e9 01 85 b3 2a
19b0:4c e7 18 c9 91 d0 33 a5 7e
19b8:29 e9 28 85 29 85 b2 b0 cc
19c0:05 c6 2a c6 b3 38 a5 28 ca
19c8:e9 01 29 07 85 28 c9 07 2d
19d0:d0 15 18 a5 29 69 40 85 03
19d8:29 85 b2 a5 2a 69 01 85 30
19e0:2a a5 b3 69 01 85 b3 4c 70
19e8:e7 18 c9 1d d0 1e e6 29 16
19f0:e6 b2 a5 27 69 00 85 27 e7
19f8:29 07 d0 0d 38 a5 29 e9 01
1a00:08 85 29 85 b2 a9 00 85 d8
1a08:27 4c e7 18 c9 9d d0 18 df
1a10:c6 29 c6 b2 c6 27 10 0d f5
1a18:18 a5 29 69 08 85 29 85 ab
1a20:b2 a9 07 85 27 4c e7 18 a3
1a28:c9 13 d0 17 a9 00 85 27 11
1a30:85 28 a9 38 85 29 85 b2 78
1a38:a9 04 85 2a a9 d8 85 b3 05
1a40:4c e7 18 c9 20 d0 11 20 ba
1a48:1e 1f a6 27 a4 28 b1 22 e5
1a50:5d 91 22 91 22 4c dd 18 0b
1a58:c9 03 d0 1b 20 f1 21 ad b6
1a60:b5 24 8d 18 d0 18 4e b1 e0
1a68:24 a9 d4 a2 23 20 8e 1d b1
1a70:20 cc 1e 20 e1 1e 60 c9 bf
1a78:53 d0 49 20 80 20 a9 93 21
1a80:20 d2 ff a9 0a 85 39 a9 96
1a88:00 85 3a a9 c0 85 9d a9 01
1a90:01 a2 08 a0 0f 20 ba ff 67
1a98:a9 0b a2 d6 a0 23 20 bd b5
1aa0:ff a9 00 85 fb a9 08 85 b3
1aa8:fc a9 fb a2 00 a0 18 20 42
1ab0:d8 ff a9 ec a2 23 20 8e c5
1ab8:1d 20 e4 ff f0 fb 20 96 6e
1ac0:20 4c 71 18 c9 93 d0 0f 15
1ac8:20 1e 1f a9 00 a0 07 91 35
1ad0:22 88 10 fb 4c dd 18 c9 cd
1ad8:12 d0 11 20 1e 1f a0 07 24
1ae0:b1 22 49 ff 91 22 88 10 d5
1ae8:f7 4c dd 18 c9 3c d0 10 5a
1af0:20 1e 1f a0 07 b1 22 0a f7
1af8:91 22 88 10 f8 4c dd 18 5d
1b00:c9 3e d0 10 20 1e 1f a0 1e
1b08:07 b1 22 4a 91 22 88 10 4d
1b10:f8 4c dd 18 c9 d6 d0 16 74
1b18:20 1e 1f a0 07 88 b1 22 b3
1b20:c8 91 22 88 10 f7 c8 a9 87
1b28:00 91 22 4c dd 18 c9 5e 0d
1b30:d0 18 20 1e 1f a2 07 a0 ec
1b38:00 c8 b1 22 88 91 22 c8 90
1b40:ca d0 f6 a9 00 91 22 4c 60
1b48:dd 18 c9 46 d0 25 20 1e 8a
1b50:1f a0 03 84 ff c8 84 fe 12
1b58:a4 ff b1 22 48 a4 fe b1 bd
1b60:22 aa 68 91 22 a4 ff 8a a6
1b68:91 22 e6 fe c6 ff 10 e8 fb
1b70:4c dd 18 c9 52 d0 25 20 24
1b78:1e 1f a0 00 a2 00 b1 22 34
1b80:0a 91 22 76 a8 e8 e0 08 7e
1b88:d0 f4 c8 c0 08 d0 ed a0 89
1b90:07 b9 a8 00 91 22 88 10 04
1b98:f8 4c dd 18 c9 4d d0 26 e6
1ba0:20 1e 1f a0 07 a2 07 b1 de
1ba8:22 4a 91 22 b9 a8 00 2a 71
1bb0:99 a8 00 ca 10 f1 88 10 f3
1bb8:ec a0 07 b9 a8 00 91 22 94
1bc0:88 10 f8 4c dd 18 c9 40 46
1bc8:d0 14 ad b5 24 cd b4 24 63
1bd0:f0 06 20 74 20 4c ed 18 72
1bd8:20 62 20 4c ed 18 c9 2a 0e
1be0:d0 2d ad aa 24 ae ad 24 86
1be8:ac af 24 8e aa 24 8c ad 7b
1bf0:24 8d af 24 ad a9 24 ae df
1bf8:ac 24 ac ae 24 8e a9 24 e1
1c00:8c ac 24 8d ae 24 20 a3 f0
1c08:20 20 cc 20 4c dd 18 c9 c7
1c10:5a d0 24 a6 a4 f0 1d a5 61
1c18:a5 d0 07 20 1e 1f c6 a4 d9
1c20:a6 a4 e6 a5 ca 86 a4 8a 50
1c28:20 4c 1f a0 07 b1 fb 91 f9
1c30:22 88 10 f9 4c dd 18 c9 11
1c38:43 d0 0f a0 07 b1 22 99 0f
1c40:51 02 88 10 f8 84 a6 4c 27
1c48:ed 18 c9 56 d0 14 24 a6 e1
1c50:10 0d 20 1e 1f a0 07 b9 fc
1c58:51 02 91 22 88 10 f8 4c d0
1c60:dd 18 c9 58 d0 16 20 1e 89
1c68:1f a0 07 b1 22 99 51 02 70
1c70:a9 00 91 22 88 10 f4 84 c4
1c78:a6 4c dd 18 c9 59 d0 0d b6
1c80:a5 a5 f0 09 c6 a5 e6 a4 e2
1c88:a6 a4 4c 27 1c c9 2f d0 70
1c90:32 20 17 1f a9 00 a2 08 59
1c98:85 fb 86 fc a2 10 85 fd 91
1ca0:86 fe a2 08 86 ff a0 00 26
1ca8:b1 fb aa b1 fd 91 fb 8a e1
1cb0:91 fd c8 d0 f3 e6 fc e6 73
1cb8:fe c6 ff d0 eb 20 7c 1f 27
1cc0:4c dd 18 c9 85 d0 16 ee c0
1cc8:86 02 ad 86 02 4d 21 d0 3b
1cd0:29 0f f0 f3 20 cc 1e 20 4f
1cd8:b9 1d 4c ed 18 c9 89 d0 69
1ce0:1b 18 ad a8 24 69 01 29 de
1ce8:0f 8d a8 24 ad 21 d0 4d 44
1cf0:a8 24 29 0f f0 eb 20 b9 cd
1cf8:1d 4c ed 18 c9 86 d0 10 2c
1d00:ee 21 d0 ad 21 d0 4d 86 5c
1d08:02 29 0f f0 f3 4c ed 18 43
1d10:c9 8a d0 10 ce 21 d0 ad 37
1d18:21 d0 4d 86 02 29 0f f0 ec
1d20:f3 4c ed 18 c9 87 d0 06 ba
1d28:ee 20 d0 4c ed 18 c9 8b af
1d30:d0 06 ce 20 d0 4c 38 1d 75
1d38:c9 88 d0 1b 18 ad a7 24 30
1d40:69 01 29 0f 8d a7 24 ad 86
1d48:21 d0 4d a7 24 29 0f f0 40
1d50:eb 20 b9 1d 4c ed 18 c9 a5
1d58:8c d0 11 18 ad a6 24 69 6a
1d60:01 29 0f 8d a6 24 20 b9 df
1d68:1d 4c ed 18 c9 48 d0 0b 9f
1d70:ad b1 24 49 80 8d b1 24 c8
1d78:4c 71 18 c9 30 90 0c c9 7a
1d80:3a b0 08 29 0f 20 eb 20 88
1d88:4c 76 18 4c ed 18 85 fb 25
1d90:86 fc a0 00 b1 fb f0 06 c6
1d98:20 d2 ff c8 d0 f6 60 a9 f0
1da0:cf a2 23 20 8e 1d a5 b4 ba
1da8:a6 b5 20 8e 1d c8 98 18 e5
1db0:65 b4 85 b4 90 02 e6 b5 d6
1db8:60 a9 38 a2 04 85 24 86 c3
1dc0:25 a2 d8 85 b0 86 b1 a9 56
1dc8:08 85 ff a0 00 a2 08 b1 be
1dd0:22 85 26 ad a6 24 91 b0 b6
1dd8:ad a9 24 06 26 90 08 ad 6a
1de0:a7 24 91 b0 ad aa 24 91 27
1de8:24 e6 24 e6 b0 d0 04 e6 99
1df0:25 e6 b1 ca d0 dd 18 a5 2e
1df8:24 69 1f 85 24 85 b0 90 05
1e00:04 e6 25 e6 b1 c8 c6 ff 49
1e08:d0 c3 2c b1 24 10 03 4c f1
1e10:e1 1e 20 6c 1f a2 19 86 cb
1e18:24 86 b0 a2 04 86 25 a2 6f
1e20:d8 86 b1 38 66 ff a0 00 98
1e28:20 65 1e e6 24 e6 b0 d0 ee
1e30:04 e6 25 e6 b1 18 66 ff f5
1e38:a2 08 18 a5 24 69 25 85 bb
1e40:24 85 b0 90 04 e6 25 e6 fb
1e48:b1 ad ab 24 2c b0 24 30 1d
1e50:02 a9 e5 91 24 e6 24 d0 a3
1e58:02 e6 25 b1 22 20 65 1e 89
1e60:c8 ca d0 d6 60 48 4a 4a 3e
1e68:4a 4a 20 7a 1e e6 24 e6 c3
1e70:b0 d0 04 e6 25 e6 b1 68 b8
1e78:29 0f 09 30 c9 3a 90 02 8b
1e80:e9 39 24 ff 10 02 09 80 9f
1e88:91 24 60 38 a5 a3 c5 a2 10
1e90:d0 28 a5 a2 69 1d 85 a3 8c
1e98:a0 00 ad a7 24 2c b0 24 ac
1ea0:10 0c b1 29 49 80 91 29 49
1ea8:ad a8 24 91 b2 60 b1 b2 b0
1eb0:29 0f cd a8 24 d0 f1 20 f1
1eb8:b4 20 60 a0 00 a5 a7 91 e4
1ec0:29 20 b4 20 18 a5 a2 69 38
1ec8:02 85 a3 60 a0 00 ad 86 c8
1ed0:02 99 00 d8 99 00 d9 99 1c
1ed8:00 da 99 00 db c8 d0 f1 94
1ee0:60 a9 b8 a2 05 85 fb 86 b5
1ee8:fc 2c b1 24 10 10 a0 00 29
1ef0:a9 20 91 fb c8 d0 fb 20 9d
1ef8:6c 1f a8 91 fb 60 20 0e 11
1f00:1f 2c b1 24 30 10 a9 d0 37
1f08:a2 06 85 fb 86 fc a0 00 f2
1f10:98 91 fb c8 d0 fa 60 a9 e7
1f18:00 85 a4 85 a5 60 a5 a4 43
1f20:c9 18 90 15 a2 00 a0 08 0b
1f28:b9 3c 03 9d 3c 03 e8 c8 15
1f30:c0 c4 d0 f4 a2 17 86 a4 8c
1f38:8a 20 4c 1f a0 07 b1 22 e5
1f40:91 fb 88 10 f9 e6 a4 c8 d5
1f48:84 a5 18 60 0a 0a 0a 18 df
1f50:69 3c 85 fb a2 03 90 01 06
1f58:e8 86 fc 60 a5 01 09 07 9c
1f60:85 01 60 a5 01 29 f8 09 af
1f68:03 85 01 60 a5 23 85 ff 74
1f70:a5 22 46 ff 6a 46 ff 6a a9
1f78:46 ff 6a 60 a9 00 a2 10 cf
1f80:85 fb 86 fc a2 38 85 fd 20
1f88:86 fe a2 08 86 ff a0 00 14
1f90:b1 fb 91 fd c8 d0 f9 e6 1d
1f98:fc e6 fe c6 ff d0 f1 60 e2
1fa0:2c 19 d0 30 03 4c 31 ea ee
1fa8:ad 19 d0 29 01 f0 f6 ad 18
1fb0:b2 24 10 2a ad 12 d0 c9 17
1fb8:c2 90 f9 a2 0a ca d0 fd 01
1fc0:ad b6 24 8d 18 d0 a9 00 38
1fc8:8d 12 d0 8d b2 24 ad 11 d7
1fd0:d0 29 7f 8d 11 d0 a9 01 aa
1fd8:8d 19 d0 4c 25 20 f0 2a b8
1fe0:ad 12 d0 c9 8a 90 f9 a2 5e
1fe8:0a ca d0 fd ad b5 24 8d f2
1ff0:18 d0 a9 a4 8d 12 d0 8d d2
1ff8:b2 24 ad 11 d0 29 7f 8d 18
2000:11 d0 a9 01 8d 19 d0 4c 01
2008:25 20 ad b4 24 8d 18 d0 3c
2010:a9 68 8d 12 d0 8d b2 24 58
2018:ad 11 d0 29 7f 8d 11 d0 45
2020:a9 01 8d 19 d0 68 a8 68 9a
2028:aa 68 40 78 a9 00 8d b2 82
2030:24 a9 00 8d 12 d0 ad 11 06
2038:d0 29 7f 8d 11 d0 ad 14 2f
2040:03 ae 15 03 e0 1f f0 10 f5
2048:8d a6 1f 8e a7 1f a9 a0 73
2050:a2 1f 8d 14 03 8e 15 03 1c
2058:ad 1a d0 09 01 8d 1a d0 e3
2060:58 60 ad b4 24 29 f0 09 96
2068:02 8d b5 24 29 f0 09 0e 33
2070:8d b6 24 60 ad b4 24 8d c5
2078:b5 24 09 02 8d b6 24 60 cd
2080:ad b5 24 8d b7 24 ad b6 c2
2088:24 8d b8 24 ad b4 24 8d ad
2090:b5 24 8d b6 24 60 ad b7 87
2098:24 8d b5 24 ad b8 24 8d 6d
20a0:b6 24 60 a9 80 8d b0 24 ab
20a8:ad aa 24 cd a9 24 d0 03 4e
20b0:4e b0 24 60 a4 28 b1 22 1a
20b8:a6 27 3d 91 22 c9 01 ad be
20c0:a6 24 90 03 ad a7 24 a0 94
20c8:00 91 b2 60 a9 24 a2 23 10
20d0:20 8e 1d 20 db 20 a9 92 af
20d8:4c d2 ff a9 ee a2 22 2c 01
20e0:b0 24 30 04 a9 09 a2 23 a2
20e8:4c 8e 1d c9 00 d0 02 a9 24
20f0:0a c9 0b 90 01 60 a8 a9 97
20f8:49 a2 24 85 fb 86 fc 88 df
2100:f0 0f 18 a5 fb 69 09 85 f8
2108:fb a5 fc 69 00 85 fc d0 c8
2110:ee a0 00 b1 fb 8d 86 02 32
2118:c8 b1 fb 8d 21 d0 c8 b1 13
2120:fb 8d 20 d0 c8 b1 fb 8d 67
2128:a6 24 c8 b1 fb 8d a7 24 84
2130:c8 b1 fb 8d a8 24 c8 b1 b4
2138:fb 8d a9 24 c8 b1 fb 8d e5
2140:aa 24 c8 b1 fb 8d ab 24 a6
2148:20 a3 20 20 cc 1e 4c 51 52
2150:21 ad aa 24 c9 a0 d0 13 ab
2158:a9 20 8d ac 24 a9 2a 8d 9d
2160:ad 24 a9 cf 8d ae 24 8d b1
2168:af 24 60 c9 2a d0 13 a9 98
2170:cf 8d ac 24 8d ad 24 a9 ea
2178:20 8d ae 24 a9 a0 8d af e0
2180:24 60 a9 20 8d ac 24 a9 35
2188:a0 8d ad 24 a9 20 8d ae 0e
2190:24 a9 2a 8d af 24 60 a9 e5
2198:fe a2 23 20 8e 1d 20 6d ff
21a0:22 d0 4d a9 0a 85 39 a9 ee
21a8:00 85 3a a9 c0 85 9d a9 2f
21b0:01 a2 08 a0 00 20 ba ff 1d
21b8:a9 08 a2 e4 a0 23 20 bd 04
21c0:ff a9 00 a2 b9 a0 24 20 50
21c8:d5 ff a2 09 a0 00 b9 b9 0d
21d0:24 99 a3 24 c8 ca d0 f6 4c
21d8:ad a3 24 ae a4 24 ac a5 fe
21e0:24 8d 86 02 8e 21 d0 8c b0
21e8:20 d0 20 a3 20 20 51 21 f2
21f0:60 ad 86 02 29 0f 8d a3 04
21f8:24 ad 21 d0 29 0f 8d a4 2f
2200:24 ad 20 d0 29 0f 8d a5 19
2208:24 20 5c 22 f0 4d 20 80 91
2210:20 a9 1f a2 24 20 8e 1d b8
2218:20 6d 22 d0 3e a9 0a 85 4b
2220:39 a9 00 85 3a a9 c0 85 43
2228:9d a9 01 a2 08 a0 0f 20 f0
2230:ba ff a9 0b a2 e1 a0 23 b8
2238:20 bd ff a9 a3 85 fb a9 6b
2240:24 85 fc a9 fb a2 ac a0 96
2248:24 20 d8 ff a9 ec a2 23 2b
2250:20 8e 1d 20 e4 ff f0 fb f2
2258:20 96 20 60 a2 09 a0 00 d6
2260:b9 b9 24 d9 a3 24 d0 04 65
2268:c8 ca d0 f4 60 20 e4 ff 7a
2270:f0 fb c9 4e d0 0b a9 45 95
2278:a2 24 20 8e 1d a9 01 d0 66
2280:0f c9 59 f0 04 c9 0d d0 2b
2288:e4 a9 40 a2 24 20 8e 1d b7
2290:60 80 40 20 10 08 04 02 d9
2298:01 7f cf df ef f7 fc fd 8c
22a0:fe 0d 20 12 20 20 43 48 1d
22a8:36 34 45 44 49 54 20 20 fd
22b0:0d 20 12 20 20 28 43 29 19
22b8:20 32 30 32 34 20 20 0d 32
22c0:20 12 20 20 44 41 56 49 bc
22c8:44 20 52 2e 20 20 0d 20 20
22d0:12 20 56 41 4e 20 57 41 e7
22d8:47 4e 45 52 20 0d 20 12 a9
22e0:20 44 41 56 45 56 57 2e 34
22e8:43 4f 4d 20 0d 13 20 20 63
22f0:20 20 20 20 20 20 20 20 35
22f8:20 20 20 20 20 12 20 37 1c
2300:36 35 34 33 32 31 30 20 3f
2308:00 20 20 20 20 20 20 20 3e
2310:20 20 20 20 20 20 20 20 56
2318:12 20 a3 a3 a3 a3 a3 a3 b4
2320:a3 a3 20 00 13 92 11 11 3b
2328:11 11 11 11 11 11 11 00 5d
2330:0d 00 12 40 2d 2b 2a 2f dc
2338:59 5a 58 43 56 0d 00 12 f9
2340:42 92 41 43 4b 20 12 52 f9
2348:92 4f 54 41 54 45 0d 00 1c
2350:12 4e 92 45 58 54 20 12 40
2358:4d 92 49 52 52 4f 52 0d b9
2360:00 12 3c 3e 5e 56 92 20 28
2368:12 46 92 4c 49 50 0d 00 06
2370:12 46 31 92 2d 12 46 38 17
2378:92 20 12 30 2d 39 0d 00 bd
2380:12 48 4f 4d 45 92 20 12 67
2388:43 4c 52 0d 00 12 52 56 e1
2390:53 92 20 20 12 53 50 41 ea
2398:43 45 0d 00 12 53 54 4f 49
23a0:50 92 20 12 53 92 41 56 96
23a8:45 0d 00 12 48 92 49 44 59
23b0:45 0d 00 92 20 20 20 20 e7
23b8:20 20 20 20 12 00 1d 1d 05
23c0:1d 1d 1d 1d 1d 1d 1d 1d 07
23c8:1d 1d 1d 1d 1d 12 00 92 1e
23d0:20 20 20 00 93 00 40 30 80
23d8:3a 46 4f 4e 54 2e 42 49 c5
23e0:4e 40 30 3a 46 4f 4e 54 68
23e8:2e 43 46 47 0d 0d 12 50 65
23f0:52 45 53 53 20 41 4e 59 4d
23f8:20 4b 45 59 0d 00 93 0d fc
2400:4c 4f 41 44 20 43 4f 4e a9
2408:46 49 47 55 52 41 54 49 8d
2410:4f 4e 20 28 59 2f 4e 29 67
2418:3f 20 12 59 92 9d 00 93 7e
2420:0d 53 41 56 45 20 43 4f d1
2428:4e 46 49 47 55 52 41 54 91
2430:49 4f 4e 20 28 59 2f 4e 10
2438:29 3f 20 12 59 92 9d 00 5a
2440:59 45 53 0d 00 4e 4f 0d a6
2448:00 0e 06 0e 0e 00 01 20 48
2450:a0 a0 01 00 0f 00 01 0b b6
2458:cf cf a0 05 00 00 00 05 e5
2460:05 20 2a a0 06 01 03 0f cb
2468:00 03 cf cf a0 00 0b 0c 8f
2470:0f 00 0e cf cf a0 0d 06 20
2478:08 07 02 04 cf cf a0 0b 11
2480:00 08 0f 08 09 20 a0 a0 d7
2488:0d 0b 0d 0c 00 04 20 a0 6d
2490:a0 00 01 0e 0f 0e 05 cf b4
2498:cf a0 0e 00 00 00 0b 06 ce
24a0:20 a0 a0 00 00 00 0e 00 51
24a8:01 20 a0 a0 20 2a cf cf b0
24b0:80 00 00 10 14 12 1e 00 5f
24b8:00 00 00 00 00 00 00 00 01

Friday, April 19, 2024

Edit Programmable Characters on Vic-20 and C64

 



The current release is considered fully functional and complete.

Links:

Vic-20 D64 (1541 image) and source

Commodore 64 D64 (1541 image) and source

The Commodore Vic-20 video chip added multiple features beyond what the original PET Model 2001 offered.  Besides color support, it also includes the ability to change to user defined character sets.  These can be used to customize the look and feel of a program, and also to provide bitmapped graphics.

Back in the 80s I was proud of my development of a character editor program that utilized a few machine language routines to perform quick operations via keyboard selections.   Unfortunately I don't have direct access to that program today (haven't been able to read the tape back into the computer yet).  So I decided to rewrite it again.

This time it is purely 6502 assembly code.  I started using the VICE monitor to write the initial functionality, and soon afterwards transitioned to ACME source to ease edits and additions.

After mocking up the look of the screen, identifying operations that would be nice to have, and testing out memory layout and configuring the video chip to use character images from RAM, I got to work.


1. Initial screen layout including editor and commands.

2. Navigation of character selection, displaying bit patterns for editing to screen, and displaying hex character value and byte values.

3. Editing the pixels in a single character.

4. Saving font to floppy disk.

5. Continuing to iterate with new features and enhancements


Description of key operations

pressing a key on the keyboard as shown below will perform an operation:


@ - toggle between RAM/ROM character sets

SPACE - toggle pixel on/off

B - navigate back one character

C - copy

F - flip upside down

M - mirror the image left to right, right to left

N - navigate forward to next character

R - rotate 90 degress to the right

S - save to FONT.BIN (WARNING: overwrites any previous saves)

V - paste

X - cut

Y - redo

Z - undo

- minus - navigate 16 characters back

+ plus - navigate 16 characters forward

< > - shift pixels left/right

↑ - shift pixels up (^ carrat on PC)

Shift V - shift pixels down

CLR - erase all pixels

CURSOR keys - move cursor left/right/up/down

HOME - move cursor to upper left position

RVS - inverse the pixels

STOP - exit (usually mapped to ESC on PC)


There are up to 24 levels of undo [Z] (25 levels of redo [Y]) when editing a character.  Navigating will clear the undos/redos.   And there is a virtual clipboard which you can copy[C]/cut[X]/paste[V] a single character.   Note in this program you do not use the Ctrl key for clipboard as you do on a PC.

Notes:

  • When launching the program for the first time, the ROM font will be copied to RAM, including moving the start of programs up to $1800 past the RAM characters.   Subsequent runs from that address will not recopy from ROM.  If you want to restart fresh from ROM, either reset your computer and run again, or POKE 44,16:SYS 6157.  You don't have to memorize the entry point, you can also LIST the line of BASIC that calls into the entry point.
  • Saving overwrites FONT.BIN.  So if you want to save your work permanently, it is recommended to rename your file to something else.
    OPEN 15,8,15,"R0:COOL=FONT.BIN":CLOSE 15
  • To LOAD your font for editing, be sure to run the program at least once, then load before running to enter back into edit mode.  Be sure to include the ,1 otherwise you will wipe the font editor out of memory, then best to restart your Commodore and try again.
    LOAD "COOL",8,1
  • Pressing COMMODORE+SHIFT while in programmable characters will shift to a second set of characters which we don't have room for in RAM, so you will see bitmapped images of the program and video memory.   Press the key combination again to return to the first set of characters. [Disabled in the C64 port]

Update 2024 April 20: also ported to Commodore 64

Update 2024 April 26: more documentation

Description of key operations since added to Commodore 64 version

H - hide UI except pixels and character for a minimalist experience

/ - swap between two RAM character sets (C64 version edits total of 512 characters) 

F1 - foreground color

F2 - cursor color 

F3 - background color

F4 - character set 1 color

F5 - border color

F6 - character set 2 color

F7 - large pixel set color (editor)

F8 - large pixel cleared color (editor)

, - change titles color

. - change menus color

1,2,3,4,5,6,7,8,9,0 - select theme (colors and grid mode)

 As the C64 has a different memory layout, video memory is at a lower address $0400 and more memory available, the memory map is a bit different.  The start of the program is still at $1800, but the programmable characters are now from $0800 to $17FF, a full 4K (512 characters). 

Note that only the first character set (256 characters) is visible at this address without moving the character set to another location (planned for future).  But the editor can handle this by swapping the character sets in RAM for editing, swapping them back and forth, so one set is always edited from the lower $0800-$0FFF range that is visible.  Just be sure to swap back to the first set before saving, otherwise the character sets will be out of order.

To use both character sets in your own programs, it is necessary to manually relocate them or load them at another address, unless you use the swapping technique used by the editor.

It is not presently possible to use raster interrupts to show both sets because the second set is at an address that is mapped to ROM characters instead.  Another reason it is planned to move these in the future, for example to $3000-$3FFF but in the middle of BASIC RAM it may be too challenging to be useful to others.

Probably a better solution is to move both VIC-II memory to another bank of 16K, which also requires moving video memory.   Say bank 4 with characters at $F000-$FFFF, and video ram at $CC00-$CFFF.  Then move the start of BASIC to $0400, resulting in 39933 (39K) bytes available for BASIC, an increase of 1K the size of the video screen memory.

Leaving the editor, you have lost 4K of RAM from BASIC.  To reclaim 2K for the not visible second character set, POKE 44, 20: POKE 20*256, 0: NEW but don't load any of your double character sets or you will wipe out the first 2K of your BASIC program.   Best to leave 4K lost at start of BASIC in that case, or resize your character sets to a single set.

We're in the weeds here.   Back to the fun -- please enjoy the programmable character sets and the graphical opportunities they provide!

Update 2024 April 27: raster interrupts implemented as described above, with two sets on screen, and working area using ROM font so doesn't change.  Second set is copied to $3800-$3FFF for display purposes, while the two sets remain at $0800-$17FF.

Update 2024 April 28: themes implemented (10) and grid mode added, new C64 keys updated above.  Themes allow quickly changing between color sets and grid options using the numeric keys.

Update 2024 May 1: wrote an article on moving video and programmable character memory.

Update 2024 May 4: have fixed many issues, and more enhancements, including moving programmable characters to $2000-$2FFF to make more usable, eliminate need to have separate edit/view copies.  But loses more BASIC RAM ($0800-$1FFF 6K now available for other uses) while reserving memory for characters.

Primary Color Theme


Wednesday, February 7, 2024

Calculator for Commodore 64 and other CBM BASIC models

 


Introduction

Wow! A new desktop calculator for Commodore.  Programmed all by myself in BASIC.  Wow, so impressed!   Or not.  Doesn't even have decimals.

No, it's not the best thing since sliced bread, but it was fun.  And it's just a start -- there's a bigger goal I'll get to in a while...

This was a puzzle programming exercise I challenged myself with.  How to make the calculator, especially with the operator precedence feature.

Link: LOAD"CALC64",8

Implementation

Let's go through how it was implemented.

User Interface

First was the design of the user interface, by creating PRINT statements.  Used reverse text to make a rectangular box with the keys displayed.

How to click on a key?  I'm so used to a mouse or touch interface.  Oops, Commodore doesn't have that usually, or not so easy.  Ignoring the 1351 mouse for now.   Most Commodore users are used to using the keyboard or joystick.  Forget the joystick, this is not a game!  Keyboard entry one key at a time will do just fine.  Note that ENTER also acts as =, and DEL is equivalent to ←, and X is a synonym for *.

Entry of digits was the first processing, accepting up to the limit of the display.  This stored as a string (V$) with keyed entries appended.

I started with 7 digits, but outgrew that in testing and increased to 9 digits.

At first, only positive numbers were supported, then fixed it to support negative numbers, with the negative sign taking up a position in the display.   The N key toggles a number entry between positive and negative and back again.

Entries allowed by this calculator are interleaved numbers and binary (two argument) operators.  Note that immediate operators like C and N usually take effect immediately, whereas binary operators require multiple arguments and a finalization (another binary operator or =).

There are exceptions allowed in entries to overwrite the prior value or the prior operator.   Examples:

  • 1+1=3 keyed entries will replace the 2 with a 3
  • 2+x3 will replace the addition operator with multiplication operator

Precedence needs a Stack

One design requirement I set for myself was to include operator precedence.  This means that multiplication and division have the same higher precedence over addition and subtraction at the same lower precedence.  Usually math is evaluated left to right, but due to precedence issues, other operators may need to be done first.  In other words the expression 1+2x3 is equivalent to 1 + (2x3) and then 1 + 6 and finally evaluates to 7.   But 1 x 2 + 3 is equivalent to (1x2) + 3, then 2 + 3, and finally 5.

I simply put numbers and operators interchangeably on a stack in order of entry until enough information is present to start evaluating.

Rule 1 - if user presses =, then evaluate

Rule 2 - if first operator is multiplication or division, once the second number is finalized with a second operator, simply evaluate the first expression

Rule 3 - if first operator is addition or subtraction, defer until the second operator and third number is finalized (third operator present!), then figure out what to do - either evaluate first or second expression, reducing the work

The stack is implemented as a count C, and an array of strings S$, which is expected to only grow up to 6 items (0..5), example C=6, S$[0]="1" [1]="+" [2]="2" [3]="*" [4]="3" [5]="+"

This example 1+2*3+ is reduced to 1+6+ and then to 7+, with the display updated to show the 7, but then wiped to disallow appending to it.


And no, I'm not doing RPN.  I didn't grow up with an HP calculator, nor am I implementing one today.  I grew up with Texas Instruments, and that's how my brain works.   Keeping it in entry order keeps it orderly for me.  Sure, there are other was to approach it.   This is BASIC, not Lisp.  And this is MY calculator, so I'm doing it MY way.  Others can follow their own paths.

Expression evaluation includes handling the equals = operation.  In the context of this calculator, that finalizes a calculation, meaning the user wants the result now.

Subroutines

There are several subroutines: 1) Evaluate and reduce stack, 2) Update display, 3) Display stack, 4) Evaluate simple expression involving two numbers and an operator.

That last subroutine is a diagnostic useful most for development, but also shows work in progress compared to a regular simple desk calculator that usually won't show pending work.

Error conditions

Overflow is when the number to be displayed doesn't fit in the 9 digit display, when the string representation of the number is long than 9 characters and/or larger than the maximum whole integer value that can be displayed in that space.   Note that the number is still internally represented and can still be acted on.  If a resulting answer can be displayed it will be (example: divide a ten digit positive number by 10).

Error indicates that division by zero was attempted.

Limitations

Only integers are supported.  No decimal numbers.  No currency.   Workaround required to calculate a percentage -- multiply by one hundred first, then divide by whole percentage.  And division results in a whole number so 1/3= results 0, and 5/2= evaluates to 2.

Non-negative numbers are limited 0 to 999999999 (nine digits).  Negative numbers are limited -1 to -99999999 (note only 8 digits).

Scientific notation is not supported.

No paper tape, no printout, no record of operations.

Limited user feedback.  No keypress indicators.

Stack diagnostic is a little technical, especially with a count, then colon, and the entries.  (Could eliminate the count and colon, and/or show previous and pending operators before and after the display.)

Keyboard entry.

Extras

The program was saved with a starting address $400, to support PET, so you must not load with secondary address 1 on a C64!  And while the program assumes a screen bigger than a VIC-20, a few minor changes to the margin and startup text can remedy that.

Next

What does the future hold?  Who can predict with any accuracy?  I can say anything here, but doesn't mean I'll follow through.  I originally was contemplating near limitless number of digits (considering the 8-bit platform, probably some 16-bit limitation).   Maybe binary and hex?   Maybe a scientific calculator?   Fixed decimal?   Near limitless decimals?   Port to assembly for fun!   We'll see...

Have fun calculating!

Saturday, December 30, 2023

Commodore 128 VDC Reference

 



The VDC8563 and VDC8568 were used in Commodore 128 and Commodore 128D computers for the secondary 80-column text screen.  There were other modes available to developers not exposed to BASIC end users (graphics, interlaced modes for higher resolutions including graphics and text, and lower resolution modes too).

I gathered this information from multiple sources including example data from VICE (sorry, didn't power on the DCR) while implementing support for my own emulator.

Hope you find this useful!

Link: PDF

Saturday, December 9, 2023

Commodore keyboards go wireless for my portable emulators

The c-simple-emu6502-cbm project supports a number of ESP32 platforms to provide a subset of Commodore C64 (and Vic-20, C128) emulation, and many currently include BLE keyboard support.  Originally for CardKB only, now I have added BLE support for Commodore keyboards (20 to 25 pins) to the m5, T-Display-S3, and ESP32-8048S070-7inch ports/branches into the encapsulated BLE_commodore_keyboard_server Arduino sketch.

BLE options: (a) Commodore keyboard (b) CardKB

No expense spared for these awesome graphics, seems retro eh?


While I have wired in the full C128DCR keyboard in the past using a circuit and software sketch with an Adafruit ItsyBitsy, now I trade the wire with another ESP32 and BLE communications.

M5Stick-C with CardKB BLE connected to T-Display-S3

Actually we already had BLE CardKB support, and the protocol for the hard wired keyboard is exactly the same as sent over BLE (string of active C64 and C128 scan codes), it was just a little bit of further coding to make the choice between CardKB and hardwired keyboard.   In fact, that code was already present for CardKB or hardwired keyboard in the M5 branch itself.  The tiny bit of extra work was to duplicate that in the BLE keyboard server project.   And voila!  More options all the way around.

Wired keyboards (a) Commodore (b) CardKB (c) Chrome Browser

There were already three options for wired keyboards.  And three common Commodore keyboards were represented, because they all have compatible pinouts, and because I do have both Vic-20 and C128DCR at home.

Dropping the wire from the wearable (or other ESP32 emulators) adds convenience to mobility, and also defers the need to support wired connections to any ESP32s missing Grove connectors and any that are not 5V tolerant, as both the ItsyBitsy and CardKB use 5V interfacing.   BLE support, and improved BLE support provide more options to the emulators running on hardware such as the T-Display-S3 and the 7"LCD ports without any hardware interventions.  While these latter ports would require extra circuitry for hardwired serial or I2C connections including 5V to 3V3 interfacing, using BLE means that the existing circuit support on the M5Stick-C acting as the BLE server can wire to those keyboards instead.  Going wireless provides the equivalent functionality without requiring a hard-wired circuit to the final display device.

While wireless does have its convenience, it does require careful timing to pair correctly.  Typically if both the BLE client and server are powered or reset at the same moment, they should pair.   A few or more keystrokes may be necessary to confirm pairing is complete.  If it doesn't work, just reset and try again.

Happy C64 computing over BLE!

Tuesday, December 5, 2023

7" LCD (ESP32) with C64 Text Emulator

 

7" is giant compared to this much smaller screen

So this ESP32-8048S070 showed up from AliExpress today.  It is a 7" IPS with touchscreen with ESP32-S3-WROOM-1 module, 16MB flash, 8MB PSRAM, microSD card, USB-C serial (CH3400 serial), Speaker connector, and other IO connectors.   The large LCD is 800x480 resolution.

The ordering page had a ZIP download of the examples, so I made sure I could build their Arduino Hello World TFT sample (I downgraded to Arduino_GFX library 1.3.1), and then ported my c-simple-emu6502-cbm project including upscaling from one to four pixels to cover the screen with C64 goodness.  Without upscaling, the C64 was using less than a quarter of the screen.   I skipped the SD support, and went straight to creating a FATFS partition and uploading a D64 image.  Saves me from pulling an SD, but moving files up and down will be a bit more cumbersome.  Included in the project already was custom wireless BLE keyboard support, so I was typing away and running my programs right away.

The largest IPS I had on hand was 3.5" 480x320, so this is a definite upgrade.  

The only downsides to this board that I can tell are the lack of an enclosure (ships in a nice plastic storage box though - I hear there is a 3D printable one on github somewhere though), and the lack of direct connection to the native ESP32-S3 USB port.  Then again, a permanent serial connection is more convenient for flashing Arduino sketches otherwise you have to keep selecting the COM port on other solutions.

Even though I've worked with it only a few hours, I highly recommend this board!