; ; Commonly used assembly routines ; ; 8259 Constants I8259A EQU 000H ; 8259 port 1 I8259B EQU 001H ; 8259 port 2 ; ; LCD Constants ; LCDINST EQU 002H ; LCD instruction I/O port LCDDATA EQU 003H ; LCD data I/O port LCLEAR EQU 001H ; LCD clear instruction LRESET EQU 038H ; LCD reset to normal instruction LHALF1 EQU 080H ; LCD move cursor to char 1 LHALF2 EQU 0c0H ; LCD move cursor to char 9 PAUSE EQU 0aH ; a UNIX newline STACKTOP EQU 00000H ; top of stack (wraps to 0ffff) ; PIC Constants PIC EQU 004H ; PIC I/O port ; ; Set up useful stuff, jump to main program ; LD SP, STACKTOP CALL LCDINIT JP MAIN ; get past library routines ; ; Catch reset if it happens and try to print it on the LCD ; ORG 0038H ; Catch a reset LD HL, GOTRESETSTR CALL LCDPRINT HALT GOTRESETSTR DB "Got RST 38H", PAUSE, 0 ; ; LCD Init routine ; In: nothing ; LCDINIT #ifdef NOPRINT RET #endif PUSH BC PUSH HL LD HL, LISTRING LD B, LISTRLEN JP OUTBLOOP ; ; LCD string bytes output routine ; In: ; B - length divided by two, (e.g. # of bytes to output, not ; including the I/O addresses) ; HL - address of bytes ; OUTBYTES PUSH BC PUSH HL OUTBLOOP LD C, (HL) INC HL OUTI JR NZ, OUTBLOOP ; Probably need a delay here at 1 MHz. ; Are we supposed to check busy bit and wait until not busy? POP HL POP BC RET ; ; Clear LCD display ; In: nothing ; LCDCLR PUSH BC PUSH HL LD HL, LCSTRING LD B, LCSTRLEN ; falls through into byte output loop JP OUTBLOOP ; ; LCD Initialization string ; LISTRLEN EQU 10 LISTRING DB LCDINST, LRESET DB LCDINST, LRESET DB LCDINST, 006H DB LCDINST, 00eH DB LCDINST, LCLEAR DB LCDINST, LHALF1 DB LCDINST, LHALF1 DB LCDINST, LHALF1 DB LCDINST, LHALF1 DB LCDINST, LHALF1 LCSTRLEN EQU 5 LCSTRING DB LCDINST, LCLEAR DB LCDINST, LHALF1 DB LCDINST, LHALF1 DB LCDINST, LHALF1 DB LCDINST, LHALF1 ; ; LCD String output routine ; In: ; HL - Address of null-terminated string ; LCDPRINT #ifdef NOPRINT RET #endif PUSH AF PUSH BC PUSH DE PUSH HL LD A, LCLEAR OUT (LCDINST), A ; do a clear #ifndef SLOWCLOCK LD B, 250 ; 250 cycles of wait LCDPCLOOP DJNZ LCDPCLOOP #endif /* SLOWCLOCK */ LD C, LCDDATA LD D, 25 ; when 1->0, switch to 2nd display LCDPLOOP DEC D JP NZ, LCDNOSWITCH LD A, LHALF2 ; set LCD to address 0xc0 OUT (LCDINST), A #ifndef SLOWCLOCK LD B, 20 ; 20 cycles of wait for write to LCD LCDP2LOOP DJNZ LCDP2LOOP ; fall through #endif /* SLOWCLOCK */ LCDNOSWITCH LD A, (HL) CP 0 JP Z, LCDPDONE CP PAUSE JP NZ, LCDPDOIT ; LD A, 0dh ; return ; OUT (PIC), A #ifndef SLOWCLOCK ; wait for two seconds here! LD D, 2 ; 2 * 256 * 256 cycles is close to 1 sec LCDP1SL1 LD A, 0 ; 256 * 256 cycles LCDP1SL2 LD B, 0 ; 256 cycles LCDP1SL3 DJNZ LCDP1SL3 DEC A JP NZ, LCDP1SL2 DEC D JP NZ, LCDP1SL1 #endif /* SLOWCLOCK */ LD A, LCLEAR OUT (LCDINST), A ; do a clear ; LD A, 0ah ; linefeed ; OUT (PIC), A #ifndef SLOWCLOCK LD B, 250 ; 250 cycles of wait LCDPNLOOP DJNZ LCDPNLOOP #endif /* SLOWCLOCK */ LD A, LHALF1 OUT (LCDINST), A ; go to address 0x80 #ifndef SLOWCLOCK LD B, 20 ; 20 cycles of wait for write LCDP1LOOP DJNZ LCDP1LOOP #endif /* SLOWCLOCK */ LD D, 9 ; reset half counter JP LCDPNEXT ; continue with next character LCDPDOIT OUT (LCDDATA), A ; output that guy ; OUT (PIC), A #ifndef SLOWCLOCK LD B, 20 ; 20 cycles of wait for write LCDPWLOOP DJNZ LCDPWLOOP #endif /* SLOWCLOCK */ LCDPNEXT INC HL ; next char JP LCDPLOOP LCDPDONE POP HL POP DE POP BC POP AF RET ; ; Wait for seconds routine ; In: ; A - number of seconds to wait ; WAITSECS PUSH AF PUSH BC RLCA ; multiply A by 2 LCDP1SLP1 LD C, 0 ; 256 * 256 cycles LCDP1SLP2 LD B, 0 ; 256 cycles LCDP1SLP3 DJNZ LCDP1SLP3 DEC C JP NZ, LCDP1SLP2 DEC A JP NZ, LCDP1SLP1 POP BC POP AF RET ; ; put the hex string representation of A into the location at IX ; IX becomes IX + 2 ; PHEXBYTE PUSH AF PUSH BC LD B, A AND 0f0H SRL A SRL A SRL A SRL A CP 0aH JP C, DIG1LESS ADD A, "a" - 10 JP DIG1DONE DIG1LESS ADD A, "0" DIG1DONE LD (IX), A INC IX LD A, B AND 0fH CP 0aH JP C, DIG2LESS ADD A, "a" - 10 JP DIG2DONE DIG2LESS ADD A, "0" DIG2DONE LD (IX), A INC IX POP BC POP AF RET ; ; put the hex string representation of HL into the location at IX ; IX becomes IX + 4 ; PHEXWORD PUSH AF LD A, H CALL PHEXBYTE LD A, L CALL PHEXBYTE POP AF RET