|Z88 Developers' Notes|
Filters, as provided on the Z88, are a fairly general means of achieving simple context-independent transformations in a character sequence. Their anticipated use is in simple text processing, but they may potentially be used for more complex tasks. The calls for handling filters are:
GN_Flo open a filter, returning a filter handle GN_Flw write a character to a filter GN_Flr read a character from a filter GN_Fpb push a character back into the filter GN_Flf flush the filter GN_Flc close the filterTo use a filter, the programmer must first set up a 'Filter Definition Table' (FDT), which determines the operation of the filter. The filter must then be opened with GN_Flo with the programmer giving the address of the FDT and setting various input parameters. GN_Flo returns a filter handle which the other filter routines takes as input. Once open the filter can be written to a byte at a time using GN_Flw and read from (again a byte at a time) using GN_Flr. The bytes read out of the filter will be the processed form of the input; if processing has occurred on a particular character this is indicated ny Fz = 1 on return from GN_Flr. While the filter is open, it can be flushed, ie. all the characters written to it, but not read out, can be discarded. It is also possible to push one character back into the filter, before a subsequent filter read takes place. Finally the filter is closed using GN_Flc, which apart from freeing the handle and buffers associated with the filter also returns information as to how many characters have been written to and read from the filter.
Note that filters can be used with a number of GN calls, in place of a source or destination which is in memory or a stream. Calls which can operate with filter are:
GN_Fcm compress a filename GN_Fex expand a filename GN_Gdn convert ASCII decimal string to integer GN_Pdn convert integer to ASCII decimal string GN_Gtm convert ASCII string to internal time GN_Ptm convert internal time to ASCII string GN_Pdt convert internal date to ASCII string GN_Gdt convert ASCII string to internal date GN_Skc skip character GN_Skd skip to delimiter GN_Skt skip to valueHow the filter works
The filter definition table provides a list of strings to be searched for in the input sequence, and when one is found it will replace the found string with a replacement string also specified in the table. The table might contain the contain the following pairs of strings:
Search Replace Monday Mon Tuesday Tue Wednesday Wed Thursday Thu Friday Fri Saturday Sat Sunday SunIf the characters M,o,n,d,a,y - were pushed into the filter, then the characters pulled from the other end (via GN_Flr) would be: M,o,n - and then and 'End of file' return code, RC_EOF ($09), would be encountered. Thus the filter provides a convenient means of performing simple text processing.
Because the filter can only search for strings to substitute amongst characters which are 'in' the filter, the normal use is to push in the entire input string and pull out the entire result, each in one go. Also note that the filter routine will select the first successful match in the FST, so if one of the search strings is an extension of another, the longer should come first if the obvious substitution is required. For instance:
Mon Lundi Monday Lundiwould result in the transformation of "Monday" into "Lundiday"; probably not what was intended.
Filter Definition Table
2 bytes Size of FDT in bytes 1 byte Options for left-hand strings 1 byte Options for right-hand stringsThe options for the strings may be made up of some combination of the following bit settings:
128 Table has top bit set characters (ISO standard) 64 Table has numeric data 32 Table has alphabetic data 16 Table has puncuation charactersThen come the entries, with the following format:
1 byte 1+m m bytes search string 1 byte 1+n n bytes replacement stringThe 'length bytes are actually a displacement to the character beyond the next string, hence they are one greater than the length of the string.
RESTRICTIONS: The FDT must not span a 16K boundary, and due to a software bug, the FDT must be addressed in segment 1.
The filter calls are fully specified in "System Calls Reference".
include ":*//memory.def" ; memory call definitions include ":*//stdio.def" ; standard I/O definitions; it is assumed that this code would be running in segment 3
.abbreviate ld c, MS_S3 ; assumes table is in segment 3 call_oz(OS_Mgb) ; get binding of segment 3 ld c, MS_S1 call_oz(OS_Mpb) ; bind table into segment 1. Note bank ; is still bound to segment 3 ld hl, fdt_Table ; start address of table ld a,h and @00111111 ; mask out segment bits (15, 14) or MM_S1 ; merge memory mask for segment 1 ld h,a ; HL now addresses segment 1 ld a, 4 ; buffer size in B ld b, 30 ; buffer size call_oz(GN_Flo) ; open filter ret c ; exit if error ld hl, (input_string) ; address of string to process .loop ld a,(hl) cp 0 jr z, end_loop call_oz(GN_FPW) ; write character to filter inc hl jr loop .end_loop call_oz(GN_Flr) ; pull character from filter jr c, finished ; exit if last one or error call_oz(OS_Out) ; write converted char to std. output jr end_loop .finished call_oz(GN_Flc) ; close the filter call_oz(GN_Nln) ; new line ret .fdt_start defw fdt_end-fdt_start ; length of FDT defb 32 ; search string alphabetic defb 32 ; replace string alphabetic defm 7 & "Monday" ; abbreviate Monday defm 4 & "Mon" defm 8 & "Tuesday" ; abbreviate Tuesday defm 4 & "Tue" defm 10 & "Wednesday" ; abbreviate Wednesday defm 4 & "Wed" defm 9 & "Thursday" ; abbreviate Thursday defm 4 & "Thu" defm 7 & "Friday" ; abbreviate Friday defm 4 & "fri" defm 9 & "Saturday" ; abbreviate Saturday defm 4 & "Sat" defm 7 & "Sunday" ; abbreviate Sunday defm 4 & "Sun" .fdt_end ; end of table
|Input and the keyboard decoder||Filters||Time and date management|