;; Generic crt0.s for a Z80 .module crt0 .globl _main .globl _line_num .globl _cur_pos .globl calc_screen_addr .area _HEADER (ABS) ;; Reset vector .org 0 jp init .org 0x08 jr put_char .org 0x10 reti .org 0x18 reti .org 0x20 reti .org 0x28 reti .org 0x30 reti .org 0x38 reti .org 0x51 ; normal ROM happens to have ei ret here too EIROM: ei ; for starting SNA images ret put_char: cp #1 ret nz ld a,l cp #0x0d ; ignore CR ret z cp #0x0A ret z push bc push hl ; l has the char call calc_screen_addr pop bc ; c has the char - this used to be HL ld (hl),c pop bc ret ;; calculate the screen address for the current character ;; destroys hl,a,bc calc_screen_addr: xor a ld h,a ld a,(#_line_num) ld l,a add hl,hl ; *2 add hl,hl ; *4 add hl,hl ; *8 add hl,hl ; *16 add hl,hl ; *32 ld bc,#0x5800 add hl,bc ; start of curr line ld a, (_cur_pos) push af inc a ld (_cur_pos),a pop af add a,l jr nc, no_carry inc h no_carry: ld l,a ; now we have the final address for a char ret .globl _key_pressed _key_pressed: push bc ld b,#0 ld c,#0xfe in a,(c) or a,#0xe0 cpl ld l,a in a,(0) ; get ascii ld h,a pop bc ret ;; .org 0x100 .area _CODE init: ;; Stack at the top of memory. ld sp,#0x1ffe ;; Initialise global variables call gsinit call _main jp _exit ;; Ordering of segments for the linker. .area _HOME .area _CODE .area _GSINIT .area _GSFINAL .area _DATA .area _BSS .area _HEAP .area _CODE __clock:: ld a,#2 rst 0x08 ret _exit:: ;; Exit - special code to the emulator ld a,#0 rst 0x08 1$: halt jr 1$ .area _GSINIT gsinit:: .area _GSFINAL ret