mirror of
https://github.com/irmen/prog8.git
synced 2026-10-22 20:02:27 +00:00
412 lines
9.6 KiB
NASM
412 lines
9.6 KiB
NASM
; A working m68k kernel for use in QEMU `-M virt` m68k machine.
|
|
; It parses the bootinfo chunks, prints stuff to the uart output, and reads input as well.
|
|
|
|
|
|
section .text,code
|
|
xref _end_of_code
|
|
|
|
global _start
|
|
_start: move.l #$fffc,sp
|
|
bsr bootinfo_parse
|
|
move.l ram_top,d0
|
|
beq 1$
|
|
sub.l #256,d0
|
|
move.l d0,sp
|
|
1$:
|
|
|
|
movea.l #str_welcome,a0
|
|
bsr puts
|
|
|
|
2$: bsr getchar
|
|
move.b d0,d1
|
|
move.b d1,(a0)
|
|
bsr putchar
|
|
cmpi.b #13,d1
|
|
bne 3$
|
|
move.b #10,d0
|
|
bsr putchar
|
|
3$: cmpi.b #$1b,d1
|
|
bne 2$
|
|
bsr do_halt
|
|
bra 2$
|
|
|
|
; ============================================================
|
|
; bootinfo_parse -- iterate bootinfo records and print them
|
|
; ============================================================
|
|
bootinfo_parse:
|
|
move.l d2,-(sp)
|
|
move.l d4,-(sp)
|
|
moveq #0,d4
|
|
move.l #_end_of_code,d0
|
|
addq.l #1,d0
|
|
lsr.l #1,d0
|
|
lsl.l #1,d0
|
|
movea.l d0,a2
|
|
bi_loop:
|
|
clr.l d0
|
|
move.w (a2)+,d0
|
|
beq bi_done
|
|
move.l d0,d2
|
|
cmpi.w #2,d2
|
|
bne 1$
|
|
moveq #1,d4
|
|
1$:
|
|
clr.l d1
|
|
move.w (a2)+,d1
|
|
move.l a2,a3
|
|
lea (-4,a2,d1.l),a2
|
|
subq.l #4,d1
|
|
|
|
movea.l #str_indent,a0
|
|
bsr puts
|
|
move.l a3,d0
|
|
subq.l #4,d0
|
|
bsr puthex8
|
|
movea.l #str_colon_space,a0
|
|
bsr puts
|
|
|
|
move.l d2,d0
|
|
bsr bi_print_tag
|
|
|
|
bsr bi_newline
|
|
|
|
movea.l #str_pad,a0
|
|
bsr puts
|
|
move.l a3,-(sp)
|
|
move.l d1,-(sp)
|
|
move.l d2,-(sp)
|
|
bsr bi_print_data
|
|
add.w #12,sp
|
|
|
|
bsr bi_newline
|
|
bra bi_loop
|
|
|
|
bi_done:
|
|
tst.l d4
|
|
bne 1$
|
|
movea.l #str_indent,a0
|
|
bsr puts
|
|
movea.l #str_no_cputype,a0
|
|
bsr puts
|
|
bsr bi_newline
|
|
1$: move.l (sp)+,d4
|
|
move.l (sp)+,d2
|
|
rts
|
|
|
|
bi_newline:
|
|
movea.l #str_newline,a0
|
|
bra puts
|
|
|
|
; ============================================================
|
|
; bi_print_tag -- print tag name for value in d0
|
|
; ============================================================
|
|
bi_print_tag:
|
|
cmpi.w #1,d0
|
|
beq bi_tag_machtype
|
|
cmpi.w #2,d0
|
|
beq bi_tag_cputype
|
|
cmpi.w #3,d0
|
|
beq bi_tag_fputype
|
|
cmpi.w #4,d0
|
|
beq bi_tag_mmutype
|
|
cmpi.w #5,d0
|
|
beq bi_tag_memchunk
|
|
cmpi.w #6,d0
|
|
beq bi_tag_ramdisk
|
|
cmpi.w #7,d0
|
|
beq bi_tag_cmdline
|
|
cmpi.w #8,d0
|
|
beq bi_tag_rngseed
|
|
cmpi.w #$8000,d0
|
|
beq bi_tag_version
|
|
cmpi.w #$8001,d0
|
|
beq bi_tag_pic
|
|
cmpi.w #$8002,d0
|
|
beq bi_tag_rtc
|
|
cmpi.w #$8003,d0
|
|
beq bi_tag_tty
|
|
cmpi.w #$8004,d0
|
|
beq bi_tag_virtio
|
|
cmpi.w #$8005,d0
|
|
beq bi_tag_ctrl
|
|
|
|
movea.l #str_hex_prefix,a0
|
|
bsr puts
|
|
bsr puthex8
|
|
rts
|
|
|
|
bi_tag_machtype: movea.l #str_machtype,a0
|
|
bra puts
|
|
bi_tag_cputype: movea.l #str_cputype,a0
|
|
bra puts
|
|
bi_tag_fputype: movea.l #str_fputype,a0
|
|
bra puts
|
|
bi_tag_mmutype: movea.l #str_mmutype,a0
|
|
bra puts
|
|
bi_tag_memchunk: movea.l #str_memchunk,a0
|
|
bra puts
|
|
bi_tag_ramdisk: movea.l #str_ramdisk,a0
|
|
bra puts
|
|
bi_tag_cmdline: movea.l #str_cmdline,a0
|
|
bra puts
|
|
bi_tag_rngseed: movea.l #str_rngseed,a0
|
|
bra puts
|
|
bi_tag_version: movea.l #str_version,a0
|
|
bra puts
|
|
bi_tag_pic: movea.l #str_pic,a0
|
|
bra puts
|
|
bi_tag_rtc: movea.l #str_rtc,a0
|
|
bra puts
|
|
bi_tag_tty: movea.l #str_tty,a0
|
|
bra puts
|
|
bi_tag_ctrl: movea.l #str_ctrl,a0
|
|
bra puts
|
|
bi_tag_virtio: movea.l #str_virtio,a0
|
|
bra puts
|
|
|
|
; ============================================================
|
|
; bi_print_data -- print data based on tag type
|
|
; stack args (low to high): tag, size, data_ptr
|
|
; ============================================================
|
|
bi_print_data:
|
|
move.l 4(sp),d0
|
|
move.l 8(sp),d1
|
|
movea.l 12(sp),a3
|
|
|
|
cmpi.w #1,d0
|
|
beq bi_data_machtype
|
|
cmpi.w #2,d0
|
|
beq bi_data_cputype
|
|
cmpi.w #3,d0
|
|
beq bi_data_u32
|
|
cmpi.w #4,d0
|
|
beq bi_data_u32
|
|
cmpi.w #$8000,d0
|
|
beq bi_data_u32
|
|
cmpi.w #5,d0
|
|
beq bi_data_memchunk
|
|
cmpi.w #6,d0
|
|
beq bi_data_base_size
|
|
cmpi.w #7,d0
|
|
beq bi_data_str
|
|
cmpi.w #8,d0
|
|
beq bi_data_hex
|
|
cmpi.w #$8001,d0
|
|
beq bi_data_base_count
|
|
cmpi.w #$8002,d0
|
|
beq bi_data_base_count
|
|
cmpi.w #$8003,d0
|
|
beq bi_data_base_count
|
|
cmpi.w #$8004,d0
|
|
beq bi_data_base_count
|
|
cmpi.w #$8005,d0
|
|
beq bi_data_base_count
|
|
|
|
bi_data_hex:
|
|
move.l d1,d3
|
|
1$: move.b (a3)+,d0
|
|
bsr puthex2
|
|
subq.l #1,d3
|
|
beq 2$
|
|
movea.l #str_space,a0
|
|
bsr puts
|
|
bra 1$
|
|
2$: rts
|
|
|
|
bi_data_u32:
|
|
move.l (a3),d0
|
|
bra puthex8
|
|
|
|
bi_data_memchunk:
|
|
move.l (a3),-(sp)
|
|
movea.l #str_mem_at,a0
|
|
bsr puts
|
|
move.l (sp)+,d0
|
|
bsr puthex8
|
|
movea.l #str_to,a0
|
|
bsr puts
|
|
move.l 4(a3),d0
|
|
add.l (a3),d0
|
|
move.l d0,ram_top
|
|
bsr puthex8
|
|
movea.l #str_size,a0
|
|
bsr puts
|
|
move.l 4(a3),d0
|
|
bra puthex8
|
|
|
|
bi_data_base_size:
|
|
movea.l #str_base,a0
|
|
bsr puts
|
|
move.l (a3),d0
|
|
bsr puthex8
|
|
movea.l #str_size,a0
|
|
bsr puts
|
|
move.l 4(a3),d0
|
|
bra puthex8
|
|
|
|
bi_data_base_count:
|
|
movea.l #str_base,a0
|
|
bsr puts
|
|
move.l (a3),d0
|
|
bsr puthex8
|
|
movea.l #str_count,a0
|
|
bsr puts
|
|
move.l 4(a3),d0
|
|
bra puthex8
|
|
|
|
bi_data_str:
|
|
movea.l a3,a0
|
|
bra puts
|
|
|
|
bi_data_machtype:
|
|
move.l (a3),d0
|
|
cmpi.l #14,d0
|
|
beq 1$
|
|
bra puthex8
|
|
1$: movea.l #str_mach_virt,a0
|
|
bra puts
|
|
|
|
bi_data_cputype:
|
|
move.l (a3),d0
|
|
beq 6$
|
|
btst #0,d0
|
|
bne 1$
|
|
btst #1,d0
|
|
bne 2$
|
|
btst #2,d0
|
|
bne 3$
|
|
btst #3,d0
|
|
bne 4$
|
|
btst #4,d0
|
|
bne 5$
|
|
bra puthex8
|
|
1$: movea.l #str_cpu68020,a0
|
|
bra puts
|
|
2$: movea.l #str_cpu68030,a0
|
|
bra puts
|
|
3$: movea.l #str_cpu68040,a0
|
|
bra puts
|
|
4$: movea.l #str_cpu68060,a0
|
|
bra puts
|
|
5$: movea.l #str_coldfire,a0
|
|
bra puts
|
|
6$: movea.l #str_cpu68000,a0
|
|
bra puts
|
|
|
|
; ============================================================
|
|
puts: move.b (a0)+,d0
|
|
beq puts_rts
|
|
bsr putchar
|
|
bra puts
|
|
puts_rts:
|
|
rts
|
|
|
|
; ============================================================
|
|
puthex8:
|
|
move.l d2,-(sp)
|
|
move.l d3,-(sp)
|
|
move.l d0,d2
|
|
moveq #28,d3
|
|
1$: move.l d2,d0
|
|
lsr.l d3,d0
|
|
and.b #$f,d0
|
|
add.b #'0',d0
|
|
cmp.b #'9',d0
|
|
bls 2$
|
|
add.b #7,d0
|
|
2$: bsr putchar
|
|
subq.l #4,d3
|
|
bpl 1$
|
|
move.l (sp)+,d3
|
|
move.l (sp)+,d2
|
|
rts
|
|
|
|
; ============================================================
|
|
puthex2:
|
|
move.l d2,-(sp)
|
|
move.l d3,-(sp)
|
|
move.l d0,d2
|
|
moveq #4,d3
|
|
1$: move.l d2,d0
|
|
lsr.l d3,d0
|
|
and.b #$f,d0
|
|
add.b #'0',d0
|
|
cmp.b #'9',d0
|
|
bls 2$
|
|
add.b #7,d0
|
|
2$: bsr putchar
|
|
subq.l #4,d3
|
|
bpl 1$
|
|
move.l (sp)+,d3
|
|
move.l (sp)+,d2
|
|
rts
|
|
|
|
; ============================================================
|
|
putchar:
|
|
movea.l #$ff008000,a1
|
|
move.l d0,(a1)
|
|
rts
|
|
|
|
; ============================================================
|
|
getchar:
|
|
suba.l #16,sp
|
|
movea.l #$ff008004,a1
|
|
1$: move.l (a1),d0
|
|
tst.l d0
|
|
beq 1$
|
|
movea.l #$ff008010,a1
|
|
move.l sp,(a1)
|
|
movea.l #$ff008014,a1
|
|
move.l #1,(a1)
|
|
movea.l #$ff008008,a1
|
|
move.l #3,(a1)
|
|
move.b (sp),d0
|
|
adda.l #16,sp
|
|
rts
|
|
|
|
; ============================================================
|
|
do_halt:
|
|
movea.l #$ff009004,a1
|
|
move.l #2,(a1)
|
|
rts
|
|
|
|
; ============================================================
|
|
; Strings
|
|
; ============================================================
|
|
str_indent: dc.b " ",0
|
|
str_colon_space: dc.b ": ",0
|
|
str_pad: dc.b " ",0
|
|
str_newline: dc.b 10,0
|
|
str_base: dc.b "base=0x",0
|
|
str_size: dc.b " size=0x",0
|
|
str_count: dc.b " count=0x",0
|
|
str_mem_at: dc.b "mem at 0x",0
|
|
str_to: dc.b " - 0x",0
|
|
str_space: dc.b " ",0
|
|
str_hex_prefix: dc.b "TAG_0x",0
|
|
str_mach_virt: dc.b "MACH_VIRT",0
|
|
str_cpu68000: dc.b "CPU_68000",0
|
|
str_cpu68020: dc.b "CPU_68020",0
|
|
str_cpu68030: dc.b "CPU_68030",0
|
|
str_cpu68040: dc.b "CPU_68040",0
|
|
str_cpu68060: dc.b "CPU_68060",0
|
|
str_coldfire: dc.b "ColdFire",0
|
|
str_no_cputype: dc.b "(no BI_CPUTYPE - assuming CPU_68000)",0
|
|
str_machtype: dc.b "BI_MACHTYPE",0
|
|
str_cputype: dc.b "BI_CPUTYPE",0
|
|
str_fputype: dc.b "BI_FPUTYPE",0
|
|
str_mmutype: dc.b "BI_MMUTYPE",0
|
|
str_memchunk: dc.b "BI_MEMCHUNK",0
|
|
str_ramdisk: dc.b "BI_RAMDISK",0
|
|
str_cmdline: dc.b "BI_COMMAND_LINE",0
|
|
str_rngseed: dc.b "BI_RNG_SEED",0
|
|
str_version: dc.b "BI_VIRT_QEMU_VER",0
|
|
str_pic: dc.b "BI_VIRT_GF_PIC",0
|
|
str_rtc: dc.b "BI_VIRT_GF_RTC",0
|
|
str_tty: dc.b "BI_VIRT_GF_TTY",0
|
|
str_ctrl: dc.b "BI_VIRT_CTRL",0
|
|
str_virtio: dc.b "BI_VIRT_VIRTIO",0
|
|
str_welcome: dc.b "Hello from m68k! (ESC to halt)",10,0
|
|
align 4
|
|
ram_top: dc.l 0
|