commit d30e8778d5412add5ee39fc160b4eb9106cdfc7f Author: Brad Grantham Date: Fri Jul 27 22:30:44 2018 -0700 initial commit diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..00287fc --- /dev/null +++ b/Makefile @@ -0,0 +1,26 @@ +CC65 = $(HOME)/trees/cc65/bin/ +CPU = 6502 + +a.out: main.o interrupt.o vectors.o apple2rom.cfg apple2rom.lib + $(CC65)/ld65 -C apple2rom.cfg -m main.map --dbgfile main.dbg interrupt.o vectors.o main.o apple2rom.lib + +clean: + rm *.o a.out main.s + +main.s: main.c + $(CC65)/cc65 -t none -O --cpu $(CPU) main.c + +main.o: main.s + $(CC65)/ca65 --cpu $(CPU) main.s + +interrupt.o: interrupt.s + $(CC65)/ca65 --cpu $(CPU) interrupt.s + +vectors.o: vectors.s + $(CC65)/ca65 --cpu $(CPU) vectors.s + +crt0.o: crt0.s + $(CC65)/ca65 --cpu $(CPU) crt0.s + +apple2rom.lib: crt0.o + ../cc65/bin/ar65 a apple2rom.lib crt0.o diff --git a/apple2rom.cfg b/apple2rom.cfg new file mode 100644 index 0000000..be6b46a --- /dev/null +++ b/apple2rom.cfg @@ -0,0 +1,35 @@ +MEMORY { + ZP: start = $0, size = $100, type = rw, define = yes; + RAM: start = $4000, size = $4000, define = yes; + ROM: start = $D000, size = $3000, file = %O; +} + +SEGMENTS { + ZEROPAGE: load = ZP, type = zp, define = yes; + DATA: load = ROM, type = rw, define = yes, run = RAM; + BSS: load = RAM, type = bss, define = yes; + HEAP: load = RAM, type = bss, optional = yes; + STARTUP: load = ROM, type = ro; + ONCE: load = ROM, type = ro, optional = yes; + CODE: load = ROM, type = ro; + RODATA: load = ROM, type = ro; + VECTORS: load = ROM, type = ro, start = $FFFA; +} + +FEATURES { + CONDES: segment = STARTUP, + type = constructor, + label = __CONSTRUCTOR_TABLE__, + count = __CONSTRUCTOR_COUNT__; + CONDES: segment = STARTUP, + type = destructor, + label = __DESTRUCTOR_TABLE__, + count = __DESTRUCTOR_COUNT__; +} + +SYMBOLS { + # Define the stack size for the application + __STACKSIZE__: value = $0200, type = weak; + # __STACKSIZE__: type = weak, value = $0800; # 2k stack +} + diff --git a/apple2rom.lib b/apple2rom.lib new file mode 100644 index 0000000..69ab811 Binary files /dev/null and b/apple2rom.lib differ diff --git a/crt0.s b/crt0.s new file mode 100644 index 0000000..32694d2 --- /dev/null +++ b/crt0.s @@ -0,0 +1,54 @@ +; --------------------------------------------------------------------------- +; crt0.s +; --------------------------------------------------------------------------- +; +; Startup code for cc65 (Single Board Computer version) + +.export _init, _exit +.import _main + +.export __STARTUP__ : absolute = 1 ; Mark as startup +.import __RAM_START__, __RAM_SIZE__ ; Linker generated + +.import copydata, zerobss, initlib, donelib + +.include "zeropage.inc" + +; --------------------------------------------------------------------------- +; Place the startup code in a special segment + +.segment "STARTUP" + +; --------------------------------------------------------------------------- +; A little light 6502 housekeeping + +_init: LDX #$FF ; Initialize stack pointer to $01FF + TXS + CLD ; Clear decimal mode + +; --------------------------------------------------------------------------- +; Set cc65 argument stack pointer + + LDA #<(__RAM_START__ + __RAM_SIZE__) + STA sp + LDA #>(__RAM_START__ + __RAM_SIZE__) + STA sp+1 + +; --------------------------------------------------------------------------- +; Initialize memory storage + + JSR zerobss ; Clear BSS segment + JSR copydata ; Initialize DATA segment + JSR initlib ; Run constructors + +; --------------------------------------------------------------------------- +; Call main() + + JSR _main + +; --------------------------------------------------------------------------- +; Back from main (this is also the _exit entry): force a software break + +_exit: JSR donelib ; Run destructors + BRK + diff --git a/interrupt.s b/interrupt.s new file mode 100644 index 0000000..28a7d30 --- /dev/null +++ b/interrupt.s @@ -0,0 +1,45 @@ +; --------------------------------------------------------------------------- +; interrupt.s +; --------------------------------------------------------------------------- +; +; Interrupt handler. +; +; Checks for a BRK instruction and returns from all valid interrupts. + +.import _stop +.export _irq_int, _nmi_int + +.segment "CODE" + +.PC02 ; Force 65C02 assembly mode + +; --------------------------------------------------------------------------- +; Non-maskable interrupt (NMI) service routine + +_nmi_int: RTI ; Return from all NMI interrupts + +; --------------------------------------------------------------------------- +; Maskable interrupt (IRQ) service routine + +_irq_int: PHX ; Save X register contents to stack + TSX ; Transfer stack pointer to X + PHA ; Save accumulator contents to stack + INX ; Increment X so it points to the status + INX ; register value saved on the stack + LDA $100,X ; Load status register contents + AND #$10 ; Isolate B status bit + BNE break ; If B = 1, BRK detected + +; --------------------------------------------------------------------------- +; IRQ detected, return + +irq: PLA ; Restore accumulator contents + PLX ; Restore X register contents + RTI ; Return from all IRQ interrupts + +; --------------------------------------------------------------------------- +; BRK detected, stop + +break: JMP break ; If BRK is detected, something very bad + ; has happened, so stop running + diff --git a/main.c b/main.c new file mode 100644 index 0000000..75b2d90 --- /dev/null +++ b/main.c @@ -0,0 +1,21 @@ +char *title = "Apple IIa"; +unsigned char title_length = 9; + +unsigned char *text_page1_base = (unsigned char *)0x400; + +int main(void) +{ + int offset = (80 - title_length) / 2; + + unsigned char *loc = text_page1_base + offset; + + int i; + + for(i = 0; i < 80 * 24; i++) + text_page1_base[i] = ' ' | 0x80; + + for(i = 0; i < title_length; i++) + loc[i] = title[i] | 0x80; + + while(1); +} diff --git a/vectors.s b/vectors.s new file mode 100644 index 0000000..ae12ffb --- /dev/null +++ b/vectors.s @@ -0,0 +1,15 @@ +; --------------------------------------------------------------------------- +; vectors.s +; --------------------------------------------------------------------------- +; +; Defines the interrupt vector table. + +.import _init +.import _nmi_int, _irq_int + +.segment "VECTORS" + +.addr _nmi_int ; NMI vector +.addr _init ; Reset vector +.addr _irq_int ; IRQ/BRK vector +