;From: andrew.mcmeikan at mitswa.com.au ;be carefull when assembling ;there is a lookup table that MUST NOT cross a ;256 byte boundry ---- CHECK IT ;thermal printer controler innerloop = 0ff lilloop = 01 bigloop =0ff strobe macro bt SETB 13ドル.bt ;bit for strobe CLRB 0b.7 ;dont want interupts CALL outsr ;clock it out CALL lildly ;let it burn in SETB 0b.7 ;re-enable interupts CLRB 13ドル.bt ;so next outsr clears it endm ORG 0000ドル JMP main ORG 0004ドル ;entry occurs in here when host pulls strobe signal low ;to indicate data that requires printing ;useing this int routine occupies two levels of stack ;one for the return address and one for outsr's return ;centronics pinouts ; pin 1 strobe is connected to RB0 ; pin 2 data1 " " RA1 ; pin 3 data2 " " RA2 ; pin 4 data3 " " RA3 ; pin 5 data4 " " RA4 ; pin 6 data5 " " RB1 ; pin 7 data6 " " RB2 ; pin 8 data7 " " RB3 ; pin 9 data8 " " RB4 ; pin10 ack " " Cap from BSY this dips low ; when want next byte ; pin11 busy is connected to RA0 High= offline ; pin12 Paper out is connected to photocell High=no paper ;pins 19 to 30 are signal grounds GND ; pin31 INT is connected to RESET (via diode) ; and is used to initialize printer SETB RA.0 ;say we are busy ;read both ports to get byte of data MOV W, >>RA ;read port a shifting data down one AND W, #0f ;only keep bottom bits MOV 16,ドル W ;keep incomming data here MOV W, >>RB ;read port b shifting down one AND W, #0f ;wipe out extraneous bits MOV 17,ドル W ;waste another register MOV W, 17ドル ;get 'b' data lower into upper W OR 16,ドル W ;or top bits into data ;bit pattern from host now in 0x16 INC 0e ;increment our count of bytes ;clock data into thermal head MOV W, #08 ;for 8 bits MOV 17,ドル W ;better keep count of it clkhd: RL 16ドル ;rotate it thru carry SETB 12ドル.4 ;set data high SC ;check the carry flag CLRB 12ドル.4 ;clear data if required CALL outsr SETB 12ドル.5 ;clock that bit in CALL outsr CLRB 12ドル.5 ;drop clock again CALL outsr DECSZ 17ドル ;have we finished loop yet ? JMP clkhd ;guess not ;no point doing the extra shift as we are just ;throwing the data away once it is in the head ;if byte count=max then lets latch and let the main routine ; print it MOV W, #$c0 ;try 192 ;216 max bytes per line 1728 bits MOV W, 0e-w ;check max against our byte count SZ ;the same? result of zero? JMP continue ;no its ok, head not full yet ;need to latch thermal head ; We do not not lower busy here ;as main routine will do so once it has reset ;the counter. SETB 12ドル.6 ;latch bit for thermal head CALL outsr ;send- no one else better be using it CLRB 12ドル.6 ;put back CALL outsr ;send that to JMP exint ;leave int handler continue: ;tell host we are no longer busy, get next byte CLRB RA.0 ;bring BSY low ;and fall thru to exit :) exint: ;now restore to before interupt RETI main ;thermal printer control program 192 dpi 9 inch 1728 pixels ;need to set up direction bits for ports ;and set initial pin levels MOV W, #$C0 MOV !OPTION, W ;set options RTW and RTI on so OptionX can be used ;pullups mov M, #0ドルE mov !RA,#$FF mov !RB,#$FF ;porta as input except RA.0 MOV RA, #$ff ;set all pins high on port a mov M, #0ドルF MOV W, #$FE ;RA0 as output ;portb interrupt on neg edge is the default MOV RB, #01f ;make bits 6,7 &5 low mov M, #0ドルF MOV !RB, #01f ;port b 5,6,7 as output MOV W, #08ドル ;specify which phase to start on MOV 15,ドル W ;store it somewhere safe CLR 0ドルE ;zero byte count for head MOV W, #00ドル ;phases off clk,lat,data, strb off MOV 12,ドル W ;data for shift reg 1 MOV W, #00 ;all strobes off (low) MOV 13,ドル W ;data for shift reg 2 CALL outsr ;set all pins high except for stepper MOV W, #90ドル ;enable RB0 and GIE interupt bits MOV 0ドルB, W ;interupts now turned on! CLRB RA.0 ;say we are not busy p1=8;9 ;1 p2=4;8 ;3 ;ok here are definitions of how the shift registers are wired p3=2;0c;2 ; ok on 0x12 bit0 stepper phase A p4=1;4 ;6 ; bit1 " " B p5=8;6 ;4 ; bit2 " " C p6=4;2 ;0c ; bit3 " " D p7=2;3 ;8 ; bit4 Data for thermal head p8=1;1 ;9 ; bit5 Clock for thermal Head ; bit6 Latch for thermal head ; bit7 strobe 1 for thermal head; ; 0x13 bit0 to bit7 rest of strobes for head mloop: ;this is the loopy bit of main ;we sit in here till we get a full head ;then we reset the counter, send an ack to the host ;print the line out and advance the paper, then we sit until ;the head is full again :) ;first check if the head is full MOV W, #$C0 ;try 192 ;216 max bytes per line 1728 bits MOV W, 0ドルE-w ;check max against our byte count SZ ;the same? result of zero? JMP mloop ;no not yet keep waiting CLR 0ドルE ;Ok we've spotted the head full ;need to strobe head drivers SETB 12ドル.7 ;strb1 CLRB 0ドルB.7 ;turn off interupts CALL outsr ;Fire! CALL lildly ;let it burn! SETB 0ドルB.7 ;re-enable interupts CLRB 12ドル.7 ;ok thats done strobe 0 strobe 1 strobe 2 strobe 3 strobe 4 strobe 5 strobe 6 strobe 7 CLRB 0ドルB.7 ;turn off interupts CALL outsr ;yay! all strobes Fired! CLRB RA.0 ;ok we aren't busy any more SETB 0ドルB.7 ;re-enable interupts CALL papadv ;move paper on to next line JMP mloop ;lets go back and see if another ;line is ready yet phlook: ;this routine looks up the value for a particular phase ;important that this lookup resides within a 256 byte block ;as PCL is directly modified. if called with value grater ;than 8 ,will cause who knows what kind of crash! ADD 02, W ;ok now its going to jump :) NOP ;err dont expect zero ?!?! RETW #p8 ;return with phase 8 RETW #p7 ;coz we are counting down RETW #p6 ;remember... see next routine! RETW #p5 RETW #p4 RETW #p3 RETW #p2 RETW #p1 SLEEP ;coz its all gone wrong if it ;gets here or past! ;check the listing to be sure ;it fits between page boundries! papadv: ;this routine is to activate a paper advance one step ;it will use register #15 to keep track of which ;point in the phase cycle it is MOV W, #0f0 ;prep mask CLRB 0ドルb.7 ;diable interupts AND 12,ドル W ;nock off bottom bits MOV W, 15ドル ;grab our phase number into W CALL phlook OR 12,ドル W ;new pattern now set SETB 0ドルb.7 ;ints re-enabled DEC 15ドル ;get next phase number SNZ ;did we hit zero? JMP recount ;yep need to reload the counter CLRB 0ドルb.7 ;turn off interupts coz of (outsr) CALL outsr ;jump to out put new phase SETB 0ドルb.7 ;turn on interupts again RET ;and go back recount: MOV W, #08 ;we hit zero reset it back to 8 MOV 15,ドル W ;use it next time round CLRB 0ドルb.7 ;clear interupt enable CALL outsr ;I know its just below us SETB 0ドルb.7 ;but tis only way to keep RET ;the interupts rightly enabled outsr: ;this routine takes bytes at 0x12 and 0x13 ;and clocks them out onto the shift registers ;shift registers accessed on port b bits 5,6 & 7 ;bit 6 as clock - clocks data on POSITIVE edge ;bit 7 as data - non inverted ;bit 5 as strobe - latches data on NEGATIVE edge ; we are sending lsb first ie bit# 1 on shift register ; output pin #8 ; sending byte at address 0x12 first then 0x13 ; this puts 0x12 on the last shift register in line ;uses reg # 14 to keep count of bits ;since this code is NON-RE-ENTERENT, do NOT call it ;while interupts are enabled, coz the int handler ;calls this routine to access the thermal head. MOV W, #08 ;for 8 bits MOV 14,ドル W ;better keep count of it shiftbits: RR 12ドル ;rotate it thru carry SETB 6.7 ;set data high SC ;check the carry flag CLRB 6.7 ;clear data if required SETB 6.6 ;clock that bit in CLRB 6.6 ;drop clock again DECSZ 14ドル ;have we finished loop yet ? JMP shiftbits ;guess not RR 12ドル ;preserve the data, shift the carry ;now we have finished one byte lets do the other MOV W, #08 ;for 8 bits MOV 14,ドル W ;better keep count of it shiftbitsagain: RR 13ドル ;rotate it thru carry SETB 6.7 ;set data high SC ;check the carry flag CLRB 6.7 ;clear data if required SETB 6.6 ;clock that bit in CLRB 6.6 ;drop clock again DECSZ 14ドル ;have we finished loop yet ? JMP shiftbitsagain ;guess not RR 13ドル ;preserve the data, shift the carry ;now we have really finished clocking bits SETB 6.5 ;bring up the strobe line CLRB 6.5 ;and LATCH it RET ;back to where ever. lildly MOV W, #lilloop MOV 11,ドル W JMP reload bigdly MOV W, #bigloop MOV 11,ドル W reload MOV W, #innerloop MOV 10,ドル W inloop NOP DECSZ 10ドル JMP inloop DECSZ 11ドル JMP reload RET ORG 2000ドル DATA 00 DATA 00 DATA 00 DATA 00 ORG 2007ドル DATA 0x19 ;fuse settings ORG 2100ドル ;data 00 ;data 00 ;data 00 END
.