;================================================================================================== ; Serial InterFace TEST - receive screen ;================================================================================================== ; uses 115200bps, two stop bits, no parity, HW data flow control ; (uncomment parts of code for IR mode or SW flow control) cpu z80undoc ; baseports 131 100xxx11b - port 131 is default ; 99 011xxx11b ; 195 110xxx11b ; 227 111xxx11b SIF_PORT equ 131 org 32768 START di ; store registers needed for return to BASIC push iy exx push hl exx ld a,56 ; default colors call CLS_COLOR ; clear screen call SIF_INIT ; set up 16C650 jp SIF_RECEIVE ; receive data and wait for key SPACE ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ; return to BASIC RETURN_TO_BASIC ld a,7 ; white BORDER out (254),a exx pop hl exx pop iy ei ret ;================================================================================================== SIF_RECEIVE ld hl,16384 ; buffer address ld de,6912 ; length = byte counter ld a,7 call SIMPLEBEEP SIF_REC_LOOP ; key SPACE = exit? ld a,127 ; read keyboard port 32766 (b, n, m, symbol shift, space) in a,(254) rra ; bit 0 in carry (test key space) jr nc,RETURN_TO_BASIC ; NC = space is pressed ; key R = RESET address to the start of screen ld a,251 ; read keyboard port 64510 (t, r, e, w, q) in a,(254) and 00000100b ; bit 3 is key R jr z,SIF_RECEIVE ; Z = R is pressed ; key P = user induced delay for data flow testing SIF_DELAY ld a,223 ; read keyboard port 57342 (y, u, i, o, p) in a,(254) and 00000001b jr nz,SIF_READ_FIFO ; NZ = P is not pressed ld a,2 ; red BORDER = delayed out (254),a jp SIF_DELAY ; repeat until key is pressed ; data ready? SIF_READ_FIFO xor a in a,(SIF_PORT+20) ; read LSR ld b,a and 10000000b ; bit 7 = "FIFO data error" jr nz,SIF_READ_FIFO_2 ; NZ = no error ld a,3 ; "FIFO data error" = purple BORDER (wrong parity?) out (254),a SIF_READ_FIFO_2 ld a,b and 00000001b ; bit 0 = "Receive data ready", 0 = no data, 1 = data in FIFO jp z,SIF_REC_LOOP ; nz = no data ld a,4 ; green BORDER = reading data out (254),a xor a in a,(SIF_PORT) ; read byte from UART ld (hl),a ; write byte in buffer inc hl ; increment pointer dec de ; decrement byte counter ld a,e or d jp nz,SIF_REC_LOOP ; NZ = repeat if byte counter > 0 jp SIF_RECEIVE ; reset address and byte counter ;================================================================================================== ; SIF init = set registers of 16C650 ;================================================================================================== SIF_INIT ld a,0 ; select UART 16C650 on SIF - 0 = first, 2 = second out (SIF_PORT+28),a xor a ; reset temporary LCR ; set parity in LCR ; 00000000b ; no parity ; 00001000b ; odd parity ; 00011000b ; even parity ; 00111000b ; force parity 0 ; 00101000b ; force parity 1 or 00000000b ; no parity ; set stop bits in LCR ; 00000000b ; 0 = 1 stop bit ; 00000100b ; 1 = 2 stop bits or 00000100b ; 2 stop bits ; set word length ; 00000000b ; 00 = 5 bits - if (S_BITS=6) lcr+=1; else { if (S_BITS=7) lcr+=2; else lcr+=3; } ; 00000001b ; 01 = 6 bits - if (S_BITS=6) lcr+=1; else { if (S_BITS=7) lcr+=2; else lcr+=3; } ; 00000010b ; 10 = 7 bits ; 00000011b ; 11 = 8 bits (default) or 00000011b ; 8 bits ld (SIF_LCR),a ; store value for latter use out (SIF_PORT+12),a ; LCR ld a,00000001b ; FIFO enable, no interrupts, no DMA, FCR[0] = 1 polled mode operation out (SIF_PORT+8),a ; FCR ; set baudrate, citation from datasheet - Baud rate registers set are accessible when LCR[7] = 1 ; 460800/115200 = 4 0, 4 ; 460800/57600 = 8 0, 8 ; 460800/38400 = 12 0, 12 ; 460800/19200 = 24 0, 24 ; 460800/9600 = 48 0, 48 ; ... ld a,128 ; LCR[7] = 1 - enable access to the registers DLL and DLM out (SIF_PORT+12),a ; LCR ld a,4 ; lower byte, "LSB of Divisor Latch" out (SIF_PORT),a ; DLL register ld a,0 ; higher byte, "MSB of Divisor Latch" out (SIF_PORT+4),a ; DLM register ; set automatic data flow control - specific for 16C650 - already set? ; from datasheet - EFR, Xon1, Xon2, Xoff1, Xoff2 are accessible only when the LCR is set to 0xBF ld a,10111111b ; 191 (0xBF) - enable access to Enhanced Registers (EFR, XON1, XON2, XOFF1, XOFF2) out (SIF_PORT+12),a ; LCR ; hardware flow control with signals CTS RTS ld a,00011010b ; EFR[4] must be active, EFR[3:2] Transmit Xon1/Xoff1, EFR[1:0] Receiver compares Xon1/Xoff1 out (SIF_PORT+8),a ; EFR ; software flow control with one byte (ignoring second Xon2 & Xoff2 registers) ; default Xon 17 (0x11) CTRL+S ; default Xoff 19 (0x13) CTRL+Q ld a,17 ; default Xon = 0x11 (CTRL+S) out (SIF_PORT+16),a ld a,19 ; default Xoff = 0x13 (CTRL+Q) out (SIF_PORT+24),a ; switch back to general register set SIF_INIT_FLOW_2 ld a,(SIF_LCR) ; restore value in LCR register (switch back to compatible registers) out (SIF_PORT+12),a ; LCR ; channel 1 (default) or channel 2 (IR) - channel is specific for SIF, IR mode for all 16C650 interfaces ld a,00000010b ; MCR[1] is inverted RTS output out (SIF_PORT+16),a ; MCR ; finally - disable all interrupts, SIFTERM is not using it (maybe it is not best decision) SIF_INIT_IERVAL ld a,00000000b ; no interrupts, we are using polled mode operation out (SIF_PORT+4),a ; IER ret SIF_LCR db 0 ; here will be assembled Line Control Register ;-------------------------------------------------------------------------------------------------- ; clear screen CLS_COLOR ld (CLS_2+1),a ; 13T store colors for future use CLS ld (CLS_SP_CMN+1),sp ; 20T - store stack pointer ld sp,23296 ; 10T - addr. of VRAM end, clearing backwards CLS_2 ld a,56 ; 7T - default color combination ld b,24 ; 7T - 24 lines (color attributes) ld h,a ; 4T - copy color from A to H and L ld l,a ; 4T CLS_0 push hl ; 11T - repeat 16x push = it stores 32 bytes push hl ; all attr. will take (16*10T)*24 = 3840T push hl push hl push hl push hl push hl push hl push hl push hl push hl push hl push hl push hl push hl push hl djnz CLS_0 ; 307T - 23*13T, per line, 8T last one ld h,b ; 4T - now B==0, let H=0, L=0 too ld l,b ; 4T ld b,192 ; 7T - number of pixel lines CLS_1 push hl ; 11T - repeat 16x push = it stores 32 bytes push hl ; all will take (16*11)*192 = 33792T push hl push hl push hl push hl push hl push hl push hl push hl push hl push hl push hl push hl push hl push hl djnz CLS_1 ; 191*13+8 = 2491T CLS_SP_CMN ld sp,0 ; 10T restore stack pointer ret ;-------------------------------------------------------------------------------------------------- ; wait for key ; PAUSE0 xor a ; in a,(254) ; read all keys ; cpl ; invert it, pressed key is 0 ; and 00011111b ; leave only bits relevant for keys ; jr z,PAUSE0 ; Z = no key is pressed => repeat ; ret ; something pressed, return ; wait if any key is pressed PAUSENK xor a in a,(254) ; read all keys cpl ; invert it, pressed key is 0 and 00011111b ; leave only bits relevant for keys jr nz,PAUSENK ; NZ = something is pressed => repeat ret ; nothing pressed, return ;-------------------------------------------------------------------------------------------------- SIMPLEBEEP push bc ; store BC ld b,128 ; counter, number of pulses SIMPLEBEEP_2 out (254),a xor 0011000b ; toggle only speaker bits push bc ; store BC for inner loop ld b,60 ; 60 times repeat = little delay SIMPLEBEEP_1 djnz SIMPLEBEEP_1 pop bc ; restore BC - inner loop djnz SIMPLEBEEP_2 pop bc ; restore BC ret