Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.env
yarn-error.log
tokagetone/
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
1 change: 1 addition & 0 deletions llvm-mos/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
build/
41 changes: 41 additions & 0 deletions llvm-mos/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#
# GNU Makefile
#

VICE=/Applications/vice-arm64-sdl2-3.7.1/bin/x64sc -autostartprgmode 1 -statusbar

all: demo

demo:
@echo "Compiling demo"
# -c Only run preprocess, compile, and assemble steps, do not link
mos-c64-clang -c -o build/music.o music.s
mos-c64-clang -c -o build/screens.o screens.s
mos-c64-clang -c -o build/demo.o demo.c
mos-c64-clang++ -std=c++20 -finput-charset=utf-8 -c -o build/strings.o strings.cpp
mos-c64-clang++ -std=c++20 -Os -flto \
-Wl,--section-start=.sid=0x1000, \
-Wl,--section-start=.bank0screen=0x0c00, \
-Wl,--section-start=.bank0bitmap=0x2000 \
-Wl,--section-start=.bank1screen=0x4c00, \
-Wl,--section-start=.bank1bitmap=0x6000 \
-o build/demo.prg build/demo.o build/music.o build/screens.o build/strings.o
mos-c64-clang++ -std=c++20 -Os -flto \
-Wl,--section-start=.sid=0x1000 \
-Wl,--section-start=.bank0screen=0x0c00 \
-Wl,--section-start=.bank0bitmap=0x2000 \
-Wl,--section-start=.bank1screen=0x4c00, \
-Wl,--section-start=.bank1bitmap=0x6000 \
-Wl,--lto-emit-asm -o build/demo.s build/demo.o build/music.o build/screens.o build/strings.o

run: demo
@echo "Running demo"
$(VICE) build/demo.prg

sid:
@echo "SID file info"
./tools/sidinfo.py music.sid

.PHONY: all demo run

# EOF - Makefile
21 changes: 21 additions & 0 deletions llvm-mos/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# C64 Demo using llvm-mos

This a follow up of my old [pure 6510 assembly demo](../asm), ported to llvm-mos.

## Requirements

* https://github.com/llvm-mos/llvm-mos - Port of LLVM to the MOS 6502 and related processors
* https://github.com/llvm-mos/llvm-mos-sdk - SDK for developing with the llvm-mos compiler


## Useful links

* 6502 opcodes - http://6502.org/tutorials/6502opcodes.html
* 6502 / 6510 Instruction Set - https://c64os.com/post/6502instructions
* llm-mos Wiki - https://llvm-mos.org/wiki/Welcome
* Gnu Assembler - https://sourceware.org/binutils/docs/as

## Other llvm-mos demos:

* C64 sprite example: https://gist.github.com/juj/84fc977c7f928e9343bb6f5f74c45a57
* sidplay: https://github.com/kklis/sidplay
137 changes: 137 additions & 0 deletions llvm-mos/demo.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
#include "macros.h"
#include <6502.h>
#include <c64.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>

extern unsigned bank0bgcolor;
extern unsigned bank1bgcolor;
extern char bank0bitmap;
extern char bank1bitmap;

extern char *message;
extern unsigned char messageLength;

unsigned char screen_state = 0;
unsigned char counter = 254;

unsigned char raster_h_offset = 7;
unsigned char msg_offset = 0;

void background(unsigned char color) {
poke(&VIC.bordercolor, color);
poke(&VIC.bgcolor0, color);
}

void recolor() {
// switch to Standard Bitmap Mode now (bit 5 set to 1)
// Bit #5: 0 = Text mode; 1 = Bitmap mode.
// see https://www.c64-wiki.com/wiki/Standard_Bitmap_Mode
poke(&VIC.ctrl1, 0b00111011);
// tells the VIC-II where to "look for graphics"
// in this case:
// 3 (%0011) * 1024 = $0c00 = address to start of color information
// bit 3 is set, then the bitmap starts at vic bank address + $2000 = $2000 or
// $6000 see https://www.c64-wiki.com/wiki/53272
poke(&VIC.addr, 0b00111000);
// bit 5 must be cleared to enter Standard Bitmap Mode
// see https://www.c64-wiki.com/wiki/Standard_Bitmap_Mode
poke(&VIC.ctrl2, 0b11011000);
if (screen_state == 0) {
background(bank1bgcolor);
vic_bank(0b0000010);
} else {
background(bank0bgcolor);
vic_bank(0b0000011);
}
counter++;
if (counter == 255) {
counter = 0;
screen_state = screen_state == 1 ? 0 : 1;
}
}

void scrollMessage() {
// use bank 0 $0000-$3FFF, ROM chars available at $1000-$1FFF
// see https://www.c64-wiki.com/wiki/VIC_bank
vic_bank(0b00000011);
// switch to Standard Character Mode now (bit 5 set to 0)
// Bit #5: 0 = Text mode; 1 = Bitmap mode.
// see https://www.c64-wiki.com/wiki/Standard_Character_Mode and
// http://sta.c64.org/cbm64mem.html
poke(&VIC.ctrl1, 0b00011011);
// tells the VIC-II where to "look for graphics"
// in this case:
// 15 (%1111) * 1024 = $3c00 = address to screen character RAM
// 2 (%010) * 2048 = $1000 = where to access the character set ROM address
// see https://www.c64-wiki.com/wiki/53272
poke(&VIC.addr, 0b11110100);

raster_h_offset--;
poke(&VIC.ctrl2, raster_h_offset);
if (raster_h_offset == 0) {
raster_h_offset = 7;

if (msg_offset == messageLength) {
msg_offset = 0;
}

for (uint8_t i = 0; i < 40; i++) {
poke(0x3fc0 + i, message[msg_offset + i]);
}

msg_offset++;
}
}

void clearBitmapLines(char *bitmap, uint16_t start, uint16_t end) {
for (uint16_t i = start; i < end; i = i + 1) {
bitmap[i] = 0;
}
}

// see https://llvm-mos.org/wiki/C_interrupts
__attribute__((interrupt, no_isr)) void play() {
interrupt_ack();
scrollMessage();
sid_play($1021);
recolor();
interrupt_exit();
}

int main(void) {
// we don't need the BASIC ROM after we start
// see https://www.c64-wiki.com/wiki/Zeropage
poke(0x0001, 0b00110110);

// initialize the SID song
sid_init($1048);

cls();

// C64 bitmaps are 320x200 pixels, or 8000 bytes. Each line is 40 bytes.
clearBitmapLines(&bank0bitmap, 8000 - 40 * 16, 8000);
clearBitmapLines(&bank1bitmap, 8000 - 40 * 16, 8000);

SEI();
poke(&VIC.rasterline, 240);
pokew(IRQVec, (unsigned int)&play);
// interrupt control - enable all interrupts with $7b (icr=$DC0D)
// see http://sta.c64.org/cbm64mem.html
poke(&CIA1.icr, 0b01111011);
// interrupt control register - enable raster interrupt with $81 ($d01a)
// see http://sta.c64.org/cbm64mem.html
poke(&VIC.imr, 0b10000001);
CLI();

while (1) {
/*
if (raster_line == 255) {
recolor();
// call sid play routing
sid_play($1021);
}
*/
}
}
42 changes: 42 additions & 0 deletions llvm-mos/macros.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#include <c64.h>
#include <6502.h>
#include <_vic2.h>

#define IRQVec 0x0314
#define BRKVec 0x0316
#define NMIVec 0x0318

// https://github.com/cc65/cc65/blob/master/include/peekpoke.h

#define poke(addr,val) (*(unsigned char*) (addr) = (val))
#define pokew(addr,val) (*(unsigned*) (addr) = (val))
#define peek(addr) (*(unsigned char*) (addr))
#define peekw(addr) (*(unsigned*) (addr))

// various
#define sid_init(addr) __attribute__((leaf)) asm("LDA #$00\nTAX\nTAY\nJSR "#addr)
#define sid_play(addr) __attribute__((leaf)) asm("JSR "#addr)
#define raster_line (*((volatile unsigned char *)(struct __vic2 *)&VIC.rasterline))

// clear screen. See http://sta.c64.org/cbm64scrfunc.html
#define cls() __attribute__((leaf)) asm("JSR $e544")

// https://www.c64-wiki.com/wiki/VIC_bank
#define vic_bank(pattern) (*((volatile unsigned char *)(struct __6526 *)&CIA2.pra))=0b11111100|pattern

#define raster_interrupt(line, fn) \
(*((volatile unsigned char *)(struct __vic2 *)&VIC.rasterline))=line; \
(*(volatile unsigned char *)0x0314)=(unsigned int)fn & 0xffff; \
(*(volatile unsigned char *)0x0315)=(unsigned int)fn >> 8;

#define interrupts_disable() __attribute__((leaf)) asm("SEI")
#define interrupts_enable() __attribute__((leaf)) asm("CLI")

// everytime an interrupt triggers, we need to acknowledge it by setting the
// corresponding VIC interrupt flag
// if we don't ack the irq, then it will be called again after we exit it
// see http://sta.c64.org/cbm64mem.html
#define interrupt_ack() (*((volatile unsigned char *)(struct __vic2 *)&VIC.irr)) = 0b11111111

// when exiting an irq, we need to restore the accumulator, and indexes y and x from the stack first
#define interrupt_exit() __attribute__((leaf)) asm("PLA\nTAY\nPLA\nTAX\nPLA\nRTI\n")
14 changes: 14 additions & 0 deletions llvm-mos/music.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# SID music section
# see --section-start=.sid=0x1000 in Makefile for sid address
# R flag is needed to avoid linker garbage collection
# see https://sourceware.org/binutils/docs/as/Section.html
#
# First 126 bytes of music.sid are header, so skip them
# .incbin "file"[,skip[,count]]
# https://www.hvsc.c64.org/download/C64Music/DOCUMENTS/SID_file_format.txt

.global sid
.type sid,@object
.section .sid,"awR",@progbits
sid:
.incbin "music.sid", 126
Binary file added llvm-mos/music.sid
Binary file not shown.
Binary file added llvm-mos/screen1.koa
Binary file not shown.
Binary file added llvm-mos/screen2.koa
Binary file not shown.
48 changes: 48 additions & 0 deletions llvm-mos/screens.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# https://www.c64-wiki.de/wiki/Koala_Painter

.global bank0bitmap
.type bank0bitmap,@object
.section .bank0bitmap,"awR",@progbits
bank0bitmap:
.incbin "screen1.koa", 2, 8000

.global bank0screen
.type bank0screen,@object
.section .bank0screen,"awR",@progbits
bank0screen:
.incbin "screen1.koa", 8002, 1000

# .global bank0color
# .type bank0color,@object
# .section .bank0color,"awR",@progbits
# bank0color:
# .incbin "screen1.koa", 9002, 1000

.global bank0bgcolor
.type bank0bgcolor,@object
bank0bgcolor:
.incbin "screen1.koa", 10002, 1

.global bank1bitmap
.type bank1bitmap,@object
.section .bank1bitmap,"awR",@progbits
bank1bitmap:
.incbin "screen2.koa", 2, 8000

.global bank1screen
.type bank1screen,@object
.section .bank1screen,"awR",@progbits
bank1screen:
.incbin "screen2.koa", 8002, 1000

# .global bank1color
# .type bank1color,@object
# .section .bank1color,"awR",@progbits
# bank1color:
# .incbin "screen2.koa", 9002, 1000

.global bank1bgcolor
.type bank1bgcolor,@object
bank1bgcolor:
.incbin "screen2.koa", 10002, 1

5 changes: 5 additions & 0 deletions llvm-mos/strings.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// https://llvm-mos.org/wiki/Character_set
#include <charset.h>

const char *message = U"THIS C64 DEMO USES VIC-II GRAPHICS, SPRITES, RASTER INTERRUPTS, A RANDOM GENERATOR AND SID MUSIC - MORE AT HTTPS://HITHUB.COM/CELSO/C64 "_uv;
unsigned char messageLength = 136;
7 changes: 7 additions & 0 deletions llvm-mos/tools.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.include "c64.inc"

.global ack
.type ack,@function
ack:
STA VIC_IRR
RTS
Loading