Skip to content

Commit

Permalink
8085 - initial int32k.asm
Browse files Browse the repository at this point in the history
  • Loading branch information
feilipu committed Aug 2, 2021
1 parent 62cf6ec commit 861f0b8
Show file tree
Hide file tree
Showing 12 changed files with 446 additions and 63 deletions.
2 changes: 1 addition & 1 deletion rc2014_NascomBasic32k/int32k.asm
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ PRINT:
JR PRINT ; Continue until $00

;------------------------------------------------------------------------------
SECTION z80_init ; ORG $0180
SECTION z80_init ; ORG $0180

PUBLIC INIT

Expand Down
22 changes: 11 additions & 11 deletions rc2014_NascomBasic32k_8085/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,20 +26,18 @@ This Source Code Form is subject to the terms of the Mozilla Public License, v.

==============================================================================

# RC2014 8085 Classic
# 8085 CPU Module for the RC2014

This ROM works with the 8085 CPU Module version of the RC2014, with 32k of RAM. This is the ROM to choose if you want fast I/O from the 8085 RC2014, together with the capability to upload C programs from within Basic.
This ROM works with the 8085 CPU Module for the RC2014, with 32k of RAM. This is the ROM to choose if you want fast I/O from the 8085 CPU for RC2014, together with the capability to upload C programs from within Basic.

ACIA 6850 interrupt driven serial I/O to run modified NASCOM Basic 4.7. Full input and output buffering with incoming data hardware handshaking. Handshake shows full before the buffer is totally filled to allow run-on from the sender. Transmit and receive are interrupt driven, and are fast.
ACIA 6850 interrupt driven serial I/O to run modified NASCOM Basic 4.7. Full input and output buffering with incoming data hardware handshaking. Handshake shows full before the buffer is totally filled to allow run-on from the sender. Transmit and receive are interrupt driven, and are fast. The ACIA interrupt uses RST 5.5.

Receive buffer is 255 bytes, to allow efficient pasting of Basic into the editor. The Transmit buffer is 63 bytes. Receive buffer overflows are silently discarded.
Receive buffer is 255 bytes, to allow efficient pasting of Basic into the editor. The Transmit buffer is 63 bytes, with 16 byte handshake overrun.

Also, this ROM provides both Intel HEX loading functions and an `RST`, `INT0`, and `NMI` RAM JumP Table, starting at `0x8000`.
Also, this ROM provides both Intel HEX loading functions and an `RST`, `INT`, and `TRAP` RAM JumP Table, starting at `0x8000`.

This allows you to upload Assembly or compiled C programs, and then run them as described below.

__NOTE__ The Intel HEX program loader has been integrated inside MS Basic as the `HLOAD` keyword.

The goal of this extension to standard MS Basic is to load an arbitrary program in Intel HEX format into an arbitrary location in the Z80 address space, and allow you to start and use your program from NASCOM Basic. Your program can be created in assembler, or in C, provided the code is available in Intel HEX format.

There are are several stages to this process.
Expand All @@ -59,11 +57,13 @@ For convenience, because we can't easily change the ROM code interrupt routines
* Tx: `RST 08` expects a byte to transmit in the `a` register.
* Rx: `RST 10` returns a received byte in the `a` register, and will block (loop) until it has a byte to return.
* Rx Check: `RST 18` will immediately return the number of bytes in the Rx buffer (0 if buffer empty) in the `a` register.
* Unused: `RST 20`, `RST 28`, `RST 30` are available to the user.
* INT: `RST 38` is used by the ACIA 68B50 Serial Device through the IM1 `INT` location.
* NMI: `NMI` is unused and is available to the user.
* Unused: `RST 20`, `RST 28`, `RST 30`, `RST 38` are available to the user.
* IRQ 5.5: is used by the 8085 CPU Module ACIA 68B50 Serial Device.
* IRQ 6.5: is connected to the RC2014 Bus `INT`, is unused, and is available to the user.
* IRQ 7.5: is connected to the RC2014 RX and can be used to trigger bit banged serial on SID.
* TRAP: is connected to the RC2014 Bus `NMI`, is unused and is available to the user.

All `RST xx` targets can be rewritten in a `JP` table originating at `0x8000` in RAM. This allows the use of debugging tools and reorganising the efficient `RST` instructions as needed.
All `RST xx` targets can be rewritten in a `JP` table originating at `0x8000` in RAM. This allows the use of debugging tools and reorganising the efficient `RST` instructions as needed. Check the source to see the address of each `RST xx`.

## USR Jump Address & Parameter Access

Expand Down
2 changes: 1 addition & 1 deletion rc2014_NascomBasic32k_8085/_ASSEMBLE_32K.BAT
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@

zcc +z80 --no-crt -v -m --list -Ca-f0xFF @nascom32k.lst -o int32k
zcc +z80 -m8085 --no-crt -v -m --list -Ca-f0xFF @nascom32k.lst -o int32k
z88dk-appmake +glue -b int32k --ihex --pad --filler 0xFF --recsize 24 --clean

# AND
Expand Down
96 changes: 53 additions & 43 deletions rc2014_NascomBasic32k_8085/int32k.asm
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
;==============================================================================
;
; The rework to support MS Basic HLOAD and the Z80 instruction tuning are
; copyright (C) 2020 Phillip Stevens
; The rework to support MS Basic HLOAD and the 8085 instruction tuning are
; copyright (C) 2021 Phillip Stevens
;
; This Source Code Form is subject to the terms of the Mozilla Public
; License, v. 2.0. If a copy of the MPL was not distributed with this
Expand All @@ -10,9 +10,9 @@
; ACIA 6850 interrupt driven serial I/O to run modified NASCOM Basic 4.7.
; Full input and output buffering with incoming data hardware handshaking.
; Handshake shows full before the buffer is totally filled to allow run-on
; from the sender. Transmit and receive are interrupt driven.
; from the sender. Transmit and receive are interrupt driven using IRQ_55.
;
; feilipu, August 2020
; feilipu, August 2021
;
;==============================================================================
;
Expand Down Expand Up @@ -44,7 +44,7 @@ INCLUDE "rc2014.inc"
;

;------------------------------------------------------------------------------
SECTION z80_acia_interrupt
SECTION acia_interrupt


serialInt:
Expand All @@ -53,15 +53,15 @@ serialInt:

in a,(SER_STATUS_ADDR) ; get the status of the ACIA
rrca ; check whether a byte has been received, via SER_RDRF
jr NC,im1_tx_send ; if not, go check for bytes to transmit
jp NC,im1_tx_send ; if not, go check for bytes to transmit

im1_rx_get:
in a,(SER_DATA_ADDR) ; Get the received byte from the ACIA
ld l,a ; Move Rx byte to l

ld a,(serRxBufUsed) ; Get the number of bytes in the Rx buffer
cp SER_RX_BUFSIZE-1 ; check whether there is space in the buffer
jr NC,im1_tx_check ; buffer full, check if we can send something
jp NC,im1_tx_check ; buffer full, check if we can send something

ld a,l ; get Rx byte from l
ld hl,serRxBufUsed
Expand All @@ -74,7 +74,7 @@ im1_rx_get:

ld a,(serRxBufUsed) ; get the current Rx count
cp SER_RX_FULLSIZE ; compare the count with the preferred full size
jr NZ,im1_tx_check ; leave the RTS low, and check for Rx/Tx possibility
jp NZ,im1_tx_check ; leave the RTS low, and check for Rx/Tx possibility

ld a,(serControl) ; get the ACIA control echo byte
and ~SER_TEI_MASK ; mask out the Tx interrupt bits
Expand All @@ -85,15 +85,15 @@ im1_rx_get:
im1_tx_check:
in a,(SER_STATUS_ADDR) ; get the status of the ACIA
rrca ; check whether a byte has been received, via SER_RDRF
jr C,im1_rx_get ; another byte received, go get it
jp C,im1_rx_get ; another byte received, go get it

im1_tx_send:
rrca ; check whether a byte can be transmitted, via SER_TDRE
jr NC,im1_txa_end ; if not, we're done for now
jp NC,im1_txa_end ; if not, we're done for now

ld a,(serTxBufUsed) ; get the number of bytes in the Tx buffer
or a ; check whether it is zero
jr Z,im1_tei_clear ; if the count is zero, then disable the Tx Interrupt
jp Z,im1_tei_clear ; if the count is zero, then disable the Tx Interrupt

ld hl,(serTxOutPtr) ; get the pointer to place where we pop the Tx byte
ld a,(hl) ; get the Tx byte
Expand All @@ -109,7 +109,7 @@ im1_tx_send:
ld hl,serTxBufUsed
dec (hl) ; atomically decrement current Tx count

jr NZ,im1_txa_end ; if we've more Tx bytes to send, we're done for now
jp NZ,im1_txa_end ; if we've more Tx bytes to send, we're done for now

im1_tei_clear:
ld a,(serControl) ; get the ACIA control echo byte
Expand All @@ -122,23 +122,23 @@ im1_txa_end:
pop af

ei
reti
ret

;------------------------------------------------------------------------------
; SECTION z80_acia_rxa_chk ; ORG $00F0
; SECTION acia_rxa_chk ; ORG $00F0
; RXA_CHK: ; insert directly into JumP table
; ld a,(serRxBufUsed)
; ret

;------------------------------------------------------------------------------
SECTION z80_acia_rxa ; ORG $00F0
SECTION acia_rxa ; ORG $00F0
RXA:
ld a,(serRxBufUsed) ; get the number of bytes in the Rx buffer
or a ; see if there are zero bytes available
jr Z,RXA ; wait, if there are no bytes available
jp Z,RXA ; wait, if there are no bytes available

cp SER_RX_EMPTYSIZE ; compare the count with the preferred empty size
jr NZ,rxa_clean_up ; if the buffer is too full, don't change the RTS
jp NZ,rxa_clean_up ; if the buffer is too full, don't change the RTS

di ; critical section begin
ld a,(serControl) ; get the ACIA control echo byte
Expand All @@ -165,18 +165,18 @@ rxa_clean_up:
ret ; char ready in A

;------------------------------------------------------------------------------
SECTION z80_acia_txa ; ORG $0120
SECTION acia_txa ; ORG $0120
TXA:
push hl ; store HL so we don't clobber it
ld l,a ; store Tx character

ld a,(serTxBufUsed) ; Get the number of bytes in the Tx buffer
or a ; check whether the buffer is empty
jr NZ,txa_buffer_out ; buffer not empty, so abandon immediate Tx
jp NZ,txa_buffer_out ; buffer not empty, so abandon immediate Tx

in a,(SER_STATUS_ADDR) ; get the status of the ACIA
and SER_TDRE ; check whether a byte can be transmitted
jr Z,txa_buffer_out ; if not, so abandon immediate Tx
jp Z,txa_buffer_out ; if not, so abandon immediate Tx

ld a,l ; Retrieve Tx character for immediate Tx
out (SER_DATA_ADDR),a ; immediately output the Tx byte to the ACIA
Expand All @@ -187,7 +187,7 @@ TXA:
txa_buffer_out:
ld a,(serTxBufUsed) ; Get the number of bytes in the Tx buffer
cp SER_TX_BUFSIZE-1 ; check whether there is space in the buffer
jr NC,txa_buffer_out ; buffer full, so wait till it has space
jp NC,txa_buffer_out ; buffer full, so wait till it has space

ld a,l ; Retrieve Tx character

Expand Down Expand Up @@ -221,27 +221,31 @@ txa_buffer_out:
ret

;------------------------------------------------------------------------------
SECTION z80_acia_print ; ORG $0170
SECTION acia_print ; ORG $0170
PRINT:
LD A,(HL) ; Get character
OR A ; Is it $00 ?
RET Z ; Then RETurn on terminator
CALL TXA ; Print it
INC HL ; Next Character
JR PRINT ; Continue until $00
JP PRINT ; Continue until $00

;------------------------------------------------------------------------------
SECTION z80_init ; ORG $0180
SECTION init ; ORG $0180

PUBLIC INIT

INIT:
LD SP,TEMPSTACK ; Set up a temporary stack

LD HL,Z80_VECTOR_PROTO ; Establish Z80 RST Vector Table
LD DE,Z80_VECTOR_BASE
LD BC,Z80_VECTOR_SIZE
LDIR
LD HL,VECTOR_PROTO ; Establish 8085 RST Vector Table
LD DE,VECTOR_BASE
LD C,VECTOR_SIZE
COPY:
LD A,(HL)
LD (DE),A
DEC C
JP NZ,COPY

LD HL,serRxBuf ; Initialise Rx Buffer
LD (serRxInPtr),HL
Expand All @@ -267,22 +271,23 @@ INIT:
LD (serControl),A ; write the ACIA control byte echo
OUT (SER_CTRL_ADDR),A ; output to the ACIA control byte

IM 1 ; interrupt mode 1
EI
LD A,1EH ; enable IRQ 5.5, mask IRQ 6.5 & 7.5
SIM ; do it
EI ; enable interrupts

START:
LD HL,SIGNON1 ; Sign-on message
CALL PRINT ; Output string
LD A,(basicStarted) ; Check the BASIC STARTED flag
CP 'Y' ; to see if this is power-up
JR NZ,COLDSTART ; If not BASIC started then always do cold start
JP NZ,COLDSTART ; If not BASIC started then always do cold start
LD HL,SIGNON2 ; Cold/warm message
CALL PRINT ; Output string
CORW:
RST 10H
AND 11011111B ; lower to uppercase
CP 'C'
JR NZ,CHECKWARM
JP NZ,CHECKWARM
RST 08H
LD A,CR
RST 08H
Expand All @@ -294,7 +299,7 @@ COLDSTART:
JP $0250 ; <<<< Start Basic COLD:
CHECKWARM:
CP 'W'
JR NZ,CORW
JP NZ,CORW
RST 08H
LD A,CR
RST 08H
Expand All @@ -307,35 +312,40 @@ WARMSTART:
;
; STRINGS
;
SECTION z80_init_strings ; ORG $01F0
SECTION init_strings ; ORG $01F8

SIGNON1: DEFM CR,LF
DEFM "RC2014 - MS Basic Loader",CR,LF
DEFM "RC2014/8085 - MS Basic Loader",CR,LF
DEFM "z88dk - feilipu",CR,LF,0

SIGNON2: DEFM CR,LF
DEFM "Cold | Warm start (C|W) ? ",0

;==============================================================================
;
; Z80 INTERRUPT VECTOR PROTOTYPE ASSIGNMENTS
; 8085 INTERRUPT VECTOR PROTOTYPE ASSIGNMENTS
;

EXTERN NULL_RET, NULL_INT, NULL_NMI
EXTERN NULL_RET, NULL_INT

PUBLIC RST_00, RST_08, RST_10; RST_18
PUBLIC RST_20, RST_28, RST_30, RST_38

PUBLIC Z180_TRAP
PUBLIC RST_08, RST_10, RST_20, RST_28, RST_30
PUBLIC INT_INT0, INT_NMI
PUBLIC TRAP, IRQ_55, IRQ_65, IRQ_75, RST_40

DEFC Z180_TRAP = INIT ; Initialise, should never get here
DEFC RST_00 = INIT ; Initialise, should never get here
DEFC RST_08 = TXA ; TX character over ACIA, loop until space
DEFC RST_10 = RXA ; RX character over ACIA, loop until byte
; RST_18 = RXA_CHK ; Check ACIA status, return # bytes available
DEFC RST_20 = NULL_RET ; RET
DEFC TRAP = NULL_INT ; 8085 TRAP 0x0024 - RC2014 Bus /NMI
DEFC RST_28 = NULL_RET ; RET
DEFC IRQ_55 = serialInt ; ACIA interrupt IRQ 5.5 - 8085 CPU Module
DEFC RST_30 = NULL_RET ; RET
DEFC INT_INT0 = serialInt ; ACIA interrupt
DEFC INT_NMI = NULL_NMI ; RETN
DEFC IRQ_65 = NULL_INT ; 8085 IRQ 6.5 - RC2014 Bus /INT
DEFC RST_38 = NULL_RET ; RET
DEFC IRQ_75 = NULL_INT ; 8085 IRQ 7.5 - RC2014 Bus /RX
DEFC RST_40 = NULL_RET ; 8085 JP V Overflow

;==============================================================================

2 changes: 1 addition & 1 deletion rc2014_NascomBasic32k_8085/nascom32k.lst
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
rc2014_map.asm
z80intr.asm
page0.asm
int32k.asm
Loading

0 comments on commit 861f0b8

Please sign in to comment.