Joined: Tue May 03, 2016 11:32 am Posts: 41
|
Got some more success with the driver (some reading here, some "stealing" there... crashes, having to rewrite IRQ handler in ROM to support separate emulation and native 65c816) Currently I am stumbling upon an issue when sending large data sets.
Code: 000000r 1 ;=============================================================================== 000000r 1 ; A D R I A - Philips/NXP 28L9x Driver skeleton 000000r 1 ; 000000r 1 ; This source file is the base skeleton for the driver for the 000000r 1 ; Philips/NXP 28L9x IC. 000000r 1 ; 000000r 1 ; This driver is (largely) based on the driver by 000000r 1 ; BDD (sbc.bcstechnology.net) and his documents "28l91 Driving" and 000000r 1 ; "28L92 Interfacing". 000000r 1 ; (Most of this driver is copied from/based on his work!) 000000r 1 ; 000000r 1 ; Written for use with the CC65 assembler. 000000r 1 ; 000000r 1 ; Version history: 000000r 1 ; 26 jan 2021 - Inital version 000000r 1 ;=============================================================================== 000000r 1 ; Linker directives 000000r 1 ;--------------------------------------- 000000r 1 .p816 000000r 1 .listbytes unlimited 000000r 1 .smart + 000000r 1 000000r 1 .org $4000 ; Our driver will be loaded ... 004000 1 ; ... at $4000 (16384) 004000 1 ; 004000 1 ;--------------------------------------- 004000 1 ; Includes to sub-modules 004000 1 ;--------------------------------------- 004000 1 .include "macro.asm" 004000 2 ;=============================================================================== 004000 2 ; A D R I A - Philips/NXP 28L9x Macro file 004000 2 ; 004000 2 ; This source file holds the global macro definitions to ease the 004000 2 ; development of the drivre for the Philips/NXP 28L9x IC. 004000 2 ; 004000 2 ; Version history: 004000 2 ; 26 jan 2021 - Inital version 004000 2 ;=============================================================================== 004000 2 ; Version information 004000 2 ;--------------------------------------- 004000 2 .macro nx_9x_version 004000 2 .byte '0' ; Major 004000 2 .byte '.' 004000 2 .byte '1' ; Minor 004000 2 .byte '.' 004000 2 .byte '0' ; Revision 004000 2 .endmacro 004000 2 ; 004000 2 ;--------------------------------------- 004000 2 ; Register width selection 004000 2 ;--------------------------------------- 004000 2 .macro longi ; Set .X and .Y to 16-bit 004000 2 rep #%00010000 004000 2 .i16 004000 2 .endmacro 004000 2 004000 2 .macro shorti ; Set .X and .Y to 8-bit 004000 2 sep #%00010000 004000 2 .i8 004000 2 .endmacro 004000 2 004000 2 .macro longa ; Set .A to 16-bit 004000 2 rep #%00100000 004000 2 .a16 004000 2 .endmacro 004000 2 004000 2 .macro shorta ; Set .A to 8-bit 004000 2 sep #%00100000 004000 2 .a8 004000 2 .endmacro 004000 2 004000 2 .macro longr ; Set all registers to 16-bit 004000 2 rep #%00110000 ; Set 16-bit .A, .X and .Y 004000 2 .a16 004000 2 .i16 004000 2 .endmacro 004000 2 004000 2 .macro shortr ; Set all registers to 8-bit 004000 2 sep #%00110000 ; Set 8-bit .A, .X and .Y 004000 2 .a8 004000 2 .i8 004000 2 .endmacro 004000 2 ; 004000 2 004000 1 .include "global.asm" 004000 2 ;=============================================================================== 004000 2 ; A D R I A - Philips/NXP 28L9x Global definitions file 004000 2 ; 004000 2 ; This source file holds the global definitions for the drivre for the 004000 2 ; Philips/NXP 28L9x IC. 004000 2 ; 004000 2 ; Version history: 004000 2 ; 26 jan 2021 - Inital version 004000 2 ;=============================================================================== 004000 2 ; GENERIC 004000 2 ;======================================= 004000 2 ; Size data types 004000 2 ;--------------------------------------- 004000 2 s_bi_bit = 1 ; 1 bit 004000 2 s_bi_nibble = 4 ; 4 bit, nibble (or nybble) 004000 2 s_bi_nybble = s_bi_nibble 004000 2 s_bi_byte = 8 ; 8 bit, 1 byte 004000 2 ; 004000 2 s_byte = 1 ; 8 bit, 1 byte 004000 2 s_word = 2 ; 16 bit, 2 bytes 004000 2 s_xword = 3 ; 24 bit, 3 bytes 004000 2 s_dword = 4 ; 32 bit, 4 bytes 004000 2 ; 004000 2 s_ptr = s_word ; Pointer , 16 bit, 2 bytes 004000 2 s_dptr = s_word * 2 ; Double pointer, 32 bit, 4 bytes 004000 2 s_rampage = $0100 ; 65xx size of RAM page (256 bytes) 004000 2 s_bank = $ffff ; 65816 size of RAM bank (65536 bytes) 004000 2 ; 004000 2 s_mpudbx = s_byte ; Size of Data Bank register 004000 2 s_mpudpx = s_word ; Size of Direct Page register 004000 2 s_mpupbx = s_byte ; Size of Program Bank register 004000 2 s_mpupcx = s_word ; Size of Program Counter register 004000 2 s_mpuspx = s_word ; Size of Stack Pointer register 004000 2 s_mpusrx = s_byte ; Size of Processor Status register 004000 2 ; 004000 2 ;--------------------------------------- 004000 2 ; Flags 004000 2 ;--------------------------------------- 004000 2 ; Status Register 004000 2 ; +----------> 1 = result = negative 004000 2 ; |+---------> 1 = sign overflow 004000 2 ; || 1 = 8 bit .A & memory 004000 2 ; ||+--------> 0 = 16 bit .A & memory 004000 2 ; ||| 1 = 8 bit index 004000 2 ; |||+-------> 0 = 16 bit index 004000 2 ; |||| 1 = decimal arithmetic mode 004000 2 ; ||||+------> 0 = binary arithmetic mode 004000 2 ; |||||+-----> 1 = IRQ disabled 004000 2 ; ||||||+----> 1 = result = zero 004000 2 ; |||||||+---> 1 = carry set/generated 004000 2 ; |||||||| 004000 2 ; NVmxDIZC 004000 2 ;--------------- 004000 2 sr_carry = %0000001 ; C => carry 004000 2 sr_zero = sr_carry << 1 ; Z => zero 004000 2 sr_irq = sr_zero << 1 ; I => IRQ 004000 2 sr_bdm = sr_irq << 1 ; D => decimal mode 004000 2 sr_ixw = sr_bdm << 1 ; x => index register width 004000 2 sr_amw = sr_ixw << 1 ; m => memory and .A width 004000 2 sr_ovl = sr_amw << 1 ; V => overflow 004000 2 sr_neg = sr_ovl << 1 ; N => negative 004000 2 ;--------------- 004000 2 ; Status Register - Inverted 004000 2 ;--------------- 004000 2 sr_carry_i = sr_carry ^ %11111111 ; C 004000 2 sr_zero_i = sr_zero ^ %11111111 ; Z 004000 2 sr_irq_i = sr_irq ^ %11111111 ; I 004000 2 sr_bdm_i = sr_bdm ^ %11111111 ; D 004000 2 sr_ixw_i = sr_ixw ^ %11111111 ; x 004000 2 sr_amw_i = sr_amw ^ %11111111 ; m 004000 2 sr_ovl_i = sr_ovl ^ %11111111 ; V 004000 2 sr_neg_i = sr_neg ^ %11111111 ; N 004000 2 ; 004000 2 ;--------------------------------------- 004000 2 ; Constants 004000 2 ;--------------------------------------- 004000 2 BELL = $07 ; <Bell> 004000 2 BS = $08 ; <Backspace> 004000 2 HTAB = $09 ; <Tab> 004000 2 LF = $0A ; <LF> 004000 2 CR = $0D ; <CR> 004000 2 SPACE = $20 ; <Space> 004000 2 DEL = $7F ; <Del> 004000 2 ; 004000 2 ;--------------------------------------- 004000 2 ; Pointers/addresses 004000 2 ;--------------------------------------- 004000 2 ; SUPERMON816 004000 2 ;--------------- 004000 2 DPYHEX = $DFAD ; Display contents of .A as byte 004000 2 NEWLINE = $DFC4 ; Go to new line 004000 2 ;--------------- 004000 2 ; ROM 004000 2 ;--------------- 004000 2 VECTOR_INT = $02D8 ; /IRQ jump vector 004000 2 CHKSUM_INT = $02DA ; /IRQ jump vector checksum 004000 2 CHAR_OUT = $FD0C ; Current Character Out jump routine 004000 2 ; 004000 2 ;======================================= 004000 2 ; DRIVER 004000 2 ;======================================= 004000 2 ; Size data types 004000 2 ;--------------------------------------- 004000 2 s_uptime = s_dword ; Uptime ticker , 32 bit, 4 bytes 004000 2 ; 004000 2 s_e32_buf = s_rampage / 2 ; Size of a UART I/O buffer 004000 2 s_e32_space = s_e32_buf * n_e32_buf ; Total space reserved for UART I/O 004000 2 ; buffers 004000 2 ; 004000 2 ;--------------------------------------- 004000 2 ; Flags 004000 2 ;--------------------------------------- 004000 2 ; Channel TxD status 004000 2 ; Only A and B are used, rest is 004000 2 ; already defined for future use 004000 2 e32_tx_sta = %00000001 ; Channel A TxD status 004000 2 e32_tx_stb = e32_tx_sta << 1 ; Channel B TxD status 004000 2 e32_tx_stc = e32_tx_stb << 1 ; Channel C TxD status 004000 2 e32_tx_std = e32_tx_stc << 1 ; Channel D TxD status 004000 2 e32_tx_ste = e32_tx_std << 1 ; Channel E TxD status 004000 2 e32_tx_stf = e32_tx_ste << 1 ; Channel F TxD status 004000 2 e32_tx_stg = e32_tx_stf << 1 ; Channel G TxD status 004000 2 e32_tx_sth = e32_tx_stg << 1 ; Channel H TxD status 004000 2 ; 004000 2 buf_idx_mask = s_e32_buf ^ %11111111 ; Buffer index wrap mask 004000 2 ; 004000 2 ; 28L9x driver status flags 004000 2 nx_driver_init = %10000000 ; Driver initialization status 004000 2 nx_txa_dis = %01000000 ; TxD channel A flag 004000 2 nx_txb_dis = %00100000 ; TxD channel B flag 004000 2 ; 004000 2 ; SR masks 004000 2 msk_sr_rx_rdy = %00000001 ; RHR not empty mask 004000 2 msk_sr_rx_full = %00000010 ; RHR full empty 004000 2 msk_sr_tx_rdy = %00000100 ; THR not full mask 004000 2 msk_sr_tx_empty = %00001000 ; THR empty mask 004000 2 ; 004000 2 ; IRQ masks 004000 2 ;--------------- 004000 2 msk_irq_txa = %00000001 ; Channel A TxRDY IRQ mask 004000 2 msk_irq_rxa = %00000010 ; Channel A RxRDY IRQ mask 004000 2 msk_irq_ct = %00001000 ; Counter Ready Mask 004000 2 msk_irq_txb = %00010000 ; Channel B TxRDY IRQ mask 004000 2 msk_irq_rxb = %00100000 ; Channel B RxRDY IRQ mask 004000 2 ; 004000 2 ;--------------------------------------- 004000 2 ; Constants 004000 2 ;--------------------------------------- 004000 2 n_chan_9x = 2 ; Number of channels 004000 2 n_reg_9x = 8 ; Number of registers per channel 004000 2 n_tot_reg_9x = n_chan_9x * n_reg_9x ; Total number of registers 004000 2 ; 004000 2 ;nx_q_size = s_rampage / 2 ; Size of a ring buffer (127) 004000 2 nx_q_size = s_rampage ; Size of a ring buffer (255) 004000 2 nx_q_base = $2000 ; For now we define our queues at $2000 004000 2 nx_rx_qa = nx_q_base ; RxD queue channel A 004000 2 nx_tx_qa = nx_rx_qa + nx_q_size ; TxD queue channel A 004000 2 nx_rx_qb = nx_tx_qa + nx_q_size ; RxD queue channel B 004000 2 nx_tx_qb = nx_rx_qb + nx_q_size ; TxD queue channel B 004000 2 ; 004000 2 n_e32_buf = 4 ; # of UART I/O buffers 004000 2 ; 004000 2 x1_freq = 3686400 ; Clock freq of X1 in Hz 004000 2 nx_ct_scale = x1_freq / 2 ; C/T scaled clock 004000 2 hz = 100 ; Frequency of C/T IRQs (in Hz) 004000 2 ; 004000 2 ;--------------------------------------- 004000 2 ; Pointers/addresses 004000 2 ;--------------------------------------- 004000 2 ; Zeropage / Direct Page 004000 2 ;--------------- 004000 2 nx_zeropage = $20 ; We use ZP from $20 004000 2 nx_jiffycnt = nx_zeropage ; Jiffy counter 004000 2 ;--------------- 004000 2 ; Uptime is little endian! 004000 2 ;--------------- 004000 2 nx_uptimecnt = nx_jiffycnt + s_byte ; 32 bit uptime counter 004000 2 ; 004000 2 ; RxD and TxD GET and PUT indexes channel A 004000 2 nx_rx_get_a = nx_uptimecnt + s_dword; 004000 2 nx_tx_get_a = nx_rx_get_a + s_byte ; 004000 2 nx_rx_put_a = nx_tx_get_a + s_byte ; 004000 2 nx_tx_put_a = nx_rx_put_a + s_byte ; 004000 2 ; 004000 2 ; RxD and TxD GET and PUT indexes channel B 004000 2 nx_rx_get_b = nx_tx_put_a + s_byte ; 004000 2 nx_tx_get_b = nx_rx_get_b + s_byte ; 004000 2 nx_rx_put_b = nx_tx_get_b + s_byte ; 004000 2 nx_tx_put_b = nx_rx_put_b + s_byte ; 004000 2 ; 004000 2 nx_tx_status = nx_tx_put_b + s_byte ; Driver TxD status register 004000 2 ; 004000 2 rom_irq = nx_tx_status + s_byte ; Store original IRQ jump vector! 004000 2 ;--------------- 004000 2 ; I/O 004000 2 ;--------------- 004000 2 IOBASE = $C400 ; NXP 28L92 is based in slot #4 004000 2 ; 004000 2 ;--------------------------------------- 004000 2 ; Data Registers 004000 2 ;--------------------------------------- 004000 2 ; Offsets to IO_BASE 004000 2 ;--------------- 004000 2 dr_mra = %0000 ; Mode Register A 004000 2 dr_sra = %0001 ; Status Register a 004000 2 dr_rxfifoa = %0011 ; Rx Holding Register A 004000 2 dr_ipcr = %0100 ; Input Port Change Register 004000 2 dr_isr = %0101 ; Interrupt Status Register 004000 2 dr_ctu = %0110 ; Counter/Timer (MSB) 004000 2 dr_ctl = %0111 ; Counter/Timer (LSB) 004000 2 dr_mrb = %1000 ; Mode Register B 004000 2 dr_srb = %1001 ; Status Register B 004000 2 dr_rxfifob = %1011 ; Rx Holding Register B 004000 2 dr_misc = %1100 ; Miscellaneous Register (Intel mode) 004000 2 dr_ipr = %1101 ; Input Port Register 004000 2 dr_cnt_start = %1110 ; Start counter command 004000 2 dr_cnt_stop = %1111 ; Stop counter command 004000 2 ; During write 004000 2 ;dr_mra = %0000 ; Mode Register A (Same when Reading) 004000 2 dr_csra = %0001 ; Clock Select Register A 004000 2 dr_cra = %0010 ; Command Register A 004000 2 dr_txfifoa = %0011 ; Tx Holding Register A 004000 2 dr_acr = %0100 ; Auxiliary Control Register 004000 2 dr_imr = %0101 ; Interrupt Mask Register 004000 2 dr_ctpu = %0110 ; Counter/Timer Upper Preset Reg (MSB) 004000 2 dr_ctpl = %0111 ; Counter/Timer Lower Preset Reg (LSB) 004000 2 ;dr_mrb = %1000 ; Mode Register B (Same when Reading) 004000 2 dr_csrb = %1001 ; Clock Select Register B 004000 2 dr_crb = %1010 ; Command Register B 004000 2 dr_txfifob = %1011 ; Tx Holding Register B 004000 2 ;dr_misc = %1100 ; Miscellaneous Register (Intel mode) 004000 2 dr_opcr = %1101 ; Output Port Configuration Register 004000 2 dr_sopr = %1110 ; Set Output Port Bits Command 004000 2 dr_ropr = %1111 ; Reset Output Port Bits Command 004000 2 ;--------------------------------------- 004000 2 ; 29L9x Registers (explained) 004000 2 ;--------------------------------------- 004000 2 ; MISC - Miscellaneous Register (Intel mode) 004000 2 ; 004000 2 ; We only explain the possible flags 004000 2 ; 004000 2 nx_misc_def = %00000000 004000 2 ; xxxxxxxx 004000 2 ; |||||||| 004000 2 ; |||+++++---> z: Unused 004000 2 ; ||| 004000 2 ; ||+--------> 1: Disable transmitter channel B 004000 2 ; |+---------> 1: Disable transmitter channel A 004000 2 ; +----------> 1: Driver initialized 004000 2 ;--------------- 004000 2 ; ACR - Auxiliary Control Register 004000 2 ;--------------- 004000 2 nx_acr_def = %01100000 004000 2 ; xxxxxxxx 004000 2 ; |||||||| 004000 2 ; |||||||+---> 1: enable IP0 IRQ 004000 2 ; ||||||+----> 1: enable IP1 IRQ 004000 2 ; |||||+-----> 1: enable IP2 IRQ 004000 2 ; ||||+------> 1: enable IP3 IRQ 004000 2 ; |+++-------> C/T setup: 004000 2 ; | 004000 2 ; | 654 Mode Source 004000 2 ; | ------------------------------- 004000 2 ; | 000 counter IP2 004000 2 ; | 001 counter TxD Ch 1 1X clock 004000 2 ; | 010 counter TxD Ch 2 1X clock 004000 2 ; | 011 counter Xtal/16 004000 2 ; | 100 timer IP2 004000 2 ; | 101 timer IP2/16 004000 2 ; | 110 timer Xtal 004000 2 ; | 111 timer Xtal/16 004000 2 ; | ------------------------------- 004000 2 ; | 004000 2 ; +----------> 0: select BRG set #1 (38.4k max) 004000 2 ; 1: select BRG set #2 (19.2k max) 004000 2 ; 004000 2 ;--------------- 004000 2 ; CR - Command Register 004000 2 ;--------------- 004000 2 nx_cr_rx_ena = %00000001 ; Enable receiver 004000 2 nx_cr_rx_dis = %00000010 ; Disable receiver 004000 2 ; 004000 2 nx_cr_tx_ena = %00000100 ; Enable transmitter 004000 2 nx_cr_tx_dis = %00001000 ; Disable transmitter 004000 2 ; 004000 2 nx_cr_mr1 = %00010000 ; Select MR1 004000 2 ; 004000 2 nx_cr_rx_res = %00100000 ; Reset receiver 004000 2 nx_cr_tx_res = %00110000 ; Reset transmitter 004000 2 nx_cr_err_res = %01000000 ; Reset error status 004000 2 nx_cr_bir_res = %01010000 ; Reset Received Break Change IRQ 004000 2 ; 004000 2 nx_cr_brk_sta = %01100000 ; Start break 004000 2 nx_cr_brk_stp = %01110000 ; Stop break 004000 2 ; 004000 2 nx_cr_rts_ass = %10000000 ; Assert RTS 004000 2 nx_cr_rts_dea = %10010000 ; Deassert RTS 004000 2 ; 004000 2 nx_cr_tmr_mod = %10100000 ; Select C/T timer mode 004000 2 ; 004000 2 nx_cr_mr0 = %10110000 ; Select MR0 004000 2 ; 004000 2 nx_cr_cnt_mod = %11000000 ; Select C/T counter mode 004000 2 ; 004000 2 nx_cr_pwr_dwn = %11100000 ; Power down mode (Port A only) 004000 2 nx_cr_pwr_up = %11110000 ; Normal power mode (Port A only) 004000 2 ; 004000 2 ; Combined CR commands 004000 2 nx_cr_rxtx_ena = nx_cr_rx_ena | nx_cr_tx_ena 004000 2 nx_cr_rxtx_dis = nx_cr_rx_dis | nx_cr_tx_dis 004000 2 ; 004000 2 ;--------------- 004000 2 ; CSR - Clock Select Register 004000 2 ;--------------- 004000 2 nx_csr = %11001100 ; RxD and TxD at 38k4 baud 004000 2 ; MR[0] = 0 & ACR[7] = 0 004000 2 ;--------------- 004000 2 ; CT - Counter / Timer 004000 2 ;--------------- 004000 2 nx_cnt_lo = <(nx_ct_scale/hz) ; Underflows/sec LSB 004000 2 nx_cnt_hi = >(nx_ct_scale/hz) ; Underflows/sec MSB 004000 2 ; 004000 2 ;--------------- 004000 2 ; IMR - Interrupt Mask Register 004000 2 ;--------------- 004000 2 ; Enable channel A RxD and TxD IRQs 004000 2 nx_irq_a = msk_irq_txa | msk_irq_rxa 004000 2 ; Enable channel B RxD and TxD IRQs 004000 2 nx_irq_b = msk_irq_txb | msk_irq_rxb 004000 2 ; Set IRQ Sources (Port A, B and C/T) 004000 2 nx_irq_msk = nx_irq_a | nx_irq_b | msk_irq_ct 004000 2 ; 004000 2 ;--------------- 004000 2 ; MR0 - Mode 0 Register 004000 2 ;--------------- 004000 2 nx_mr0 = %11001000 004000 2 ; |||||||| 004000 2 ; |||||+++----> Baud rate: Normal mode 004000 2 ; ||||+-------> 16-deep FIFO 004000 2 ; ||++--------> TxD interrupts only when FIFO is empty 004000 2 ; |+----------> RxD interrupts only when FIFO is full 004000 2 ; | (also see MR1[6]) 004000 2 ; +-----------> Enable RxD watchdog timer 004000 2 ; 004000 2 ;--------------- 004000 2 ; MR1 - Mode 1 Register 004000 2 ;--------------- 004000 2 nx_mr1 = %11010011 004000 2 ; |||||||| 004000 2 ; ||||||++----> 8 bit character size 004000 2 ; |||||+------> Parity type (ignored) 004000 2 ; |||++-------> No parity generated or checked 004000 2 ; ||+---------> Character error mode 004000 2 ; |+----------> RxD interrupts only when FIFO is full 004000 2 ; | (See also MR0[6] 004000 2 ; +-----------> RxD controls RTS 004000 2 ; 004000 2 ;--------------- 004000 2 ; MR2 - Mode 2 Register 004000 2 ;--------------- 004000 2 nx_mr2 = %00010111 ; Normal mode, auto RTS 004000 2 ; |||||||| 004000 2 ; ||||++++---> stop bit length 004000 2 ; |||| 004000 2 ; |||+-------> TxD CTS mode: 0: off 004000 2 ; ||| 1: on 004000 2 ; ||+--------> TxD RTS mode: 0: off 004000 2 ; || 1: on 004000 2 ; ++---------> channel mode: 00: normal 004000 2 ; 01: auto echo 004000 2 ; 10: local loop 004000 2 ; 11: remote loop 004000 2 ; 004000 2 ;--------------- 004000 2 ; OPCR - Output Port Configuration Register 004000 2 ;--------------- 004000 2 nx_opcr_def = %11110000 ; OP4-7 as IRQ outputs 004000 2 004000 2 004000 2 004000 1 .include "frontend.asm" 004000 2 ;=============================================================================== 004000 2 ; A D R I A - Philips/NXP 28L9x Front-end routine(s) 004000 2 ; 004000 2 ; This source file holds the front-end routine(s) for the 004000 2 ; Philips/NXP 28L9x IC. 004000 2 ; 004000 2 ; Version history: 004000 2 ; 26 jan 2021 - Inital version 004000 2 ;=============================================================================== 004000 2 ; Process Receive Request 004000 2 ; 004000 2 ; Call the subroutine and the routine will try to "get" a datum from the 004000 2 ; corresponding RxQ. If this succeeds, the routine will return: 004000 2 ; .A - valid datum 004000 2 ; carry - clear 004000 2 ; 004000 2 ; If no datum is present in the RxQ, the routine will return: 004000 2 ; .A - unchanged 004000 2 ; carry - set 004000 2 ; 004000 2 ; NOTE: Carry will also be returned set, if the driver hasn't been initialized, 004000 2 ; yet... 004000 2 ;------------------------------------------------------------------------------- 004000 2 ; nx_sioget_a - Process datum from channel A RxQ 004000 2 ;----------------------- 004000 2 nx_sioget_a: 004000 2 E2 30 shortr ; Make sure we are in 8-bit registers 004002 2 38 sec ; Default: assume error 004003 2 2C 0C C4 bit IOBASE + dr_misc ; Read bit 7 of dr_misc, if set, driver 004006 2 ; has been initialized 004006 2 10 0E bpl @done ; No, error 004008 2 ; 004008 2 DA phx ; Save .X 004009 2 A6 25 ldx nx_rx_get_a ; RxD "get" index 00400B 2 E4 27 cpx nx_rx_put_a ; Compare with RxD "put" index 00400D 2 F0 06 beq @no_datum ; No datum available 00400F 2 ; 00400F 2 BD 00 20 lda nx_rx_qa, X ; Get datum from queue 004012 2 E6 25 inc nx_rx_get_a ; Increment "get" index 004014 2 18 clc ; Clear error (carry) 004015 2 ; 004015 2 @no_datum: 004015 2 FA plx ; Restore .X 004016 2 ; 004016 2 @done: 004016 2 60 rts 004017 2 ; 004017 2 ;----------------------- 004017 2 ; nx_sioget_b - Process datum from channel B RxQ 004017 2 ;----------------------- 004017 2 nx_sioget_b: 004017 2 E2 30 shortr ; Make sure we are in 8-bit registers 004019 2 38 sec ; Default, assume error 00401A 2 2C 0C C4 bit IOBASE + dr_misc ; Read bit 7 of dr_misc, if set, driver 00401D 2 ; has been initialized 00401D 2 10 0E bpl @done ; No, error 00401F 2 ; 00401F 2 DA phx ; Save .X 004020 2 A6 29 ldx nx_rx_get_b ; RxD "get" index 004022 2 E4 2B cpx nx_rx_put_b ; Compare with RxD "put" index 004024 2 F0 06 beq @no_datum ; No datum available 004026 2 ; 004026 2 BD 00 22 lda nx_rx_qb, X ; Get datum from queue 004029 2 E6 29 inc nx_rx_get_b ; Increment "get" index 00402B 2 18 clc ; Clear error (carry) 00402C 2 ; 00402C 2 @no_datum: 00402C 2 FA plx ; Restore .X 00402D 2 ; 00402D 2 @done: 00402D 2 60 rts 00402E 2 ; 00402E 2 ;------------------------------------------------------------------------------- 00402E 2 ; Process Transmit Request 00402E 2 ; 00402E 2 ; Call the subroutine and the routine will try to "put" a datum into the 00402E 2 ; corresponding TxQ. If this succeeds, the routine will return: 00402E 2 ; carry - clear 00402E 2 ; 00402E 2 ; NOTE: Carry will be set, if the driver hasn't been initialized, 00402E 2 ; yet... 00402E 2 ;------------------------------------------------------------------------------- 00402E 2 ; nx_sioput_a - Process datum for channel A TxQ 00402E 2 ;----------------------- 00402E 2 nx_sioput_a: 00402E 2 E2 30 shortr ; 8 bit registers 004030 2 38 sec ; Default, assume error 004031 2 2C 0C C4 bit IOBASE + dr_misc ; Read bit 7 of dr_misc, if set, driver 004034 2 ; has been initialized 004034 2 10 1E bpl @done ; No, error! 004036 2 ; 004036 2 48 pha ; Preserve .A 004037 2 DA phx ; Preserve .X 004038 2 A6 28 ldx nx_tx_put_a ; TxQ "put" index 00403A 2 E8 inx 00403B 2 ; 00403B 2 @full: 00403B 2 E4 26 cpx nx_tx_get_a ; TxQ "get" index 00403D 2 F0 FC beq @full ; TxQ is full, block... 00403F 2 ; 00403F 2 CA dex ; Realign "put" index and ... 004040 2 9D 00 21 sta nx_tx_qa, X ; ... put datum into TxQ 004043 2 E6 28 inc nx_tx_put_a ; Bump "put" index 004045 2 ; 004045 2 ;--------------- 004045 2 ; Manage transmitter 004045 2 ;--------------- 004045 2 A9 40 lda #nx_txa_dis ; Transmitter disabled flag 004047 2 1C 0C C4 trb IOBASE + dr_misc ; is transmitter disabled? 00404A 2 F0 05 beq @cleanup ; No 00404C 2 ; 00404C 2 A9 04 lda #nx_cr_tx_ena ; Yes, enable transmitter 00404E 2 8D 02 C4 sta IOBASE + dr_cra 004051 2 ; 004051 2 @cleanup: 004051 2 FA plx 004052 2 68 pla 004053 2 18 clc 004054 2 ; 004054 2 @done: 004054 2 60 rts 004055 2 ; 004055 2 ;----------------------- 004055 2 ; nx_sioput_b - Process datum from channel B TxQ 004055 2 ;----------------------- 004055 2 nx_sioput_b: 004055 2 E2 30 shortr ; 8 bit registers 004057 2 38 sec ; Default, assume error 004058 2 2C 0C C4 bit IOBASE + dr_misc ; Read bit 7 of dr_misc, if set, driver 00405B 2 ; has been initialized 00405B 2 10 1E bpl @done ; No, error! 00405D 2 ; 00405D 2 48 pha ; Preserve .A 00405E 2 DA phx ; Preserve .X 00405F 2 A6 2C ldx nx_tx_put_b ; TxQ "put" index 004061 2 E8 inx 004062 2 ; 004062 2 @full: 004062 2 E4 2A cpx nx_tx_get_b ; TxQ "get" index 004064 2 F0 FC beq @full ; TxQ is full, block... 004066 2 ; 004066 2 CA dex ; Realign "put" index and ... 004067 2 9D 00 21 sta nx_tx_qa, X ; ... put datum into TxQ 00406A 2 E6 2C inc nx_tx_put_b ; Bump "put" index 00406C 2 ; 00406C 2 ;--------------- 00406C 2 ; Manage transmitter 00406C 2 ;--------------- 00406C 2 A9 20 lda #nx_txb_dis ; Transmitter disabled flag 00406E 2 1C 0C C4 trb IOBASE + dr_misc ; is transmitter disabled? 004071 2 F0 05 beq @cleanup ; No 004073 2 ; 004073 2 A9 04 lda #nx_cr_tx_ena ; Yes, enable transmitter 004075 2 8D 0A C4 sta IOBASE + dr_crb 004078 2 ; 004078 2 @cleanup: 004078 2 FA plx 004079 2 68 pla 00407A 2 18 clc 00407B 2 ; 00407B 2 @done: 00407B 2 60 rts 00407C 2 ; 00407C 2 ;------------------------------------------------------------------------------- 00407C 2 ; UART Channel B Control 00407C 2 ; 00407C 2 ; Enable/disable channel based on carry value. Routine is based (copied ;)) from 00407C 2 ; BDD's SBC POCv1 ROM 00407C 2 ; 00407C 2 ; carry = 1 => Enable channel B 00407C 2 ; carry = 0 => Disable channel B 00407C 2 ;------------------------------------------------------------------------------- 00407C 2 nx_chan_b_ctl: 00407C 2 E2 20 shorta 00407E 2 90 04 bcc nx_dis_chanb ; If carry is cleared, disable channel B 004080 2 ; 004080 2 nx_ena_chanb: 004080 2 A9 85 lda #(nx_cr_rxtx_ena | nx_cr_rts_ass) 004082 2 80 02 bra nx_chanctl ; Write to DUART command register 004084 2 ; 004084 2 nx_dis_chanb: 004084 2 A9 9A lda #(nx_cr_rxtx_dis | nx_cr_rts_dea) 004086 2 ; 004086 2 nx_chanctl: 004086 2 8D 0A C4 sta IOBASE + dr_crb ; Save to Command Register channel B 004089 2 CB wai ; We have to wait two /IRQs? 00408A 2 CB wai 00408B 2 60 rts 00408C 2 00408C 1 .include "interrupt.asm" 00408C 2 ;=============================================================================== 00408C 2 ; A D R I A - Philips/NXP 28L9x Interrupt handler(s) 00408C 2 ; 00408C 2 ; This source file holds the interrupt handler(s) (back-end of driver) 00408C 2 ; for the Philips/NXP 28L9x IC. 00408C 2 ; 00408C 2 ; Version history: 00408C 2 ; 26 jan 2021 - Inital version 00408C 2 ;=============================================================================== 00408C 2 ; nx_irq - Hardware Interrupt Request Service routine 00408C 2 ;------------------------------------------------------------------------------- 00408C 2 nx_irq: 00408C 2 E2 30 shortr ; 8 bit registers 00408E 2 ; 00408E 2 AD 05 C4 lda IOBASE + dr_isr ; Load IRQ register, did UART interrupt? 004091 2 ; 004091 2 ; 004091 2 ; Seems when adding another channel, the branch is taken too long ;) had to 004091 2 ; solve it somehow 004091 2 ; beq nx_irq_end ; Nope 004091 2 D0 03 bne @save_ISR ; Very short branch 004093 2 4C FB 40 jmp nx_irq_end ; And we use a jump 004096 2 ; 004096 2 @save_ISR: 004096 2 E2 20 shorta 004098 2 48 pha ; As per tip from BDD 004099 2 ; (see forum.6502.org) I now push .A 004099 2 ; to the stack before! 004099 2 ; 004099 2 ;----------------------- 004099 2 ; Contents of stack, which we 004099 2 ; (might) use in the routine 004099 2 ;----------------------- 004099 2 irq_isrx = 1 ; UART IRQ status 004099 2 irq_yreg = irq_isrx + s_byte ; 16 bit .Y 004099 2 irq_xreg = irq_yreg + s_word ; 16 bit .X 004099 2 irq_areg = irq_xreg + s_word ; 16 bit .A 004099 2 irq_dpreg = irq_areg + s_word ; DP 004099 2 irq_dbreg = irq_dpreg + s_mpudpx ; DBR 004099 2 ; pushed by hardware 004099 2 irq_srreg = irq_dbreg + s_mpudbx ; SR 004099 2 irq_pcreg = irq_srreg + s_mpusrx ; PC 004099 2 irq_pbreg = irq_pcreg + s_mpupcx ; PBR 004099 2 ; 004099 2 ;----------------------- 004099 2 ; Test for C/T IRQ 004099 2 ;----------------------- 004099 2 test_ct: 004099 2 ; 004099 2 89 08 bit #msk_irq_ct ; Did C/T interrupt? 00409B 2 F0 16 beq test_rhr_a ; Nope, skip this section 00409D 2 ; 00409D 2 ;----------------------- 00409D 2 ; Process C/T IRQ 00409D 2 ;----------------------- 00409D 2 @handle_ct: 00409D 2 AE 0F C4 ldx IOBASE + dr_cnt_stop ; Reset C/T IRQ 0040A0 2 A6 20 ldx nx_jiffycnt ; Get jiffy counter 0040A2 2 CA dex ; Decrement by one 0040A3 2 D0 0C bne @upd_jiffy ; Not time, yet, to update uptime 0040A5 2 ; 0040A5 2 C2 20 longa ; 16 bit .A 0040A7 2 E6 21 inc nx_uptimecnt ; increment uptime LSW 0040A9 2 D0 02 bne @reset_jiffy ; Done with uptime 0040AB 2 ; 0040AB 2 E6 23 inc nx_uptimecnt + s_word ; Increment uptime MSW 0040AD 2 ; 0040AD 2 @reset_jiffy: 0040AD 2 E2 30 shortr ; 8 bit .A 0040AF 2 A2 64 ldx #hz ; Reset jiffy count 0040B1 2 ; 0040B1 2 @upd_jiffy: 0040B1 2 86 20 stx nx_jiffycnt ; Set new jiffy count value 0040B3 2 ; 0040B3 2 ;----------------------- 0040B3 2 ; Test for channel A RHR IRQ 0040B3 2 ;----------------------- 0040B3 2 test_rhr_a: 0040B3 2 E2 30 shortr 0040B5 2 A3 01 lda irq_isrx, S ; Get original ISR from stack 0040B7 2 89 02 bit #msk_irq_rxa ; Did receiver A request? 0040B9 2 F0 13 beq test_rhr_b ; Nope, check channel B 0040BB 2 ;----------------------- 0040BB 2 ; Process channel A RHR IRQ 0040BB 2 ; 0040BB 2 ; Enter loop to service RHR. Loop will not break until RHR is empty 0040BB 2 ;----------------------- 0040BB 2 @handle_rhr_a: 0040BB 2 ; Taken from pocrom v1 source 0040BB 2 AC 03 C4 ldy IOBASE + dr_rxfifoa ; Read RHR 0040BE 2 A6 27 ldx nx_rx_put_a ; Read buffer "put" index 0040C0 2 8A txa ; Determine ... 0040C1 2 1A ina ; ... next position 0040C2 2 25 7F and buf_idx_mask ; Deal with index wrap 0040C4 2 C5 25 cmp nx_rx_get_a ; Compare with "get" index 0040C6 2 F0 06 beq test_rhr_b ; Buffer is full, drop datum 0040C8 2 ; 0040C8 2 85 27 sta nx_rx_put_a ; Set new "put" index 0040CA 2 98 tya ; Recover and ... 0040CB 2 9D 00 20 sta nx_rx_qa, X ; Store datum 0040CE 2 ; 0040CE 2 ; vvvv THIS WAS BASED ON PDF BY BDD vvv 0040CE 2 ; ldy #msk_sr_rx_rdy ; RHR status mask 0040CE 2 ;@process_datum: 0040CE 2 ; tya 0040CE 2 ; bit IOBASE + dr_sra ; Do we have anything in our RHR for 0040CE 2 ; beq test_rhr_b ; channel A? Nope: go to B 0040CE 2 ; 0040CE 2 ; lda IOBASE + dr_rxfifoa ; YES, read datum from RHR 0040CE 2 ; ldx nx_rx_put_a ; RxD "put" index 0040CE 2 ; inx ; Increment 0040CE 2 ; cpx nx_rx_get_a ; Compare with "get" index 0040CE 2 ; beq @process_datum ; RxQ is full 0040CE 2 ;----------------------- 0040CE 2 ; If RxQ is full, the datum cannot be processed and is lost, corrupting the 0040CE 2 ; data stream. This should not happen is the frontend gets from RxQ in time 0040CE 2 ;----------------------- 0040CE 2 ; dex ; Realign RxD "put" index 0040CE 2 ; sta nx_rx_qa, X ; Store datum into RxQ 0040CE 2 ; inc nx_rx_put_a ; Increment RxD "put" index 0040CE 2 ; bra @process_datum ; Loop for next 0040CE 2 ; ^^^ THIS WAS BASED ON PDF BY BDD ^^^ 0040CE 2 test_rhr_b: 0040CE 2 A3 01 lda irq_isrx, S 0040D0 2 @handle_rhr_b: 0040D0 2 ; 0040D0 2 ;----------------------- 0040D0 2 ; Test for channel A THR IRQ 0040D0 2 ;----------------------- 0040D0 2 test_thr_a: 0040D0 2 A3 01 lda irq_isrx, S ; Get ISR from stack 0040D2 2 ; 0040D2 2 89 01 bit #msk_irq_txa ; Did Xmitter A request interrupt? 0040D4 2 F0 20 beq test_thr_b ; Nope, try Xmitter B 0040D6 2 ;----------------------- 0040D6 2 ; Process channel A THR IRQ 0040D6 2 ;----------------------- 0040D6 2 @handle_thr_a: 0040D6 2 A6 26 ldx nx_tx_get_a ; Buffer "get" index 0040D8 2 E4 28 cpx nx_tx_put_a ; Compare with buffer "put" index 0040DA 2 D0 0E bne @get_datum 0040DC 2 ; 0040DC 2 A9 08 lda #nx_cr_tx_dis ; Disable TxD to suppress ... 0040DE 2 8D 02 C4 sta IOBASE + dr_cra ; ... interrupts 0040E1 2 A9 40 lda #nx_txa_dis ; Set xmitter disabled flag in 0040E3 2 0C 0C C4 tsb IOBASE + dr_misc ; - MISC register 0040E6 2 04 2D tsb nx_tx_status ; - ZP (for debug) 0040E8 2 80 0C bra test_thr_b ; Buffer is empty, so we can continue 0040EA 2 ; 0040EA 2 @get_datum: 0040EA 2 BD 00 21 lda nx_tx_qa, X ; Get datum from buffer 0040ED 2 8D 03 C4 sta IOBASE + dr_txfifoa ; Write to THR 0040F0 2 8A txa ; Current position 0040F1 2 1A ina ; New buffer position 0040F2 2 29 7F and #buf_idx_mask ; Deal with wrap of index 0040F4 2 85 26 sta nx_tx_get_a ; Set new "get" index 0040F6 2 ; 0040F6 2 ; vvvv THIS WAS BASED ON PDF BY BDD vvv 0040F6 2 ; ldx nx_tx_get_a ; Get current TxQ "get" index 0040F6 2 ; ldy #msk_sr_tx_rdy ; THR status mask 0040F6 2 ;----------------------- 0040F6 2 ; Enter the loop to service the THR interrupt. This loop will continue until 0040F6 2 ; the THR is full or TxQ is empty 0040F6 2 ;----------------------- 0040F6 2 ;@next_datum: 0040F6 2 ; cpx nx_tx_put_a ; Any (new) datums in TxQ? 0040F6 2 ; beq @tx_off ; Nope, shutdown Xmitter and go to B 0040F6 2 ; 0040F6 2 ; tya ; YES ... 0040F6 2 ; bit IOBASE + dr_sra ; Any space left in THR 0040F6 2 ; beq @done ; no, done for now... 0040F6 2 ;----------------------- 0040F6 2 ; If the THR is full, the transmitter IRQ processing is done for now... 0040F6 2 ; Later on, when the THR's level has been reduced, another IRQ will occur and 0040F6 2 ; more datums can be processed 0040F6 2 ;----------------------- 0040F6 2 ; lda nx_tx_qa, X ; Get datum from queue and ... 0040F6 2 ; sta IOBASE + dr_txfifoa ; ... write to THR (FIFO) 0040F6 2 ; inx ; Increment "get" index 0040F6 2 ; bra @next_datum ; And process next 0040F6 2 ; 0040F6 2 ;@tx_off: 0040F6 2 ; lda #nx_cr_tx_dis ; Shutdown Xmitter A to suppress ... 0040F6 2 ; sta IOBASE + dr_cra ; ... IRQs 0040F6 2 ; lda #nx_txa_dis ; Set Xmitter A disbaled flag 0040F6 2 ; tsb IOBASE + dr_misc ; Do in MISC register! 0040F6 2 ; tsb nx_tx_status ; And in ZP (for debug) 0040F6 2 ; 0040F6 2 ;@done: 0040F6 2 ; stx nx_tx_get_a ; Save final TxQ "get" index 0040F6 2 ; ^^^ THIS WAS BASED ON PDF BY BDD ^^^ 0040F6 2 ; 0040F6 2 test_thr_b: 0040F6 2 A3 01 lda irq_isrx, S 0040F8 2 @handle_thr_b: 0040F8 2 0040F8 2 ; 0040F8 2 ;----------------------- 0040F8 2 ; We have reached the end of our IRQ handler 0040F8 2 ; 0040F8 2 ; Clean stack from UART IRQ status 0040F8 2 ;----------------------- 0040F8 2 E2 30 shortr 0040FA 2 68 pla ; Clear saved UART IRQ Status & discard 0040FB 2 ; 0040FB 2 nx_irq_end: 0040FB 2 ; 0040FB 2 ;----------------------- 0040FB 2 ; Clear stack and restore saved registers 0040FB 2 ;----------------------- 0040FB 2 C2 30 longr ; 16 bit registers to recover 0040FD 2 7A ply ; .Y 0040FE 2 FA plx ; .X 0040FF 2 68 pla ; .A 004100 2 E2 30 shortr 004102 2 2B pld ; Restore DP 004103 2 AB plb ; Restore DBR 004104 2 ; 004104 2 ;----------------------- 004104 2 ; Contents of stack 004104 2 ; pushed by hardware 004104 2 ;irq_srreg = 1 ; SR 004104 2 ;irq_pcreg = irq_srreg + s_mpusrx ; PC 004104 2 ;irq_pbreg = irq_pcreg + s_mpupcx ; PBR 004104 2 40 rti ; Return from IRQ 004105 2 004105 1 .include "init.asm" 004105 2 ;=============================================================================== 004105 2 ; A D R I A - Philips/NXP 28L9x Initialization routine(s) 004105 2 ; 004105 2 ; This source file holds the initialization routine(s) for the 004105 2 ; Philips/NXP 28L9x IC. 004105 2 ; 004105 2 ; Version history: 004105 2 ; 26 jan 2021 - Inital version 004105 2 ;=============================================================================== 004105 2 ; nx_init - Initialize 28L9x environment 004105 2 ; 004105 2 ; Will read the configuration parameters from the table (bottom-up) and write 004105 2 ; them to the 29L9x. 004105 2 ; 004105 2 ; Currently the table is made for the 28L92 (2 ports), but this can be extended 004105 2 ; to the 8-port variant. 004105 2 ; 004105 2 ; Returns with carry cleared. 004105 2 ;------------------------------------------------------------------------------- 004105 2 nx_init: 004105 2 E2 30 shortr 004107 2 78 sei ; Disable interrupts until done 004108 2 ;--------------------------------------- 004108 2 ; We use register $0C (dr_misc) of the 28L9x as temporary storage 004108 2 ; and to indicate the driver initialization has succeeded. Initially we zero 004108 2 ; this register 004108 2 9C 0C C4 stz IOBASE + dr_misc 00410B 2 ; 00410B 2 ; DEBUG 00410B 2 ; jsr NEWLINE 00410B 2 ; DEBUG 00410B 2 ; 00410B 2 ; Clear used/reserved zeropage (DP) locations 00410B 2 ;--------------------------------------- 00410B 2 A2 00 ldx #$00 00410D 2 @nextAddr: 00410D 2 74 20 stz nx_zeropage, X 00410F 2 E8 inx 004110 2 E0 20 cpx #$20 ; Reserve $20 (32) bytes and clear these 004112 2 D0 F9 bne @nextAddr 004114 2 ; 004114 2 ; Prepare jiffy counter 004114 2 ;--------------------------------------- 004114 2 A9 64 lda #hz 004116 2 85 20 sta nx_jiffycnt 004118 2 ; 004118 2 ; Set up the 28L9x IC using the setup/lookup table 004118 2 ;--------------------------------------- 004118 2 A0 42 ldy #size_l92_suTable - 2 ; Get size of setup/lookup table 00411A 2 @setup: 00411A 2 BE 72 41 ldx l92_suTable, Y ; Read register offset 00411D 2 B9 73 41 lda l92_suTable + s_byte, Y ; Read register parameter 004120 2 ; 004120 2 9D 00 C4 sta IOBASE, X ; Write to register 004123 2 ; vvv DEBUG vvv 004123 2 84 40 sty $40 004125 2 86 41 stx $41 004127 2 85 42 sta $42 004129 2 ; 004129 2 A5 40 lda $40 ; Debug .Y 00412B 2 20 AD DF jsr DPYHEX 00412E 2 A9 2D lda #'-' 004130 2 20 0C FD jsr CHAR_OUT 004133 2 ; 004133 2 A5 41 lda $41 ; Debug .X 004135 2 20 AD DF jsr DPYHEX 004138 2 A9 2D lda #'-' 00413A 2 20 0C FD jsr CHAR_OUT 00413D 2 ; 00413D 2 A5 42 lda $42 ; Debug .A 00413F 2 20 AD DF jsr DPYHEX 004142 2 20 C4 DF jsr NEWLINE 004145 2 ; 004145 2 A5 42 lda $42 004147 2 A6 41 ldx $41 004149 2 A4 40 ldy $40 00414B 2 ; ^^^ DEBUG ^^^ 00414B 2 88 dey ; As we use two bytes per register, ... 00414C 2 88 dey ; ... we have to decrement .Y by 2 00414D 2 10 CB bpl @setup ; Continue until we have reached top 00414F 2 ; 00414F 2 ; before we return, just point to our IRQ handler 00414F 2 C2 30 longr 004151 2 AD D8 02 lda VECTOR_INT ; Get original /IRQ vector 004154 2 85 2E sta rom_irq ; Save it for later 004156 2 ; 004156 2 A9 8C 40 lda #nx_irq ; Install our new /IRQ vector 004159 2 AA tax 00415A 2 49 AD DE eor #$DEAD ; Calculate checksum (force invalid for 00415D 2 ; now) 00415D 2 8D DA 02 sta CHKSUM_INT ; Store the checksum 004160 2 8E D8 02 stx VECTOR_INT ; Save the new vector 004163 2 ; 004163 2 E2 30 shortr ; 8 bit registers 004165 2 ; 004165 2 ; Before we return we have to start the counter by reading IOBASE + dr_cnt_start 004165 2 ; As BDD mentioned, it might be safer to use a BIT instruction 004165 2 ; lda IOBASE + dr_cnt_start 004165 2 2C 0E C4 bit IOBASE + dr_cnt_start 004168 2 ; 004168 2 ; Now we should get a 100Hz ticker and by enabling the interrupts (below), we 004168 2 ; should now have a 0.01 second clock timer ;) 004168 2 ; 004168 2 ; Before returning, set the nx_driver_init flag 004168 2 A9 80 lda #nx_driver_init 00416A 2 0C 0C C4 tsb IOBASE + dr_misc ; Store this is the dr_misc register 00416D 2 04 2D tsb nx_tx_status 00416F 2 ; 00416F 2 58 cli ; Enable interrupts 004170 2 18 clc ; C is cleared, no error 004171 2 60 rts 004172 2 ; 004172 2 004172 1 .include "tables.asm" 004172 2 ;=============================================================================== 004172 2 ; A D R I A - Philips/NXP 28L9x Fixed data/reference/lookup tables 004172 2 ; 004172 2 ; Version history: 004172 2 ; 26 jan 2021 - Inital version 004172 2 ; 08 feb 2020 - Changed Counter mode to Timer mode 004172 2 ;=============================================================================== 004172 2 ; l92_suTable - 28L9x initialization sequence for two (2) ports 004172 2 ;--------------------------------------- 004172 2 l92_suTable: ; Philip/NXP 28L9x Initialization Table 004172 2 ; 004172 2 ; vvv DEBUG vvv 004172 2 ; Disabled IRQ for now, we have to start them manually) 004172 2 05 3B .byte dr_imr, nx_irq_msk ; IMR (Enable IRQs) 004174 2 ; .byte dr_imr, msk_irq_ct ; For testing, only enable CT IRQs 004174 2 ; ^^^ DEBUG ^^^ 004174 2 ; 004174 2 06 48 .byte dr_ctu, nx_cnt_hi ; CTU 004176 2 07 00 .byte dr_ctl, nx_cnt_lo ; CTL 004178 2 004178 2 0A 0A .byte dr_crb, nx_cr_rxtx_dis ; CRB - Disable RxD and TxD 00417A 2 ;--------------------------------------- 00417A 2 ; Port B will be disabled, for now! 00417A 2 ;--------------------------------------- 00417A 2 ; 00417A 2 09 CC .byte dr_csrb, nx_csr ; CSR - Set Clock Register 00417C 2 08 17 .byte dr_mrb, nx_mr2 ; MR2 - Set Mode Register 2 00417E 2 08 D3 .byte dr_mrb, nx_mr1 ; MR1 - Set Mode Register 1 004180 2 0A 10 .byte dr_crb, nx_cr_mr1 ; CRA - Select Mode Register 1 004182 2 08 C8 .byte dr_mrb, nx_mr0 ; MR0 - Set Memory Register 0 004184 2 0A B0 .byte dr_crb, nx_cr_mr0 ; CRA - Select Mode Register 0 004186 2 ;--------------------------------------- 004186 2 ; Port B 004186 2 ;--------------------------------------- 004186 2 ; 004186 2 02 80 .byte dr_cra, nx_cr_rts_ass ; CRA - Assert RTS 004188 2 02 05 .byte dr_cra, nx_cr_rxtx_ena ; CRA - Enable RxD and TxD 00418A 2 00418A 2 ; .byte dr_cra, nx_cr_rxtx_dis ; CRA - For now, disable RxD and TxD 00418A 2 ; 00418A 2 ;--------------------------------------- 00418A 2 ; Enable port A 00418A 2 ;--------------------------------------- 00418A 2 ; 00418A 2 01 CC .byte dr_csra, nx_csr ; CSR - Set Clock Register 00418C 2 00 17 .byte dr_mra, nx_mr2 ; MR2 - Set Mode Register 2 00418E 2 00 D3 .byte dr_mra, nx_mr1 ; MR1 - Set Mode Register 1 004190 2 02 10 .byte dr_cra, nx_cr_mr1 ; CRA - Select Mode Register 1 004192 2 00 C8 .byte dr_mra, nx_mr0 ; MR0 - Set Memory Register 0 004194 2 02 B0 .byte dr_cra, nx_cr_mr0 ; CRA - Select Mode Register 0 004196 2 ;--------------------------------------- 004196 2 ; Port A 004196 2 ;--------------------------------------- 004196 2 ; 004196 2 04 60 .byte dr_acr, nx_acr_def ; ACR - Auxiliary Control Register 004198 2 ;--------------------------------------- 004198 2 ; ACR 004198 2 ;--------------------------------------- 004198 2 ; 004198 2 0D F0 .byte dr_opcr, nx_opcr_def ; OPCR - Output Port Configuration Reg 00419A 2 ;--------------------------------------- 00419A 2 ; OPCR 00419A 2 ;--------------------------------------- 00419A 2 ; 00419A 2 0A C0 .byte dr_crb, nx_cr_cnt_mod ; CRB - Select C/T Counter mode 00419C 2 0A 40 .byte dr_crb, nx_cr_err_res ; CRB - Reset error status 00419E 2 0A 50 .byte dr_crb, nx_cr_bir_res ; CRB - Reset Received Break Change IRQ 0041A0 2 0A 30 .byte dr_crb, nx_cr_tx_res ; CRB - Reset transmitter 0041A2 2 0A 20 .byte dr_crb, nx_cr_rx_res ; CRB - Reset receiver 0041A4 2 0A 90 .byte dr_crb, nx_cr_rts_dea ; CRB - Deassert RTS 0041A6 2 ;--------------------------------------- 0041A6 2 ; Init port B 0041A6 2 ;--------------------------------------- 0041A6 2 0041A6 2 02 C0 .byte dr_cra, nx_cr_cnt_mod ; CRA - Select C/T Counter mode 0041A8 2 02 40 .byte dr_cra, nx_cr_err_res ; CRA - Reset error status 0041AA 2 02 50 .byte dr_cra, nx_cr_bir_res ; CRA - Reset Received Break Change IRQ 0041AC 2 02 30 .byte dr_cra, nx_cr_tx_res ; CRA - Reset transmitter 0041AE 2 02 20 .byte dr_cra, nx_cr_rx_res ; CRA - Reset receiver 0041B0 2 02 90 .byte dr_cra, nx_cr_rts_dea ; CRA - Deassert RTS 0041B2 2 ;--------------------------------------- 0041B2 2 ; Init port A 0041B2 2 ;--------------------------------------- 0041B2 2 ; 0041B2 2 05 00 .byte dr_imr, $00 ; IMR - Disable IRQs 0041B4 2 02 F0 .byte dr_cra, nx_cr_pwr_up ; CRA - Power up 0041B6 2 ;--------------------------------------- 0041B6 2 ; Size of table 0041B6 2 ;--------------------------------------- 0041B6 2 size_l92_suTable = * - l92_suTable
Last edited by xjmaas on Thu Feb 11, 2021 9:15 am, edited 1 time in total.
|
|