summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeo C2014-10-28 10:29:13 +0100
committerLeo C2014-10-28 10:29:13 +0100
commit30d1329e8e5c029a87f657baace698d1d7031f9e (patch)
tree8968e54145c1212cbaad6938e3da86cb42bf3707
parent8a7deceacd30529e5c32082b2c719eb055841d0d (diff)
downloadz180-stamp-30d1329e8e5c029a87f657baace698d1d7031f9e.zip
CP/M 3 compatible character i/o handling
-rw-r--r--z180/Tupfile2
-rw-r--r--z180/bioscio.180325
-rw-r--r--z180/chario.180103
-rw-r--r--z180/conbuf-a.1803
-rw-r--r--z180/console.18010
-rw-r--r--z180/ddtz.180120
-rw-r--r--z180/modebaud.inc31
-rw-r--r--z180/r3init.18039
-rw-r--r--z180/ser1-i.1809
9 files changed, 575 insertions, 67 deletions
diff --git a/z180/Tupfile b/z180/Tupfile
index 8b50b8a..bb88946 100644
--- a/z180/Tupfile
+++ b/z180/Tupfile
@@ -5,7 +5,7 @@ PROG = hdrom
SRC = r3init.180
SRC += ddtz.180
#SRC += fifoio.180 msgbuf.180 ser1-i.180 console.180
-SRC += msgbuf-a.180 conbuf-a.180 ser1-i.180 console.180
+SRC += msgbuf-a.180 conbuf-a.180 ser1-i.180 bioscio.180 chario.180
# serial (asci1) console only:
#SRC += ser1-i.180 console.180
SRC += romend.180
diff --git a/z180/bioscio.180 b/z180/bioscio.180
new file mode 100644
index 0000000..a3a179f
--- /dev/null
+++ b/z180/bioscio.180
@@ -0,0 +1,325 @@
+
+ .z80
+
+; Copyright (C), 1982
+; Digital Research, Inc
+; P.O. Box 579
+; Pacific Grove, CA 93950
+
+; This is the invariant portion of the modular BIOS and is
+; distributed as source for informational purposes only.
+; All desired modifications should be performed by
+; adding or changing externally defined modules.
+; This allows producing "standard" I/O modules that
+; can be combined to support a particular system
+; configuration.
+;
+; Modified for faster character I/O by Udo Munk
+
+cr equ 13
+lf equ 10
+bell equ 7
+ctlQ equ 'Q'-'@'
+ctlS equ 'S'-'@'
+
+ cseg ; GENCPM puts CSEG stuff in common memory
+
+ ; variables in system data page
+
+;; extrn @covec,@civec,@aovec,@aivec,@lovec ; I/O redirection vectors
+
+ ; user defined character I/O routines
+
+ extrn ?ci,?co,?cist,?cost ; each take device in <B>
+ extrn ?cinit ; (re)initialize device in <C>
+ extrn @ctbl ; physical character device table
+
+
+ include modebaud.inc ; define mode bits
+
+
+ public @covec,@civec,@aovec,@aivec,@lovec ; I/O redirection vectors
+ public ?const,?conin,?cono,?list,?auxo,?auxi
+ public ?lists,?conos,?auxis,?auxos,?dvtbl,charini
+
+
+@CIVEC: dw 0 ; Console Input Redirection
+ ; Vector (word, r/w)
+@COVEC: dw 0 ; Console Output Redirection
+ ; Vector (word, r/w)
+@AIVEC: dw 0 ; Auxiliary Input Redirection
+ ; Vector (word, r/w)
+@AOVEC: dw 0 ; Auxiliary Output Redirection
+ ; Vector (word, r/w)
+@LOVEC: dw 0 ; List Output Redirection
+ ; Vector (word, r/w)
+
+
+charini:
+
+ ld c,15 ; initialize all 16 character devices
+c$init$loop:
+ push bc
+ call ?cinit
+ pop bc
+ dec c
+ jp p,c$init$loop
+
+ ld hl,1100000000000000b ; assign console to HOST and ASCI1
+ ld (@civec),hl
+ ld (@covec),hl
+ ld hl,0000000000000000b ; assign auxiliary to nothing
+ ld (@aivec),hl
+ ld (@aovec),hl
+ ld hl,0000000000000000b ; assign printer to nothing
+ ld (@lovec),hl
+ ret
+
+
+ ; DEVTBL
+ ; Return address of character device table
+
+?dvtbl:
+devtbl:
+ ld hl,@ctbl
+ ret
+
+
+ ; CONOUT
+ ; Console Output. Send character in <C>
+ ; to all selected devices
+
+?cono:
+conout:
+ ld hl,(@covec) ; fetch console output bit vector
+ jr out$scan
+
+
+ ; AUXOUT
+ ; Auxiliary Output. Send character in <C>
+ ; to all selected devices
+
+?auxo:
+auxout:
+ ld hl,(@aovec) ; fetch aux output bit vector
+ jr out$scan
+
+
+ ; LIST
+ ; List Output. Send character in <C>
+ ; to all selected devices.
+
+?list:
+list:
+ ld hl,(@lovec) ; fetch list output bit vector
+
+out$scan:
+ ld b,0 ; start with device 0
+co$next:
+ add hl,hl ; shift out next bit
+ jr nc,not$out$device
+ push hl ; save the vector
+ push bc ; save the count and character
+ call ?co ; if device selected, print it
+ pop bc ; recover count and character
+ pop hl ; recover the rest of the vector
+not$out$device:
+ inc b ; next device number
+ ld a,h
+ or l ; see if any devices left
+ jr nz,co$next ; and go find them...
+ ret
+
+
+ ; CONOST
+ ; Console Output Status. Return true if
+ ; all selected console output devices
+ ; are ready.
+
+?conos:
+conost:
+ ld hl,(@covec) ; get console output bit vector
+ jr ost$scan
+
+
+ ; AUXOST
+ ; Auxiliary Output Status. Return true if
+ ; all selected auxiliary output devices
+ ; are ready.
+
+?auxos:
+auxost:
+ ld hl,(@aovec) ; get aux output bit vector
+ jr ost$scan
+
+
+ ; LISTST
+ ; List Output Status. Return true if
+ ; all selected list output devices
+ ; are ready.
+
+?lists:
+listst:
+ ld hl,(@lovec) ; get list output bit vector
+
+ost$scan:
+ ld b,0 ; start with device 0
+cos$next:
+ add hl,hl ; check next bit
+ push hl ; save the vector
+ push bc ; save the count
+ ld a,0FFh ; assume device ready
+ call c,coster ; check status for this device
+ pop bc ; recover count
+ pop hl ; recover bit vector
+ or a ; see if device ready
+ ret z ; if any not ready, return false
+ inc b ; drop device number
+ ld a,h
+ or l ; see if any more selected devices
+ jr nz,cos$next
+ or 0FFh ; all selected were ready, return true
+ ret
+
+coster: ; check for output device ready, including optional
+ ; xon/xoff support
+ ;
+ ;TODO: interrupt driven devices should xon/xoff handle
+ ; in isv
+
+ ld l,b
+ ld h,0 ; make device code 16 bits
+ push hl ; save it in stack
+ add hl,hl
+ add hl,hl
+ add hl,hl ; create offset into device characteristics tbl
+ ld de,@ctbl+6
+ add hl,de ; make address of mode byte
+ ld a,(hl)
+ and mb$xon$xoff
+ pop hl ; recover console number in <HL>
+ jp z,?cost ; not a xon device, go get output status direct
+ ld de,xofflist
+ add hl,de ; make pointer to proper xon/xoff flag
+ call cist1 ; see if this keyboard has character
+ ld a,(hl)
+ call nz,ci1 ; get flag or read key if any
+ cp ctlq
+ jr nz,not$q ; if its a ctl-Q,
+ ld a,0FFh ; set the flag ready
+not$q:
+ cp ctls
+ jr nz,not$s ; if its a ctl-S,
+ ld a,00h ; clear the flag
+not$s:
+ ld (hl),a ; save the flag
+ call cost1 ; get the actual output status,
+ and (hl) ; and mask with ctl-Q/ctl-S flag
+ ret ; return this as the status
+
+cist1: ; get input status with <BC> and <HL> saved
+ push bc
+ push hl
+ call ?cist
+ pop hl
+ pop bc
+ or a
+ ret
+
+cost1: ; get output status, saving <BC> & <HL>
+ push bc
+ push hl
+ call ?cost
+ pop hl
+ pop bc
+ or a
+ ret
+
+ci1: ; get input, saving <BC> & <HL>
+ push bc
+ push hl
+ call ?ci
+ pop hl
+ pop bc
+ ret
+
+
+ ; AUXIST
+ ; Auxiliary Input Status. Return true if
+ ; any selected auxiliary input device
+ ; has an available character.
+?auxis:
+auxist:
+ ld hl,(@aivec) ; get aux input bit vector
+ jr ist$scan
+
+
+ ; CONST
+ ; Console Input Status. Return true if
+ ; any selected console input device
+ ; has an available character.
+?const:
+const:
+ ld hl,(@civec) ; get console input bit vector
+
+
+ist$scan:
+ ld b,0 ; start with device 0
+cis$next:
+ add hl,hl ; check next bit
+ ld a,0 ; assume device not ready
+ call c,cist1 ; check status for this device
+ or a
+ ret nz ; if any ready, return true
+ inc b ; next device number
+ ld a,h
+ or l ; see if any more selected devices
+ jr nz,cis$next
+ xor a ; all selected were not ready, return false
+ ret
+
+
+ ; AUXIN
+ ; Auxiliary Input. Return character from first
+ ; ready auxiliary input device.
+?auxi:
+auxin:
+ ld hl,(@aivec)
+ jr in$scan
+
+
+ ; CONIN
+ ; Console Input. Return character from first
+ ; ready console input device.
+?conin:
+conin:
+ ld hl,(@civec)
+
+in$scan:
+ push hl ; save bit vector
+ ld b,0
+ci$next:
+ add hl,hl ; shift out next bit
+ ld a,0 ; insure zero a (nonexistant device not ready).
+ call c,cist1 ; see if the device has a character
+ or a
+ jr nz,ci$rdy ; this device has a character
+ inc b ; else, next device
+ ld a,h
+ or l ; see if any more devices
+ jr nz,ci$next ; go look at them
+ pop hl ; recover bit vector
+ jr in$scan ; loop til we find a character
+ci$rdy:
+ pop hl ; discard extra stack
+ jp ?ci
+
+
+
+xofflist:
+ db -1,-1,-1,-1,-1,-1,-1,-1 ; ctl-s clears to zero
+ db -1,-1,-1,-1,-1,-1,-1,-1
+
+
+ end
+
diff --git a/z180/chario.180 b/z180/chario.180
new file mode 100644
index 0000000..6632690
--- /dev/null
+++ b/z180/chario.180
@@ -0,0 +1,103 @@
+ page 255
+ .z80
+
+
+; CP/M 3 compatible character i/o
+
+ public ?cinit,?ci,?co,?cist,?cost
+ public @ctbl
+
+ extrn ff.init,ff.i.st,ff.in,ff.o.st,ff.out
+ extrn ser.init,ser.ist,ser.in,ser.ost,ser.out
+
+ include config.inc
+ include z180reg.inc
+ include modebaud.inc ; define mode bits and baud eqautes
+
+
+max$device equ 2
+
+ cseg
+
+; c = device
+
+?cinit: ; init devices
+ ld b,c
+ call vector$io
+ dw ff.init
+ dw ser.init
+ dw rret
+
+; b = device, c = output char, a = input char
+
+?ci: ; character input
+ call vector$io
+ dw ff.in
+ dw ser.in
+ dw null$input
+
+?cist: ; character input status
+ call vector$io
+ dw ff.i.st
+ dw ser.ist
+ dw null$status
+
+?co: ; character output
+ call vector$io
+ dw ff.out
+ dw ser.out
+ dw rret
+
+?cost: ; character output status
+ call vector$io
+ dw ff.o.st
+ dw ser.ost
+ dw ret$true
+
+vector$io:
+ ld a,max$device
+ ld e,b
+vector:
+ pop hl
+ ld d,0
+ cp e
+ jr nc,exist
+ ld e,a ; use null device if a >= max$device
+exist: add hl,de
+ add hl,de
+ ld a,(hl)
+ inc hl
+ ld h,(hl)
+ ld l,a
+ jp (hl)
+
+
+null$input:
+ ld a,1Ah
+rret:
+ ret
+ret$true:
+ or 0FFh
+ ret
+
+null$status:
+ xor a
+ ret
+
+;--------------------------------------------------------------
+
+
+@ctbl:
+ db 'HOST ' ; device 0
+ db mb$output
+ db baud$none
+
+ db 'ASCI1 ' ; device 0
+ db mb$in$out+mb$serial+mb$soft$baud
+ser1$baud:
+ db baud$19200
+
+ db 0 ; table terminator
+
+ end
+
diff --git a/z180/conbuf-a.180 b/z180/conbuf-a.180
index 3ec84d4..8534f73 100644
--- a/z180/conbuf-a.180
+++ b/z180/conbuf-a.180
@@ -4,7 +4,7 @@
;
; FIFO channels for communication with avr
;
- global ff.init,ff.in,ff.out,ff.i.st
+ global ff.init,ff.in,ff.out,ff.i.st,ff.o.st
extrn buf.init
@@ -105,6 +105,7 @@ buf.put:
push bc
push ix
pop hl
+ ld a,c
ld c,(ix+o.in_idx) ;
ld b,0
add hl,bc
diff --git a/z180/console.180 b/z180/console.180
index 07fb570..d4f4130 100644
--- a/z180/console.180
+++ b/z180/console.180
@@ -7,9 +7,9 @@
global $co
- extrn ser.init,ser.instat,ser.in,ser.out
- extrn ff.init,ff.i.st,ff.in,ff.out
- extrn ff.out
+ extrn ser.init,ser.ist,ser.in,ser.ost,ser.out
+ extrn ff.init,ff.i.st,ff.in
+ extrn ff.o.st,ff.out
include config.inc
@@ -27,13 +27,13 @@ $coninit:
$cists:
call ff.i.st
ret nz
- call ser.instat
+ call ser.ist
ret
$ci:
call ff.i.st
jp nz,ff.in
- call ser.instat
+ call ser.ist
jp nz,ser.in
jr $ci
diff --git a/z180/ddtz.180 b/z180/ddtz.180
index 77da910..e544b08 100644
--- a/z180/ddtz.180
+++ b/z180/ddtz.180
@@ -1,7 +1,7 @@
page 255
.z80
- external $ci, $co, $cists
+ extrn ?const,?conin,?cono
global ddtz,bpent
global $stack
@@ -27,7 +27,7 @@ BP_CNT equ 12 ;number of breakbpoints
;--------------------------------------------------
-;
+;
; copy code to common memory and execute it there
comst macro
@@ -103,17 +103,17 @@ ddtz:
ld hl,sysramc
ld de,topcodbeg
ld bc,topcodend-topcodbeg
- ldir
-
+ ldir
+
ld hl,vartab
ld de,ddtram
ld bc,vartabe-vartab
- ldir
+ ldir
exx
ld a,e
ld (ubbr),a
-
+
ddtz_w:
ld hl,MSG ;073c
call PSTR ;073f
@@ -203,29 +203,53 @@ CMD.?:
call PSTR
ret
+$ci:
+ push hl
+ push de
+ push bc
+ call ?conin
+ pop bc
+ pop de
+ pop hl
+ ret
+
+$co:
+ push hl
+ push de
+ push bc
+ ld c,a
+ call ?cono
+ pop bc
+ pop de
+ pop hl
+ ret
+
DELC:
- ld a,b ;07f2
- or a ;07f3
- ret z ;07f4
- ld a,BS ;07f5
- call $co ;07f7
- ld a,' ' ;07fa
- call $co ;07fc
- ld a,BS ;07ff
- call $co ;0801
- dec hl ;0804
- dec b ;0805
- inc c ;0806
- ld a,(hl) ;0807
- cp ' ' ;0808
- ret nc ;080a
- ld a,BS ;080b
- call $co ;080d
- ld a,' ' ;0810
- call $co ;0812
- ld a,BS ;0815
- call $co ;0817
- ret ;081a
+ ld a,b
+ or a
+ ret z
+ call DELC1
+ dec hl
+ dec b
+ inc c
+ ld a,(hl)
+ cp ' '
+ ret nc
+DELC1:
+ push de
+ push hl
+ push bc
+ ld c,BS
+ call ?cono
+ ld c,' '
+ call ?cono
+ ld c,BS
+ call ?cono
+ pop bc
+ pop hl
+ pop de
+ ret
+
DELL:
ld a,b ;081b
or a ;081c
@@ -472,22 +496,34 @@ l0960h:
outquote:
ld a,'''' ;0979
OUTCHAR:
- push hl ;097b
- push af ;097c
- and 07fh ;097d
- call $co ;097f
- ld hl,CON.COL ;0982
- inc (hl) ;0985
- pop af ;0986
- pop hl ;0987
+ push hl
+ push de
+ push bc
+ push af
+ and 07fh
+ ld c,a
+ call ?cono
+ ld hl,CON.COL
+ inc (hl)
+ pop af
+ pop bc
+ pop de
+ pop hl
ret ;0988
inchar:
- call $cists ;0989
- and a ;098c
- ret z ;098d
- call $ci ;098e
+ push hl
+ push de
+ push bc
+ call ?const
+ and a
+ jr z,inch1
+ call ?conin
scf ;0991
+inch1:
+ pop bc
+ pop de
+ pop hl
ret ;0992
PSTR:
@@ -1816,7 +1852,7 @@ l1144h:
inc hl ;1176
ld a,d ;1177
comrep ;1178
-
+
else
ld a,(ddtrst) ;115c
@@ -4649,7 +4685,7 @@ b_0x2108_start: ; 1 byte opcodes
defb 08bh ;2137
defw l2561h ;2138
- defb 0c7h ;213a rst
+ defb 0c7h ;213a rst
defb 0c7h ;213b
defb 0b4h ;213c
defw l231eh ;213d
diff --git a/z180/modebaud.inc b/z180/modebaud.inc
new file mode 100644
index 0000000..2e60e44
--- /dev/null
+++ b/z180/modebaud.inc
@@ -0,0 +1,31 @@
+ ; equates for mode byte bit fields
+
+mb$input equ 00000001b ; device may do input
+mb$output equ 00000010b ; device may do output
+mb$in$out equ mb$input+mb$output
+
+mb$soft$baud equ 00000100b ; software selectable
+ ; baud rates
+
+mb$serial equ 00001000b ; device may use protocol
+mb$xon$xoff equ 00010000b ; XON/XOFF protocol
+ ; enabled
+
+baud$none equ 0 ; no baud rate associated
+ ; with this device
+baud$50 equ 1 ; 50 baud
+baud$75 equ 2 ; 75 baud
+baud$110 equ 3 ; 110 baud
+baud$134 equ 4 ; 134.5 baud
+baud$150 equ 5 ; 150 baud
+baud$300 equ 6 ; 300 baud
+baud$600 equ 7 ; 600 baud
+baud$1200 equ 8 ; 1200 baud
+baud$1800 equ 9 ; 1800 baud
+baud$2400 equ 10 ; 2400 baud
+baud$3600 equ 11 ; 3600 baud
+baud$4800 equ 12 ; 4800 baud
+baud$7200 equ 13 ; 7200 baud
+baud$9600 equ 14 ; 9600 baud
+baud$19200 equ 15 ; 19.2k baud
+
diff --git a/z180/r3init.180 b/z180/r3init.180
index 2dd1bb8..9adbdd8 100644
--- a/z180/r3init.180
+++ b/z180/r3init.180
@@ -3,7 +3,7 @@
extrn ddtz,bpent
extrn $stack
- extrn $coninit,$cists,$ci
+ extrn charini,?const,?conin
extrn romend
@@ -73,17 +73,20 @@ hwini0:
;----------------------------------------------------------------------
start:
- push af ;003c
- in0 a,(itc) ;003d Illegal opcode trap?
- jp p,??st01 ;0040
- pop af ;0043
- jp bpent ;0044 yes, handle
+ ld (tmpstack),sp
+ ld sp,tmpstack
+ push af
+ in0 a,(itc) ;Illegal opcode trap?
+ jp m,??st01
+ ld a,i ;I register == 0 ?
+ jr z,??st02 ; yes, harware reset
??st01:
- ld a,i ;0047 I register == 0 ?
- jr z,??st02 ;004b yes, harware reset
- pop af ;004d
- jp bpent ;004e no, allready set up
+ ld a,(syscbr)
+ out0 (cbr),a
+ pop af ;restore registers
+ ld sp,(tmpstack) ;
+ jp bpent ;
??st02:
di ;0058
@@ -189,6 +192,8 @@ ramok:
alloc:
out0 (cbr),c ;01de
+ ld a,c
+ ld (syscbr),a
ld sp,$stack ;01e1
; Clear RAM using DMA0
@@ -280,7 +285,7 @@ wstart:
call prt0_init
- call $coninit
+ call charini
call bufferinit
@@ -289,15 +294,21 @@ wstart:
im 2 ;?030e
ei ;0282
- call $cists ;0284
- call $cists ;0287
+ call ?const ;0284
+ call ?const ;0287
or a ;028a
- call nz,$ci ;028d
+ call nz,?conin ;028d
ld a,(banktab) ;
ld e,a ;
jp ddtz ;0290
+
+ ds 8
+tmpstack:
+ dw 2
+syscbr: db 1
+
;
;----------------------------------------------------------------------
;
diff --git a/z180/ser1-i.180 b/z180/ser1-i.180
index 4074a9d..2410e38 100644
--- a/z180/ser1-i.180
+++ b/z180/ser1-i.180
@@ -6,8 +6,8 @@
global ser.init
- global ser.instat,ser.in
- global ser.out
+ global ser.ist,ser.in
+ global ser.ost,ser.out
;TODO: define a trampoline area somewhere in top ram.
rtxisvjmp equ 0FF60h ;momentan frei...
@@ -78,7 +78,7 @@ ser.init:
; ei
ret ;
-ser.instat:
+ser.ist:
push ix
ld ix,ser1.inbuf ;
@@ -126,7 +126,7 @@ bg.w1:
ret ; 9
; 153
-ser.outstat:
+ser.ost:
push ix
ld ix,ser1.outbuf ;
buf.full:
@@ -148,6 +148,7 @@ buf.put:
push bc
push ix
pop hl
+ ld a,c
ld c,(ix+o.in_idx) ;
ld b,0
add hl,bc