main fake_cpm.sz8
  1CONSOLE_PORT equ 0
  2STATUS_PORT  equ 1
  3EXIT_PORT    equ 2
  4	org $E400
  5	jp handle_call
  6	ld a, (should_exit)
  7	dec a
  8	jr z, do_exit
  9	ld a, 1
 10	ld (should_exit), a
 11	jp $100
 12do_exit:
 13no_impl
 14	out (EXIT_PORT), a
 15should_exit:
 16	dc.b 0
 17	
 18console_in:
 19	in a, (CONSOLE_PORT)
 20	ld l, a
 21	ret
 22console_out:
 23	ld a, e
 24	out (CONSOLE_PORT), a
 25	ret
 26get_iobyte:
 27	ld a, (3)
 28	ld l, a
 29	ret
 30set_iobyte:
 31	ld a, e
 32	ld (3), a
 33	ret
 34write_string:
 35	ld c, '$'
 36	jp .start
 37.continue
 38	out (CONSOLE_PORT), a
 39	inc de
 40.start
 41	ld a, (de)
 42	cp c
 43	jr nz, .continue
 44	;flush output
 45	out (STATUS_PORT),a 
 46	ret
 47read_string:
 48	ld a, (de)
 49	ld c, a
 50	ld b, $A ;newline
 51	inc c
 52	inc de
 53	push de
 54	inc de
 55	jp .start
 56.continue
 57	in a, (CONSOLE_PORT)
 58	cp b
 59	jr z, .end
 60	ld (de), a
 61	inc de
 62.start
 63	dec c
 64	jr nz, .continue
 65	;todo: consume excess characters
 66.end
 67	pop hl
 68	ex de, hl
 69	sbc hl, de
 70	ld a, l
 71	ld (de), a
 72	ret
 73
 74console_status:
 75	in a, (STATUS_PORT)
 76	ld l, a
 77	ret
 78
 79handle_call:
 80	ld a, c
 81	or a
 82	jr z, do_exit
 83	dec a
 84	jr z, console_in
 85	dec a
 86	jr z, console_out
 87	dec a
 88	jr z, no_impl ;aux reader input
 89	dec a
 90	jr z, no_impl ;aux punch output
 91	dec a
 92	jr z, no_impl ;printer output
 93	dec a
 94	jr z, no_impl ;direct console IO
 95	dec a
 96	jr z, get_iobyte
 97	dec a
 98	jr z, set_iobyte
 99	dec a
100	jr z, write_string
101	dec a
102	jr z, read_string
103	dec a
104	jr z, console_status
105	jp no_impl