The DDmmmYYYY character font

Interpreting a numeric DATE string added by a VTI (Video Time Inserter) can be a real problem when much CCTV kit is designed in the USA. This is because the US software inevitably shows the data as Month Day Year, whilst here in Europe we use Day Month Year. Of course both are wrong (Year, Month, Day is what you need if you expect to 'sort' anything in data order) One way to eliminate the doubt is to show the Month as a 3 character string, rather than a 2 digit number The 'simplest' character shapes that are legible are defined in a 5x7 (5 pixel wide, 7 line high) character 'map'. To output the time and date as "DD mmm YYYY hh:mm:ss.ss", the character set we must define is :- The numbers [0-9], 10 maps (70 table entries) plus The 3 char month names [Jan, Feb, Mar, Apr, May, Jun, Jly, Aug, Spt, Oct, Nov, Dec] Whilst the characters could be held in any order, alphabetic makes is easier to remember :- A a b c D e F g J l M N n O o p r S t u v y = 22 char. maps Total 10+22 = 32 @ 7 lines ea. = 224 bytes (assuming we use 1 byte for each of the 5 pixels i.e. no packing) The required punctuation ('space', ':', '.') can all be 'hard coded' rather than 'mapped'
Note that the bit map is output 'MSB first' (i.e. it's 'shifted up') which means the maps have to be held as 'mirror images' in b0-b4

The 16F54 has only 256 'Call' locations, so using 224 locations for the pixel map Data Table leaves only 32 into which we have to fit all the subroutine 'Call' hooks !

This means that the 3 character month will only be possible with the 16F57 or 59 (which has 2k instruction space in 54 pages, i.e. 4 sets of 256 Tables)

Loading the 3 character month pixel maps

Generating a 3 char month is a bit complex. If the month value held a decimal count (0-11 or 1-12) we could use that as an index into a pre-character Table to pre-load the string registers with the required character code offsets. However that not only requires another data table (of 12x3 = 36 entries) but also wastes time (the Call, computed Jump, Return is at least 6 clks, plus we have to copy the count to the Acc before calling and then copy the Acc to the Register after Return for at least 2 more). So, instead, we will have to 'hard code' a sequence of CALL's into the pixel map table

; Get the 3 alpha offsets into the 3 mmm Registers (mInitial, m10s, m1s). ; Current month is in MmmReg, value 1-12 (binary). slInit: loadMonth: ;CALL here to load the 3 month regs with the char codes DEC MmmReg,Acc ; Month 0-11, to Acc CLR Cy ; make sure Cy clear ROTL Acc ; double the month ROTL Acc ; double again (now have 0,4,8, .. each load takes 8 instructions ) ADD Acc,PCL ; Jump to the correct month load code ; Here for Jan (each month requires 8 inst) LOAD 'J',Acc CALL getMap: COPY Acc,mInitial ; save msb pixel map LOAD 'a',Acc CALL getMap: COPY Acc,m10s ;save middle pixel map LOAD 'n',Acc JMP getMap: ; shape table RET will return to original calling routine ; Note: the calling routine must save the lsb pixel map (COPY Acc,m1s) ; ; Here for Feb (each month requires 8 inst) LOAD 'F',Acc ... ; main line code CALL loadMonth: ;load mInitial, m10s pixel maps COPY Acc, m1s ;load m1s pixel map ...

NOTE that loading a 3 character alphabetic month consumes at least 12x8 = 96 instructions of Low address space (so, again, this is only on the 2k instruction space 16F57/9))

Adding a day post-fix

The 16F57/9 has enough space to add day post-fix '1st, 2nd, 3rd, 4th ...') at a 'cost' of only 3 more character (s d h)

The pixel bit map Data Tables

Note that, after the Table is CALL'd, the Data Table values are accessed with a calculated jump (using a 'Copy Acc to PCL' command), so the entire table must be within the first 256 locations.

Since the Month character maps depends on the device used (16F54 or 57/9), a separate Month table will be used. This means the numeric pixel map is common for all devices

The Table has to be organised in 'scan line sets' (i.e. sets of 10 scan lines, one for each numeral (0-9) together)

The 'punctuation' marks (. and :) are present in b7 of the relevant scan line pixel maps. The output code will only 'use' these bits if the number is in one of the units positions (so the bits never appear when '10's are output). To avoid a '.' turning into a ':', on return, b7 is cleared in the unit seconds except for the bottom scan-line 6
; numeric Table, Call here getNoMap: AND 0x0F ; remove top nibble (1) ADD slNumb,Acc ; add the current scan line number, char top 0, to 7 char bottom line (1) ADD Acc,PCL ; get the map (+2 CLK) ; The call (+2) has to load the Acc, so +1 and on return (+2) save the shape (+1), so total is 10 CLK's per digit slNumb: RET No0line0 ; bit map for '0' (and 'mark' in top bits) for top scan line, return with data (= +2 CLK) RET No1line0 ; ... 9 more locations consisting of scan line N defn. for No. 1-9 .. RET No0line1 .. RET No0line2 .. .. RET No0line6 ;last set of 10 (7th = bottom scan line)

Since a 'computed jump' is required for each character (there is no such thing as a 'computed Call'), there is no simple** way to look up the pixel maps any faster

**A rather more complex way does exist - manipulating the Return Stack and performing Returns without a Call - however that only saves significant CLK cycles when loading a series of shapes using INDF register addressing