title 'Character I/O handler for Tarbell based system' ; Copyright (c) 1983 Tarbell Electronics ; Version 1.0 4-12-83 ED SMITH ; Character I/O for the Modular CP/M 3 BIOS public ?cinit,?ci,?co,?cist,?cost public @ctbl maclib Z80 ; define Z80 op codes maclib modebaud ; define mode bits and baud euqates data$port set 0 status$port set 1 in$mask set 2 in$rdy$mask set 3 out$mask set 4 out$rdy$mask set 5 initial set 6 max$devices equ 2 ; only crt & printer supported cseg ; this table shows each device for use by the DEVICE utility @ctbl db 'CRT ' ; device 0, CRT port 0 db mb$in$out+mb$serial db baud$none db 'LPT ' ; device 1, LPT port 0 db mb$output+mb$serial db baud$none db 0 ; table terminator ; the following is a table of 8 bytes per device ; and defines the port #s status bytes ect. for use by ; the routines in this module dev$tab: ; CRT PORT A OF TARBELL CPU CARD db 00h ; data port db 01h ; comand / status port db 02h ; input mask db 02h ; input ready mask db 01h ; output mask db 01h ; output ready mask db 04h ; init table 0 - 4 bytes long db 00h ; reserved ; PRINTER PORT B OF TARBELL CPU CARD db 02h ; data port db 03h ; comand / status port db 02h ; input mask db 02h ; input ready mask db 81h ; output mask db 81h ; output ready mask db 14h ; init table 1 - 4 bytes long db 00h ; reserved ; device initialization table - 1 to 8 bytes for each device ; if init for 2 or more devices is the same may use same table ; byte 6 of dev$tab upper nib = ini$tab # (0-f) lower nib = ; length of init string (1-8). If byte 6 is 00h then no init will be done ini$tab: db 0aah,40h,0ceh,37h,0,0,0,0 ;init for crt db 0aah,40h,0ceh,37h,0,0,0,0 ;init for printer ; initialize device specified by register c ; regs used A,BC,DE,HL,IX none saved ?cinit: mov a,c ;put device # in A cpi max$devices rnc ; invalid device call dev$idx ; setup index ldx a,initial ; get init byte ora a rz ;return if no init push psw ;save init byte ani 0f0h ;mask upper nibble srlr a ;a= table # * 8 mov e,a ;de = relative offset mvi d,0 lxi h,ini$tab ;hl = beginning of table dad d ;add offset pop psw ;get init byte back ani 0fh ;mask count mov b,a ldx c,status$port ;get port # for init ;initialize device at port c with table at hl outir ret ; input character from device specified by B return with character ; in reg A with bit 7 cleared. do not return untill character is input ; regs used A,BC,IX none saved ?ci: mov a,b cpi 1 jnc null$input ; can't read from printer call dev$idx ; setup index ldx c,status$port ; get status port ci1: inp a ; get status andx in$mask ; mask status cmpx in$rdy$mask ; test status jnz ci1 ; wait for character ready ldx c,data$port ; get data port inp a ; get data ani 7Fh ; mask parity ret null$input: mvi a,1Ah ; return a ctl-Z for no device ret ; get input status of device specified by B ; return with A=0ffh if ready and A=0 if not ready ; regs used A,BC,IX none saved ?cist: mov a,b cpi 1 jnc null$status ; can't read from printer call dev$idx ; setup index ldx c,status$port ; get port # inp a ; get status andx in$mask ; mask status cmpx in$rdy$mask ; test status mvi a,0 rnz ; return not ready cma ret ; return ready null$status: xra a ret ; output character in C to device specified by B ; do not return untill done ; regs used A,BC,IX none saved ?co: mov a,b cpi max$devices rnc ; return if no device push b ; save character to output call dev$idx ; setup index ldx c,status$port ; get status port co$spin: inp a ; get status andx out$mask ; mask status cmpx out$rdy$mask ; test status jnz co$spin ; wait for transmitter ready pop b ; get character back mov a,c ldx c,data$port ; get data port outp a ; send data ret ; get output status of device specified by B ; return with A=0ffh if ready and A=0 if not ready ; regs used A,BC,IX none saved ?cost: mov a,b cpi max$devices ;test for no device jnc null$status call dev$idx ; setup index ldx c,status$port ; get port # inp a ; get status andx out$mask ; mask status cmpx out$rdy$mask ; test status mvi a,0 rnz ; return not ready cma ret ; return ready ; Setup index X to point to device table of device in A ; regs used IX,BC,A none saved dev$idx: add a ;* 2 add a ;* 4 add a ;* 8 mov c,a ;result in c mvi b,0 ;bc = relative offset lxix dev$tab ;device table to index X dadx bc ;add offset to index X ret end