; ============================================================================= ; APPLIX 1616 NO-RAM STRING PRINTER ("Hi Keith") ; Fetches 8-byte font graphics from 0x00516144 and draws to VRAM at 0x00078000 ; ============================================================================= .text .org 0x500000 ; Absolute Boot Start of ROM ; --- Hardware Vectors --- .long 0x00000300 ; Dummy Stack Pointer .long BOOT_VECTOR ; Reset Vector BOOT_VECTOR: JMP START_DIAG(PC) ; Skip existing code block ; ============================================================================= ; DIAGNOSTIC CODE ENTRY POINT ; ============================================================================= .org 0x51DB80 START_DIAG: MOVE.W #0x2700,SR ; Disable interrupts ; ----------------------------------------------------------------------------- ; 1. CONFIGURE VIDLATCH & CLEAR VIDEO RAM ; ----------------------------------------------------------------------------- MOVEA.L #0x600101,A0 ; A0 = VIDLATCH MOVE.B #0x0F,(A0) ; Point video hardware to 0x00078000 bank MOVEA.L #0x00078000,A1 ; Start of Video RAM MOVEA.L #0x00080000,A2 ; End of Video RAM boundary MOVE.W #0x0000,D0 ; Clear value (Black pixels) CLEAR_VRAM: MOVE.W D0,(A1)+ CMPA.L A2,A1 BNE.S CLEAR_VRAM ; ----------------------------------------------------------------------------- ; 2. INITIALIZE MC6845 CRTC FOR PAL VIDEO ; ----------------------------------------------------------------------------- MOVEA.L #0x700180,A3 ; A3 = CRTCADDR MOVEA.L #0x700182,A4 ; A4 = CRTCDATA MOVE.B #0,(A3) ; MOVE.B #0x3F,(A4) ; R0: Horizontal Total MOVE.B #1,(A3) ; MOVE.B #0x28,(A4) ; R1: Horizontal Displayed MOVE.B #2,(A3) ; MOVE.B #0x2D,(A4) ; R2: Horizontal Sync Position MOVE.B #3,(A3) ; MOVE.B #0x0A,(A4) ; R3: Sync Widths MOVE.B #4,(A3) ; MOVE.B #0x26,(A4) ; R4: Vertical Total MOVE.B #5,(A3) ; MOVE.B #0x00,(A4) ; R5: Vertical Total Adjust MOVE.B #6,(A3) ; MOVE.B #0x19,(A4) ; R6: Vertical Displayed MOVE.B #7,(A3) ; MOVE.B #0x22,(A4) ; R7: Vertical Sync Position MOVE.B #8,(A3) ; MOVE.B #0x00,(A4) ; R8: Interlace Mode MOVE.B #9,(A3) ; MOVE.B #0x07,(A4) ; R9: Max Scan Line Address MOVE.B #10,(A3) ; MOVE.B #0x20,(A4) ; R10: Cursor Start Line MOVE.B #11,(A3) ; MOVE.B #0x00,(A4) ; R11: Cursor End Line MOVE.B #12,(A3) ; MOVE.B #0x00,(A4) ; R12: Start Address High MOVE.B #13,(A3) ; MOVE.B #0x00,(A4) ; R13: Start Address Low ; ----------------------------------------------------------------------------- ; 3. RENDER "Hi Keith" TO SCREEN (NO STACK, NO RAM UTILITY) ; ----------------------------------------------------------------------------- ; Set up base pointers MOVEA.L #0x00516144,A1 ; A1 = Font Table base address MOVEA.L #0x00078000,A2 ; A2 = Current destination pixel column MOVE.L #4096,D2 ; D2 = 4096 byte stride for interlaced lines ; --- PRINT 'H' (ASCII 72) --- ; Offset = 72 * 8 = 576 bytes LEA 576(A1),A5 ; A5 points to font data for 'H' MOVEA.L A2,A6 ; A6 copies current screen base column pointer MOVE.B (A5)+,(A6) ; ADDA.L D2,A6 MOVE.B (A5)+,(A6) ; ADDA.L D2,A6 MOVE.B (A5)+,(A6) ; ADDA.L D2,A6 MOVE.B (A5)+,(A6) ; ADDA.L D2,A6 MOVE.B (A5)+,(A6) ; ADDA.L D2,A6 MOVE.B (A5)+,(A6) ; ADDA.L D2,A6 MOVE.B (A5)+,(A6) ; ADDA.L D2,A6 MOVE.B (A5)+,(A6) ADDQ.L #1,A2; MOVE to the next horizontal screen byte column ; --- PRINT 'i' (ASCII 105) --- ; Offset = 105 * 8 = 840 bytes LEA 840(A1),A5 MOVEA.L A2,A6 MOVE.B (A5)+,(A6) ; ADDA.L D2,A6 MOVE.B (A5)+,(A6) ; ADDA.L D2,A6 MOVE.B (A5)+,(A6) ; ADDA.L D2,A6 MOVE.B (A5)+,(A6) ; ADDA.L D2,A6 MOVE.B (A5)+,(A6) ; ADDA.L D2,A6 MOVE.B (A5)+,(A6) ; ADDA.L D2,A6 MOVE.B (A5)+,(A6) ; ADDA.L D2,A6 MOVE.B (A5)+,(A6) ADDQ.L #1,A2 ; --- PRINT ' ' (ASCII 32) --- ; Offset = 32 * 8 = 256 bytes LEA 256(A1),A5 MOVEA.L A2,A6 MOVE.B (A5)+,(A6) ; ADDA.L D2,A6 MOVE.B (A5)+,(A6) ; ADDA.L D2,A6 MOVE.B (A5)+,(A6) ; ADDA.L D2,A6 MOVE.B (A5)+,(A6) ; ADDA.L D2,A6 MOVE.B (A5)+,(A6) ; ADDA.L D2,A6 MOVE.B (A5)+,(A6) ; ADDA.L D2,A6 MOVE.B (A5)+,(A6) ; ADDA.L D2,A6 MOVE.B (A5)+,(A6) ADDQ.L #1,A2 ; --- PRINT 'K' (ASCII 75) --- ; Offset = 75 * 8 = 600 bytes LEA 600(A1),A5 MOVEA.L A2,A6 MOVE.B (A5)+,(A6) ; ADDA.L D2,A6 MOVE.B (A5)+,(A6) ; ADDA.L D2,A6 MOVE.B (A5)+,(A6) ; ADDA.L D2,A6 MOVE.B (A5)+,(A6) ; ADDA.L D2,A6 MOVE.B (A5)+,(A6) ; ADDA.L D2,A6 MOVE.B (A5)+,(A6) ; ADDA.L D2,A6 MOVE.B (A5)+,(A6) ; ADDA.L D2,A6 MOVE.B (A5)+,(A6) ADDQ.L #1,A2 ; --- PRINT 'e' (ASCII 101) --- ; Offset = 101 * 8 = 808 bytes LEA 808(A1),A5 MOVEA.L A2,A6 MOVE.B (A5)+,(A6) ; ADDA.L D2,A6 MOVE.B (A5)+,(A6) ; ADDA.L D2,A6 MOVE.B (A5)+,(A6) ; ADDA.L D2,A6 MOVE.B (A5)+,(A6) ; ADDA.L D2,A6 MOVE.B (A5)+,(A6) ; ADDA.L D2,A6 MOVE.B (A5)+,(A6) ; ADDA.L D2,A6 MOVE.B (A5)+,(A6) ; ADDA.L D2,A6 MOVE.B (A5)+,(A6) ADDQ.L #1,A2 ; --- PRINT 'i' (ASCII 105) --- ; Offset = 105 * 8 = 840 bytes LEA 840(A1),A5 MOVEA.L A2,A6 MOVE.B (A5)+,(A6) ; ADDA.L D2,A6 MOVE.B (A5)+,(A6) ; ADDA.L D2,A6 MOVE.B (A5)+,(A6) ; ADDA.L D2,A6 MOVE.B (A5)+,(A6) ; ADDA.L D2,A6 MOVE.B (A5)+,(A6) ; ADDA.L D2,A6 MOVE.B (A5)+,(A6) ; ADDA.L D2,A6 MOVE.B (A5)+,(A6) ; ADDA.L D2,A6 MOVE.B (A5)+,(A6) ADDQ.L #1,A2 ; --- PRINT 't' (ASCII 116) --- ; Offset = 116 * 8 = 928 bytes LEA 928(A1),A5 MOVEA.L A2,A6 MOVE.B (A5)+,(A6) ; ADDA.L D2,A6 MOVE.B (A5)+,(A6) ; ADDA.L D2,A6 MOVE.B (A5)+,(A6) ; ADDA.L D2,A6 MOVE.B (A5)+,(A6) ; ADDA.L D2,A6 MOVE.B (A5)+,(A6) ; ADDA.L D2,A6 MOVE.B (A5)+,(A6) ; ADDA.L D2,A6 MOVE.B (A5)+,(A6) ; ADDA.L D2,A6 MOVE.B (A5)+,(A6) ADDQ.L #1,A2 ; --- PRINT 'h' (ASCII 104) --- ; Offset = 104 * 8 = 832 bytes LEA 832(A1),A5 MOVEA.L A2,A6 MOVE.B (A5)+,(A6) ; ADDA.L D2,A6 MOVE.B (A5)+,(A6) ; ADDA.L D2,A6 MOVE.B (A5)+,(A6) ; ADDA.L D2,A6 MOVE.B (A5)+,(A6) ; ADDA.L D2,A6 MOVE.B (A5)+,(A6) ; ADDA.L D2,A6 MOVE.B (A5)+,(A6) ; ADDA.L D2,A6 MOVE.B (A5)+,(A6) ; ADDA.L D2,A6 MOVE.B (A5)+,(A6) ; ----------------------------------------------------------------------------- ; 4. INITIALIZE ZILOG SCC & INF-LOOP (Keeps Serial Active as Backup) ; ----------------------------------------------------------------------------- MOVEA.L #0x700004,A5 ; A5 = SCCAC MOVE.B #9,(A5) ; MOVE.B #0x40,(A5) MOVE.B #4,(A5) ; MOVE.B #0x44,(A5) MOVE.B #3,(A5) ; MOVE.B #0xC0,(A5) MOVE.B #5,(A5) ; MOVE.B #0x60,(A5) MOVE.B #11,(A5) ; MOVE.B #0x50,(A5) MOVE.B #12,(A5) ; MOVE.B #0x0A,(A5) MOVE.B #13,(A5) ; MOVE.B #0x00,(A5) MOVE.B #14,(A5) ; MOVE.B #0x01,(A5) MOVE.B #3,(A5) ; MOVE.B #0xC1,(A5) MOVE.B #5,(A5) ; MOVE.B #0x6A,(A5) DIAG_LOOP: MOVE.B #0,(A5) ; want reg 0 MOVE.B (A5),D0 ; read reg AND.B #0x04,D0 ; check ready to send BEQ.S DIAG_LOOP MOVEA.L #0x700006,A6 MOVE.B #0x41,(A6) ; Blast 'A' out to serial terminal BRA.S DIAG_LOOP