Unterschiede
Hier werden die Unterschiede zwischen zwei Versionen angezeigt.
Nächste Überarbeitung | Vorhergehende ÜberarbeitungLetzte ÜberarbeitungBeide Seiten der Revision | ||
amstradcpc:sdcc [2013/01/04 23:50] – angelegt octoate | amstradcpc:sdcc [2013/01/05 22:43] – [crt0.s] ROM Version hinzugefügt octoate | ||
---|---|---|---|
Zeile 4: | Zeile 4: | ||
Ein englischsprachiges Tutorial, wie man einfache Programme mit SDCC für den Amstrad CPC entwickelt, findet man auf [[http:// | Ein englischsprachiges Tutorial, wie man einfache Programme mit SDCC für den Amstrad CPC entwickelt, findet man auf [[http:// | ||
+ | |||
+ | ===== crt0.s ===== | ||
+ | |||
+ | Da der SDCC standardmäßig seinen Code ab 0x0000 ablegt und auch der Startup Code ab dieser Stelle läuft, muss beim Compilieren eines Programmes vorher eine angepasste Version der //crt0.s// erstellt werden, die dann über den Kommandozeilenparameter **--no-std-crt0** eingebunden wird. Die //crt0.s// muss vorher aber noch ein Objektcode umgewandelt werden, was mit dem Programm **sdasz80** erledigt wird. Der Aufruf lautet | ||
+ | |||
+ | < | ||
+ | |||
+ | Danach liegt im gleichen Verzeichnis die Datei **crt0.rel**, | ||
+ | |||
+ | ==== crt0.s für ROMs ==== | ||
+ | |||
+ | Um ein ROM mit SDCC zu erstellen wird eine angepasste **crt0.s** benötigt. Sie stellt den ROM Header zur Verfügung, initialisiert das ROM, stellt RSX Befehle zur Verfügung, um das ROM in BASIC einzubinden und legt die Bereiche für den Linker fest. Nachfolgend ist eine Beispieldatei, | ||
+ | |||
+ | <code asm 1> | ||
+ | ;; FILE: crt0.s | ||
+ | ;; adapted for Amstrad CPC ROM creation 2013 by Tim Riemann / Octoate | ||
+ | |||
+ | .module crt0 | ||
+ | .globl | ||
+ | |||
+ | .area _HEADER (ABS) | ||
+ | |||
+ | .org 0xC000 | ||
+ | |||
+ | .db 0x01 ; background ROM | ||
+ | .db 0, 0, 1 ; version 0.0.1 | ||
+ | |||
+ | .dw rsx_name_table | ||
+ | |||
+ | ; RSX jump block | ||
+ | jp init_rom | ||
+ | jp run_game | ||
+ | |||
+ | rsx_name_table: | ||
+ | .ascis "Init ROM" | ||
+ | ; use a name, which you can't execute from BASIC here | ||
+ | .ascis " | ||
+ | .db 0 ; end of the RSX command table | ||
+ | |||
+ | init_rom: | ||
+ | push hl | ||
+ | ld hl, #init_msg | ||
+ | call show_message | ||
+ | pop hl | ||
+ | scf ; tell the firmware, that initialisation was successful | ||
+ | ret | ||
+ | |||
+ | init_msg: | ||
+ | .db 0x0F, 2 | ||
+ | .ascii " Project" | ||
+ | .db 0x0F, 3 | ||
+ | .ascii " Alpha" | ||
+ | .db 0x0F, 1 | ||
+ | .ascii " (" | ||
+ | .db 0x7C | ||
+ | .ascii "GAME) " | ||
+ | .db 0xA4 | ||
+ | .ascii " | ||
+ | |||
+ | .db 0x0F, 3 | ||
+ | .ascii " You" | ||
+ | .db 0x0F, 1, 7, 10, 13, 0xFF | ||
+ | |||
+ | run_game: | ||
+ | ; Get the ROM number | ||
+ | call 0xB912 | ||
+ | ld (0x4000), a ; Save the rom number in a variable in ram | ||
+ | |||
+ | ld hl, # | ||
+ | call show_message | ||
+ | |||
+ | ;; Stack at the top of memory. | ||
+ | ;;ld sp,(0xC000 - 1) | ||
+ | |||
+ | call gsinit | ||
+ | call _main | ||
+ | |||
+ | ret ; end of the execution -> reset the CPC | ||
+ | |||
+ | game_message: | ||
+ | .ascii "Hello CPC World!" | ||
+ | .db 10, 13, 0xFF | ||
+ | |||
+ | show_message: | ||
+ | ld a, (hl) | ||
+ | loop_show_message: | ||
+ | call 0xBB5A | ||
+ | inc hl | ||
+ | ld a, (hl) | ||
+ | cp #0xFF | ||
+ | jr nz, loop_show_message | ||
+ | ret | ||
+ | |||
+ | _putchar:: | ||
+ | _putchar_rr_s:: | ||
+ | ld hl,#2 | ||
+ | add hl,sp | ||
+ | |||
+ | ld a,(hl) | ||
+ | call 0xBB5A | ||
+ | ret | ||
+ | |||
+ | _putchar_rr_dbs:: | ||
+ | ld a,e | ||
+ | call 0xBB5A | ||
+ | ret | ||
+ | |||
+ | __clock:: | ||
+ | ret | ||
+ | |||
+ | _exit:: | ||
+ | ret | ||
+ | |||
+ | .area _GSINIT | ||
+ | gsinit:: | ||
+ | .area _GSFINAL | ||
+ | ret | ||
+ | |||
+ | ;; Ordering of segments for the linker. | ||
+ | .area _HOME | ||
+ | .area _CODE | ||
+ | .area _GSINIT | ||
+ | .area _GSFINAL | ||
+ | |||
+ | .area _DATA | ||
+ | .area _BSS | ||
+ | .area _HEAP | ||
+ | |||
+ | .area _CODE | ||
+ | |||
+ | </ | ||