;; 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 call calc_screen_addr_apple 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 ;; almost like Apple but added 0x4000 as 0x400 is code in M4K calc_screen_addr_apple: ld a,(#_line_num) ; 0 to $17 ;; rrca ; 000ABCDE -> high 1CD, low EABAB000 and #7 or #0x88 ; will get to be 44 ld h,a ; high byte 44 to 47 ld a,(#_line_num) and #0x18 ; e00ab000 ld l,a sla l sla l or l ; a should have 0abab000 rla ; a should have abab000x sra h ; carry gets E res 7,h rra ; a should have Eabab000 ld l,a ; l should have eabab000 ld a, (_cur_pos) ld c,a inc a ld (_cur_pos),a xor a ld b,a add hl, bc ret ;; 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 add hl,hl ; *64 ld bc,#0x4000 add hl,bc ; start of curr line add_offset: 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: in a,(0) ; get ascii ld l,a ret ;; .org 0x100 .area _CODE init: ;; Stack at the top of memory. ld sp,#0xfffe ;; 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