obj = $(asrc:.s=.o) $(aSsrc:.S=.o) $(csrc:.c=.o)
dep = $(csrc:.c=.d)
+z80src = $(wildcard src/z80/*.asm)
+z80obj = $(z80src:.asm=.z80)
+z80bin = z80.bin
+
name = life
elf = $(name).elf
bin = $(name).bin
LDFLAGS = -T megadrive.ld -print-gc-sections \
-L/usr/lib/gcc-cross/m68k-linux-gnu/11 -lgcc
+Z80AS = vasmz80_oldstyle
+Z80ASFLAGS = -Fvobj
+Z80LD = vlink
+Z80LDFLAGS = -T z80.ld -b rawbin1
+
+
$(bin): $(elf)
$(OBJCOPY) -O binary $< $@
$(elf): $(obj)
$(LD) -o $@ $(obj) -Map link.map $(LDFLAGS)
+$(z80bin): $(z80obj)
+ $(Z80LD) -o $@ $(Z80LDFLAGS) $(z80obj)
+
+src/z80prog.o: src/z80prog.s $(z80bin)
+
-include $(dep)
+%.z80: %.asm
+ $(Z80AS) -o $@ $(Z80ASFLAGS) $< >/dev/null
+
.PHONY: clean
clean:
rm -f $(obj) $(elf) $(bin)
+ rm -f $(z80obj) $(z80bin)
.PHONY: cleandep
cleandep:
mount /media/usbmass
[ -f /media/usbmass/MEGA/MEGA.RBF ] || cp $(bin) /media/usbmass/MEGA/MEGA.BIN
umount /media/usbmass
+
--- /dev/null
+#ifndef HWREGS_H_
+#define HWREGS_H_
+
+#include <inttypes.h>
+
+#define REG16PTR(addr) (*(volatile uint16_t*)(addr))
+
+#define Z80_MEMMODE REG16PTR(0xa11000)
+#define Z80_BUSREQ REG16PTR(0xa11100)
+#define Z80_RESET REG16PTR(0xa11200)
+#define Z80_MEM ((uint8_t*)0xa00000)
+
+#define VDP_PORT_DATA REG16PTR(0xc00000)
+#define VDP_PORT_CTL REG16PTR(0xc00004)
+
+#endif /* HWREGS_H_ */
| from here on we continue in the regular .text section since we don't care
| where this code ends up.
.text
+ .include "vdpdefs.inc"
.global enable_intr
enable_intr:
| .extern vblank_handler
intr_hblank:
+| move.l %d0, -(%sp)
| move.l #0xc0020000, VDP_PORT_CTL
|
| move.w testcol, %d0
| rol.b #4, %d0
| move.w %d0, testcol
|
+| move.l (%sp)+, %d0
rte
+|testcol: .word 0
+
intr_vblank:
| jsr vblank_handler
rte
--- /dev/null
+#ifndef INTTYPES_H_
+#define INTTYPES_H_
+
+typedef signed char int8_t;
+typedef short int16_t;
+typedef long int32_t;
+
+typedef unsigned char uint8_t;
+typedef unsigned short uint16_t;
+typedef unsigned long uint32_t;
+
+#endif /* INTTYPES_H_ */
+#include "z80.h"
+
int main(void)
{
+ z80_init();
+
return 0;
}
--- /dev/null
+#include "z80.h"
+
+extern unsigned char z80prog[];
+extern long z80proglen;
+
+void z80_init(void)
+{
+ int i;
+ unsigned char *src, *dest;
+
+ z80_grab_bus();
+ z80_reset(0);
+ while(!z80_have_bus());
+
+ src = z80prog;
+ dest = Z80_MEM;
+ for(i=0; i<z80proglen; i++) {
+ *dest++ = *src++;
+ }
+
+ z80_reset(1);
+ z80_release_bus();
+ z80_reset(0);
+}
--- /dev/null
+#ifndef Z80_H_
+#define Z80_H_
+
+#include "hwregs.h"
+
+void z80_init(void);
+
+#define z80_grab_bus() (Z80_BUSREQ = 0x100)
+#define z80_release_bus() (Z80_BUSREQ = 0)
+/* non-zero if 68k grabbed the bus */
+#define z80_have_bus() ((Z80_BUSREQ & 0x100) == 0)
+
+#define z80_reset(rst) (Z80_RESET = ((rst) ? 0 : 0x100))
+
+#endif /* Z80_H_ */
--- /dev/null
+ include "sndregs.inc"
+
+ section .vect
+ jp main
+
+ org 38h
+ jp vblank_isr
+
+ section .text
+main: di
+ ld sp, $2000
+ im 1
+ ei
+.hang: halt
+ jr .hang
+
+init:
+ call ymwait
+ ret
+
+ymwait:
+ ld hl, YMADDR
+.wait: ld a, (hl)
+ bit 7, a
+ jr z, .wait
+ ret
+
+
+vblank_isr:
+ ;ex af, af'
+
+ ;ex af, af'
+ ;ei
+ ret
+
+; vi:ft=z80:
--- /dev/null
+YMADDR equ $4000
+YMDATA equ $4001
+YMADDR2 equ $4002
+YMDATA2 equ $4003
+
+YM_LFO equ $22
+YM_TIMERA_L equ $24
+YM_TIMERA_H equ $25
+YM_TIMERB equ $26
+YM_MODE equ $27
+YM_OPER equ $28
+YM_DAC equ $2a
+YM_DACEN equ $2b
+
+YM_OP1_DT1MUL equ $30
+YM_OP2_DT1MUL equ $34
+YM_OP3_DT1MUL equ $38
+YM_OP4_DT1MUL equ $3c
+
+; vi:ft=z80:
--- /dev/null
+ .section .rodata
+
+ .globl z80prog
+ .globl z80proglen
+
+z80prog:
+ .incbin "z80.bin"
+ .align 2
+z80proglen:
+ .long z80prog - z80proglen
--- /dev/null
+MEMORY {
+ ram : ORIGIN = 0, LENGTH = 0x2000
+}
+
+SECTIONS {
+ /* reset and interrupt vectors */
+ .vect : { * (.vect); }
+ /* we only need vectors up to 38h for IM 1 */
+ . = 0x40;
+ .text : { * (.text*); }
+ .rodata : { * (.rodata); }
+ .data : { * (.data); }
+ .bss : {
+ _bss_start = .;
+ * (.bss);
+ . = ALIGN(2)
+ _bss_end = .;
+ }
+ _bss_size = SIZEOF(.bss);
+}