TITLE IO SYSTEM MODULE ; USE M80 TO COMPILE true equ -1 false equ 0 banked equ true .Z80 entry ?cinit,?ci,?co,?cist,?cost,@ctbl if banked extrn ?bank,?rbank,?bank0 endif .COMMENT * DEVICE NUMBER IN B CHARACTER FOR OUTPUT IN C - CHARACTER RETURNED TO A ?cinit INITIALIZE DEVICE - DEVICE NUMBER IN C ?ci CHARACTER IN ?co CHARACTER OUT ?cist INPUT STATUS ?cost OUTPUT STATUS ?bank BANK CHANGE ?rbank RESTORE BANK ?bank0 SET BANK 0 @ctbl CHARACTER DEVICE TABLE * mbin equ 1 ; device may do input mbout equ 2 ; device may do output mbio equ 3 ; both input and output mbsb equ 4 ; software selectable baud rates mbser equ 8 ; serial device mbx equ 16 ; xon/xoff protocol bnone equ 0 ; no baud rate associated b50 equ 1 ; 50 baud b75 equ 2 ; 75 baud b110 equ 3 ; 110 baud b134 equ 4 ; 134.5 baud b150 equ 5 ; 150 baud b300 equ 6 ; 300 baud b600 equ 7 ; 600 baud b1200 equ 8 ; 1200 baud b1800 equ 9 ; 1800 baud b2400 equ 10 ; 2400 baud b3600 equ 11 ; 3600 baud b4800 equ 12 ; 4800 baud b7200 equ 13 ; 7200 baud b9600 equ 14 ; 9600 baud b19200 equ 15 ; 19.2k baud if banked maxdev equ 8 ; 8 devices defined else maxdev equ 7 ; 7 if unbanked - exclude double size endif cseg ?cinit: ; initialize devices ld b,c ; device number is in c call jump inittb: db init0-inittb ; screen db indev-inittb ; keyboard & tv monitor db noinit-inittb ; printer db indev-inittb ; modem db noinit-inittb ; mouse db noinit-inittb ; screen - graphics db indev-inittb ; tape if banked db noinit-inittb ; screen - double size endif noinit: ret ; no initializing init0: ld a,1 ; reset micro-angelo out (0e1h),a ld a,0 out (0e1h),a ld a,'A' ld (mahndl),a ; handler 'A' setup ld hl,maalp ; send setup chars to a ld bc,04e0h ; count and port jp macyc ; jump to macycle and return indev: ; clear input device call ?cist ; input status and a ; set flags ret z ; return if buffer clear call ?ci ; get character jr indev ; try again ?ci: ; character input icyc: call ?cist ; get input status and a ; set flags jr z,icyc call jump itb: db nullin-itb db i1-itb ; keyboard db nullin-itb db i3-itb ; modem db i4-itb ; mouse db i5-itb ; graphics board input db i6-itb ; tape if banked db nullin-itb endif nullin: ld a,1ah ; return a cntl-z for no device ret i1: if banked call ?bank0 ; bank 0 endif ld a,(0e3f8h) ; get this straight from the dj if banked call ?rbank ; restore bank endif cpl ; dj requires this ret i3: in a,(1) ret i4: in a,(0) ret i5: in a,(0e0h) ret i6: in a,(6fh) ret ?co: ; character output ocyc: call ?cost ; get status and a ; get flags jr z,ocyc ; wait till clear call jump otb: db o0-otb ; screen - alpha mode db o1-otb ; TV monitor db o2-otb ; printer db o3-otb ; modem db o4-otb ; sw serial port 1 db o5-otb ; screen - graphics mode db o6-otb ; tape if banked db o7-otb ; screen - double size endif nullou: ret ; no device o0: ld a,(mahndl) ; check handler being used cp 'A' jr z,o0e ; jump if set up for alpha handler ld a,'A' ; update handler code ld (mahndl),a push bc ld hl,maalp ; send setup chars to a ld bc,06e0h ; count and port call macyc pop bc o0e: ld a,c cp 7 ; check for bell character jr z,o1 ; send bell char to dj cp 8 ; check for backspace character jr z,bs1 and 7fh ; truncate to 7 bits bs2: out (0e0h),a ; output character ret bs1: ld a,13h ; backspace without deleting jr bs2 o1: if banked call ?bank0 endif call 0e006h if banked call ?rbank endif ret o2: ld a,c out (4),a ; output character xor a ; clear a out (3),a ; strobe ret o3: ld a,c out (1),a ret o4: ld a,c out (0),a ret o5: ld a,(mahndl) ; check graphics handler cp 'G' jr z,o5e ld a,'G' ld (mahndl),a o5e: ld a,c out (0e0h),a ret o6: ld a,c out (6fh),a ret if banked o7: call ?bank0 ; work in banked memory jp o7b ; jump to banked memory dseg o7b: ld a,(mahndl) ; check double size handler cp 'D' jr z,o7e ld a,'D' ld (mahndl),a push bc ld hl,madou ; send setup chars to ma board ld bc,0Ce0h ; count and port call macyc pop bc o7e: ld a,c cp 7 ; bell code jp z,bell cp 8 ; back space jp z,bksp cp 0ah ; linefeed jp z,o7c ; ignore cp 0dh ; carriage ret jp z,carr ld a,98h ; code to send character call maout ld a,c ; send character call maout ; now to jump to new line if reqd call getcur ld a,d ; high x and a ; set flags jr z,o7x ; must be 1 for eol ld a,e ; low x cp 248 ; check at last location jr nz,o7x ; at end of line o7f: ld a,h ; high y and a ; set flags jr nz,o7j ; must be 0 for bottom line ld a,l ; low y and a ; set flags jr nz,o7j ; 0 for bottom line push hl ld hl,mascr ; force scroll using alpha cursor ld bc,04e0h call macyc ; to send stream of chars pop hl jr o7k o7j: ; advance cursor by one line ld de,-24 ; line spacing add hl,de ; next line o7k: ; output new cursor position ld a,84h ; to set location call maout ld de,0 call maoutx ; output de & hl o7x: ld a,95h call undlin ; to underline next location jp o7c bell: ; bell call 0e006h ; dj output (ok since we are in bank 0) jp o7c carr: ; carriage return call getcur ; get cursor location ld a,94h call undlin ; to clear cursor jp o7f ; jump to main routine bksp: ; backspace call getcur ; get cursor location xor a ; clear a or d ; check de = 0 or e jp z,o7c ; do nothing if at left margin ld a,94h call undlin ; to delete current underline push hl ld hl,-12 ; column spacing add hl,de ; hl contains x location ld a,84h ; to set location call maout ex de,hl pop hl call maoutx ; output de and hl jp o7x ; jump to main routine undlin: ; to set or reset underline call maout call maoutx ; output de & hl push de push hl ld hl,9 ; underline 10 units long add hl,de ex de,hl pop hl push hl inc hl ; to form double line call maoutx ; output de & hl pop hl pop de ret maoutx: ; send de and hl to ma board ld a,d call maout ld a,e call maout ld a,h call maout ld a,l call maout ret getcur: ld a,85h ; to get location of g-cursor call maout call main ld d,a ; high x call main ld e,a ; low x call main ld h,a ; high y call main ld l,a ; low y ret main: ; get char from ma board in a,(0e1h) and 2 jr z,main in a,(0e0h) ret maout: ; output char to micro angelo board push af maoutc: in a,(0e1h) and 1 jr nz,maoutc pop af out (0e0h),a ret ; characters to initialize ma board for double size madou: db 84h,0,0,1,200 ; set graphics cursor db 0ch ; clear screen db 99h,4 ; double size db 83h,2 ; pop up two alpha lines db 80h,16 ; turn off alpha cursor mascr: db 81h,39,0 ; set alpha cursor to bot line db 0dh ; carriage return cseg o7c: call ?rbank ret endif ?cist: ; character input status call jump isttb: db nullis-isttb db ist1-isttb ; keyboard db nullis-isttb db ist3-isttb ; modem db ist4-isttb ; mouse db ist5-isttb ; graphics board db ist6-isttb ; tape if banked db nullis-isttb endif nullis: ld a,0ffh ; return 0ffh for no device ret ; to prevent waiting forever for ; device to clear ist1: if banked call ?bank0 endif call 0e021h ; dj status routine if banked call ?rbank endif jr zrrd ; zero = ready ist3: in a,(2) ; switch board status and 64 ; serial input device 2 status jr nzrd ist4: in a,(2) ; switch board status and 4 ; serial input device 1 status jr nzrd ist5: in a,(0e1h) ; get status and 2 ; zero = not ready jr nzrd ist6: in a,(6eh) ; tarbell status and 16 ; input status jr zrrd ?cost: ; output status call jump osttb: db ost0-osttb ; screen - alpha mode db ost1-osttb ; tv monitor db ost2-osttb ; printer db ost3-osttb ; modem db ost4-osttb ; sw serial port 1 db ost0-osttb ; screen - graphics mode db ost6-osttb ; tape if banked db ost0-osttb ; screen - double size endif nullos: jp nullis ; same as input status ost0: in a,(0e1h) ; get status and 1 ; 0 = ready jr zrrd ost1: ld a,0ffh ; dj doesn't provide routine so ; don't implement this ret ost2: in a,(5) ; get status and 2 ; 0 = ready jr zrrd ost3: in a,(2) ; serial port status and 128 ; serial output device 2 jr nzrd ost4: in a,(2) ; serial port status and 8 ; serial output device 1 jr nzrd ost6: in a,(6eh) ; tarbell status and 32 ; bit 5 jr zrrd zrrd: jr z,nz1 ; 0 = ready zr1: xor a ; return 0 ret nzrd: jr z,zr1 ; 0 = not ready nz1: ld a,0ffh ; return -1 ret jump: ; jump to device instruction pop de ; get location of jump vector ld a,b cp maxdev ; check if defined device ret nc ld h,0 ld l,a add hl,de ; points to rel address of device routine ld a,(hl) ; relative address ld h,0 ld l,a add hl,de ; absolute address jp (hl) ; send stream of bytes to ma board macyc: in a,(0e1h) ; status and 1 jr nz,macyc ; cycle if not ready outi ; output with increment jr nz,macyc ret mahndl: ds 1 ; to show which ma handler is being used ; code to initialize ma board for alphabetic entry maalp: db 80h,60h ; set special & hi-speed modes db 83h,4 ; 4 line scroll db 0ch,0ch ; clear screen (twice) ; table of device characteristics @ctbl: db 'MA-ALP' ; device 0, screen - alphabetic db mbout db bnone db 'KEY/TV' ; device 1, keyboard & TV monitor db mbio+mbser+mbx db b300 db 'EPSON ' ; device 2, printer db mbout db bnone db 'MODEM ' ; device 3, modem db mbio+mbser db b300 db 'MOUSE ' ; device 4, mouse & serial port db mbio+mbser db b1200 db 'MA-GRA' ; device 5, screen - graphics mode db mbio db bnone db 'TAPE ' ; device 6, cassette tape db mbio db bnone if banked db 'MA-DOU' ; device 7, screen - double size print db mbout db bnone endif db 0 ; table end end ll maout ld a,c