home *** CD-ROM | disk | FTP | other *** search
- ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- ; This is a library of routines for interfacing to PL/I-80
- ; which supports some added features due to SME Systems hardware
- ; and some other nifty things.
- ;
- ; This version contains....
- ;
- ; INITRND Initialize a random number seed
- ; RAND16 Return a random number +-32k in size
- ; RANDP16 Return a positive random number 0..32k
- ; RAND8 Return an 8 bit number +-127
- ; CLKRD Read the real time clock on SBC-800 into ram
- ; CONIN Return a character from the console
- ; CONST Return the console status
- ;
- ; Extended and patchable screen functions.
- ;
- ; CLEAR Erase the screen
- ; CLEOL Clear to end of line
- ; CLEOP Clear to end of page
- ; SETXY Position cursor to X, Y co-ords
- ; SETREV Initialize reverse video
- ; SETUND Initialize underlined characters
- ; SETHLF Initialize half intensity characters
- ; SETBLK Initialize blinking characters
- ; CLRATT Clear the current attribute
- ; CURON Enale the cursor
- ; CUROFF Disable the cursor
- ;
- ;
- ; For full documentation on this lot, see SMEPLI DOCUMENTATION which
- ; contains examples etc. (if you are lucky)
- ;
- ; Written R.C.H. 26/10/83
- ; Last Update R.C.H. 28/11/83
- ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- ;
- name 'SMEPLI'
- maclib z80
- public conin,const,initrnd,randp16,rand16
- public rand8,clkrd
- ;
- ;
- bdos equ 5
- ;
- ;----------------------------------------------------------------
- ; CONIN - Get a character from the console
- ;
- ; This function returns the first character typed on the keyboard.
- ; The character is returned as char(1) to PL/I.
- ;
- ; This function uses the bdos function 10 to return the character
- ; which is not echoed as it is received. This is l;eft to the user.
- ;----------------------------------------------------------------
- ;
- conin:
- call cst
- jrz conin ; wait for a character
- ; Now do a direct bdos call for the character
- conin1:
- mvi e,0ffh ; get character routine
- mvi c,06 ; direct console i/o
- call bdos ; character is in A now
- ora a
- jrz conin1 ; if no character, wait for it
- ; Now load the character onto PL/I's stack
- pop h ; drop off return address
- push psw ; put the character onto it
- inx sp ; bump stack
- mvi a,1 ; characters on stack = 1
- pchl ; trick return
- ;
- ;----------------------------------------------------------------
- ; CONST - Get the console status.
- ;
- ; If a character is ready then the return is a true flag else
- ; a false flag is returned. This function uses the bdos function
- ; 10 to detect if the character is there.
- ;----------------------------------------------------------------
- ;
- const:
- call cst ; get the status
- ora a ; zero ?
- rz ; return if so
- mvi a,0ffh ; clean true value
- ret ; if not then make it positively so
- ;
- ; The following code merely uses bdos function 11 to return the console
- ; status.
- ;
- cst:
- push h
- push b
- push d
- mvi c,11 ; get console status fumction
- call bdos
- pop d
- pop b
- pop h
- ora a ; Set the flag 00 = not ready
- ret
- ;
- ;----------------------------------------------------------------
- ; CLKRD - Read the real time clock
- ;
- ; This function uses the SBC-800 real time clock to return the
- ; time into a piece of memory that may be either bit(8) or bin(7)
- ; or whatever. I like using a structure laid out with
- ; fileds called year,month,day,dow,hour,minute,second declared as
- ; bit(8) or bin(7) where appropriate.
- ;
- ; The following equates specify the port addresses of the real time clock
- ; chip and interface. The clock chip is an OKI 5832 and the interface
- ; is an intel 8255.
- ;
- ; HACKERS - The following is a particularly nasty piece of code
- ; which holds the OKI 5832 clock chip and reads all the
- ; internal registers. If running at 6Mhz then the timing loops
- ; for the hold times may need expanding out to suit.
- ;
- ;----------------------------------------------------------------
- ;
- ;Clock and centronics ports on the sbc-800
- ;
- pp0a equ 84h ; Port a 0
- pp0b equ pp0a+1 ; Port b 0
- pp0c equ pp0a+2 ; Port c 0
- pp0d equ pp0a+3 ; Control port 0
- ;
- ; I/O lines and part of clock strobe
- ;
- pp1a equ 80h ; Port a 1
- pp1b equ pp1a+1 ; Port b 1
- pp1c equ pp1a+2 ; Port c 1
- pp1d equ pp1a+3 ; Control port 1
- ;
- ;****************************************************************
- ;* Read Real Time Clock to memory *
- ;* pointed by DE, and stored as follows *
- ;* *
- ;* hl+0 => years 1 byte 2 digit bcd *
- ;* +1 => months 1 byte 2 digit bcd *
- ;* +2 => days 1 byte 2 digit bcd *
- ;* +3 => dweek 1 byte 1 digit bcd ** low nibble only ***
- ;* +4 => hours 1 byte 2 digit bcd *
- ;* +5 => minutes 1 byte 2 digit bcd *
- ;* +6 => seconds 1 byte 2 digit bcd *
- ;* *
- ;****************************************************************
- ;
- ; Note that the user passes a POINTER to this function which then
- ; writes the bytes to the address for 7 bytes. Use carefully, it is
- ; a good routine to corrupt memory if poorly used.
- ;
- clkrd: ; Read clock into memory at DE
- call getp2 ; return the address in de
- xchg ; put into hl
- ;
- ; Here try to hold the clock chip for 150 us.
- mvi a,00001101b ; Hld bit
- out pp0d ; Set bit
- ; Now load a counter for a 150 us delay.
- mvi b,120 ; 7 T
- ;
- hld$wait:
- djnz hld$wait ; 8/10 T
- ;
- out pp1d ; this is the read bit load
- ; Loop to read all registers in one go
- mvi b,12 ; register count
- rclk1:
- call get$reg
- mov a,b
- cpi 6 ; Was it day of week
- jrz rclk2 ; Skip second register if so
- dcr b ; Next register
- call get$reg ; read the register
- rclk2: ; Jump here after reading day of week
- inx h ; next byte in ram to rotate into
- dcr b ; register number
- xra a
- ora b ; set the minus flag
- jp rclk1
- ; restore the port bits
- mvi a,00001100b ; Reset bit 6
- out pp0d
- out pp1d ; Clear hold+read
- ret
- ;
- get$reg: ; Read register in B into memory with an RLD
- mov a,b
- out pp0b
- mvi a,8
- rdreg1: ; This loop is needed for a 6 us delay for reading the register
- dcr a
- jrnz rdreg1 ; another wait of 15 us or better
- in pp0a
- ani 15 ; Get data
- rld ; Saved in memory
- ret
- ;
- ;----------------------------------------------------------------
- ; RANDOM NUMBER ROUTINES
- ;
- ; These routines intialize/return random numbers. The user must
- ; feed these routines a string of bytes (5 minimum) which are used as
- ; a seed. The initialization uses the Z-80 refresh register as a
- ; jumble function of these bytes.
- ;
- ; This is a module in the ASMLIB Library.
- ;
- ; This module generates PSEUDO RANDOM NUMBERS by using a seed array
- ; and doing adds and shifts on the bytes in the array.
- ;
- ;----------------------------------------------------------------
- ;
- initrnd: ; initialize the random number seed string pointed to
- call getp2 ; get the pointer to the string
- ldax d ; get the string size
- cpi 5
- rc ; Error if less than 5 elements in the array
- push d
- push b
- mov b,a ; Load counter
- xchg
- inx h ; Now HL -> first seed byte
- ldar ; Get refresh register value
- dcr b ; Do one less than the required
- initloop:
- add m
- rrc
- mov m,a
- inr m
- mov a,m
- inx h
- djnz initloop
- ; Restore and exit gracefully
- xchg ; Restore HL
- pop b
- pop d ; Restore other registers
- ret
- ;
- ; Return an 8 bit random number in A
- ;
- rand8:
- call getp2 ; get the strings address
- rand81:
- ldax d ; A = number of seeds
- cpi 5 ; Check if less than 5 seed values
- rc ; Return with a carry to indicate an error
- ; Here we load the number of cells into B then decrtement so as to skip
- ; these which are operated on later.
- push b
- push d ; Saver address of seed array
- mov b,a
- dcr b
- dcr b
- inx d ; DE -> first seed in the array
- xchg ; Put memory pointer into HL
- ;
- ;Loop for N-2 times.
- loop: inr m ;INCREMENT SEED VALUE.
- mov a,m
- inx h ;HL POINTS TO NEXT SEED VALUE IN ARRAY.
- add m
- rrc ;ROTATE RIGHT CIRCULAR ACCUMULATOR.
- mov m,a
- djnz loop
- ;
- ; Last iteration to compute random byte in register a.
- inx h ; HL -> last byte in the array
- add m
- cma ; complement the accumulator
- rrc ; rotate it right
- mov m,a
- xra a ; Clear carry
- mov a,m ; Re-load value, carry not set.
- ;
- ; Restore the registers and return with the value in A
- error:
- xchg ; Restore HL
- pop d
- pop b
- ret
- ;
- ; Return a 16 bit random number in HL.
- ;
- rand16:
- call getp2 ; get string address
- push d
- call rand81
- mov h,a ; msb byte
- pop d ; restore string address
- call rand81
- mov l,a ; lsb byte
- ret
- ;
- ; Return a positive 16 bit random number
- ;
- randp16:
- call rand16 ; get the number
- mov a,h
- ani 07fh ; Mask off top bit
- mov h,a ; restore
- mov a,l ; echo lsb in a
- ret
- ;
- getp1:
- mov e,m
- inx h
- mov d,m
- xchg
- mov e,m
- ret
- ;
- ;
- getp2:
- call getp1
- inx h
- mov d,m
- ret
- ;
- ;----------------------------------------------------------------
- ; Screen Based Functions.....
- ;
- ; These are taken from the ASMLIB source code modules and as such are
- ; patchable to suit a termial in use by using the SETUP.COM program
- ; to write the correct terminal driver into the code patch area.
- ;----------------------------------------------------------------
-
-
-
- end
-
-
-