Lion CPU has 16 bit data and now 19 bit address bus. It has 8 registers A0 to A7. Also it has a loop index register IDX, a status register SR, a stack pointer SP, a register named OtherDataPage ODP and the program counter PC. All registers are 16-bit.
Execution starts at address $0020 (32) this is after the interrupt table. The stack pointer is initially set at $FFFE the end of first ram page 0.
Interrupt table is 16 words-interrupt vectors long INT 0 to 15, Interrupts 0-3 are hardware driven interrupts and INT 15 is the trap interrupt. Interrupts 4 to 14 are for software. Some interrupts are remapped by system rom to fixed address table at ram.
Memory paging support has been added to Lion by using 9bits of the status register.
For code execution and branching bits 15,14,13 of status register become the bits A18,A17,A16 of the address and PC or the instruction specified address (16bits) fill the rest A15..A0 address bits.The same when data access to the memory is performed status register bits 12,11,10 become A18,A17,A16.Finally in stack operations bits 9,8,7 of the SR become the most significant bits of the address.So in a way similar to x86 segments, code, data and stack can be located in different pages.
With 3 bits 8 pages can be addressed of 64K each. There are of course special instructions to set the current page, jump to and move from or to a page. For movement of data between pages register ODP holds the source or destination page.
When Lion starts all Pages code,data,stack point to the first Page, Page 0.
On interrupt all the current page values are saved in stack by pushing the sr and the current code page is set to 0. On return from interrupt they are restored.
Total Memory is 128K bytes (up to 512K). $00000 - $0001F Interrupt vector table 16 words
$00020 - $01FFF ROM (8K in fpga)
$02000 - $0FFFF RAM Page 0
$10000 - $1FFFF RAM Page 1
Video ram is mapped at IO address space
$8000 - $FFFF Dual port Video Ram 32K in I/O space (fpga internal)
Sprite ram 12K is mapped at IO address space
$4000 - $6FFF
HARDWARE SIGNALS of Lion system.
Line INT when low sets the interrupt,lines I1 and I0 define the interrupt vector and lines IACK, IA1,IA0 acknowledge the service of the interrupt.
Line RESET resets the CPU when LOW.
Line Clock is the clock 50MHz .
Lines A0-A18 are the address bus and D0-15 the data bus
Line RD can be used to insert wait states.
Line HOLD active low releases the buses after finishing the current instruction and CPU sets HOLDA to acknowledge.
Line AS is address strobe and DS is the data strobe (active low).
Line RW when high indicate a read cycle and when low a write.
Line IO indicates an input output operation.
Line BACS when high indicates a byte access.
Lines Rx,Tx are the serial receive and transmit signals. Lines R,G,B,Vsync,Hsync for VGA support .
Lines MOSI,MISO,CCS,SCLK for SPI
Lines AUDIOA,AUDIOB,AUDIOC,NOISE Sound Channels
Lines KCLK,KDATA PS/2 keyboard
Lines JOYST1[0..4],JOYST2[0..4] 2 joysticks
Serial communication port parameters: 38400, 8 data, 1 stop, no parity, flow control none. 32 bytes read buffer, 32 bytes transmit buffer. SR register bits:(as with all registers, SR(0) is the rightmost less significant bit )SR(0) = Carry flagSR(1) = Overflow flag
SR(2) = Zero flag
SR(3) = Negative flag
SR(4) = JXA increase or decrease register
SR(5) = TRAP Interrupt 15 on/off (off=0 the default value)
SR(6) = Interrupt disable (default disabled)SR(7..9) Current StackPage
SR(10..12) Current Data Page
SR(13..15) Current Code Page
Operations must be aligned to even addresses (the assembler takes care of this).
Some operations have a .B extension, they are byte width operations.
NOP does nothing, after lot of debugging it works fine.
MOV moves a 16bit word and has the form MOV destination, source
MOV Ax|(Ax)|(address) , Ax|address|(Ax)|(address)
Source can be a 16-bit number or a register or content of address constant or contents of address stored in a register
Destination can be a register, or address or the address stored in register.
MOV.B moves the rightmost byte of source to rightmost byte of destination when it is a register or to the address specified. expamles: MOV A0,$100 MOV.B (A0),A1 MOV (A1),(A0) MOV A0,($FF00) MOV (100),A2 MOV (100),13
!!! MOV ($100),($200) now supported
MOVI and MOVI.B is used to store a small number 0-15 to a register is smaller and faster. ex. MOVI A0,9 SWAP Ax swaps low and high bytes in a register
XCHG ax,ax exchanges values of registers
BSET Ax,(n|Ax) BCLR Ax,(n|Ax) Sets/clears the nth bit of Ax
16/5/2016 Added 3 more instructions MOVHL, MOVELH and MOVHH first argument always a register. MOVEHL moves the low byte of source to the high of destination. MOVELH moves the high to the low.
MOVEHH moves the high to the high.
Added MOVR, MOVR.B relative move and GADR get address instructions. MOVR A1,(Label)
GADR A1,Label gets the runtime calculated absolute address of Label.
ADD ADC ADD.B add without and with carry and add byteSUB SUB.B subtraction
MULU, MULU.B unsigned byte multiplication
ADDI SUBBI quick add/subtract a small number 0-15
Destination a register or an address.INC INC.B DEC DEC.B Increase decrease value
result is stored in destination (first register)
examples: ADD A1,(100) MUL.B A0,10 SUB A3,(A2) INC A0 DEC (COUNTER)
Division implemented only by software (signed INT 4 with A0=9, unsigned INT5,A0=6). Logic instructions
Destination always a register, source a constant. AND OR NOT XOR AND.B OR.B XOR.B NOT.B
SRL SLL SRL.B SLL.B logical shift, SLL Ax,n shifts Ax n bits
SRA SLA Arithmetic Shift ROR ROL Rotate
ex. SLL A0,3 Shifts Left Logically A0 register 3 bit positions
Test and branch instructions
CMP CMP.B compare register or constant or value of address in a register or constant and set the flags
CMPI CMPI.B Reg,0-15 compares register with small number, smaller and a bit faster than CMP.
CMPH like CMP.B but compare the upper bytes.
examples CMP A4,A1 CMP A0,10 CMP A1,(100) CMP A0,(A3) CMP (100),A2 CMPI A0,2
BTST Ax,(n,An) Tests nth bit of register Ax and sets the zero flag JMP JR Jump to an absolute or relative address
ex. JMP (A1) JR A0 JMP $FF7E JR 8
JSR JRSR Jump to subroutine pushes next address to the stack
RET Return from subroutine restores PC from stack
JZ JE JNZ, JRZ, JRNZ Jump depending on zero flag (absolute and relative)
JC JNC JRC Jump depending on carry flag JO JNO JRO Jump depending on overflow flag
JN JP JRN Jump depending if negative or positive
JBE JA JAE JRBE JRA Jump below or equal, above, above or equal for unsigned values
JLE JRLE JG JGE JRG JRLE JRG JRGE as above for signed values
SETX Sets IDX index register to a Value,register,indirect
JMPX JRX Jump if not zero and decrease IDX example:
loop: SRL A0,1
This will loop 4 times dividing A0 by 16
New command 21/12/2018
JXAB JXAW JRXAB JRXAW same as JMPX JRX but if IDX is non zero increases a specified register to act as pointer to a byte or word example:
loop: MOV.B (A2),0
This fills 100 bytes starting at address1 with zeros.
MOVX Ax moves the value of IDX to register Ax
Stack and interrupts
PUSH pushes Ax or SR or (Ax) to the stack decreasing SP by 2
POP pops AX or SR from the stack increasing SP by 2
PUSHX POPX pushes/pops IDXSETSP Ax|address|(Ax)|(address) Sets the stack pointer to a new address
GETSP Ax Stores sp value in Ax
MOV SP,Ax also valid
INT n Jumps to the nth interrupt vector pushing PC and SR
RETI Returns from interrupt restoring SR and PC
STI Enables interrupts
CLI Disable interrupts
When a hardware interrupt occurs interrupts are disabled by default until the end of service.
IN Ax, address|Ax|(Ax) inputs a word
OUT, OUT.B address|Ax , value|Ax|(Ax) outputs a word, byte
Memory Paging instructions
Page number values are 0 to 7
SDP (number or An) Set data page
SSP (number or An) Set the stack page
PJMP Address,Page Set code page and jump to address
PJSR Address,Page Set code page and jump to subroutine at address
PRET Return restoring code page
PMOV PMOV.B An,(address) or (address),An move a word/byte from/to address of the Page contained in the ODP register
SODP (n or An) Set ODP register
PMOV A0,(100) ; Move word from address 100 of page 1 to A0
Block move & block fill instructions
The IDX register that is used as a loop counter and index, is used by the transfer instructions to hold the number of words to be moved.
Instructions MTOM, MTOI, ITOM, ITOI with two arguments An1,An2 move fast blocks of words starting from memory or IO address An2 to memory or IO address An1. Instructions NTOM, NTOI with arguments An1,N or An1,An2 fill the block pointed by An1 of size IDX+1 with the 16 bit value N (or An2).Also there are the byte by byte block move instructions MTOM.B MTOI.B ITOM.B ITOI.B
MOV A1,buffer1 MOV A2,buffer2 SETX 99 MTOM A1,A2 ;copy the 100 words block starting at buffer2 to buffer1 SETX 99 NTOM A2,0 ;fill buffer2 with zerosAssembler directives
PAGE number define 64K Page
ORG address position following code start at address
[name] DW w1,w2,...wn (auto align in even address)
[name] DB b1.b2...bn
[name] DS count in bytes
[name] TEXT "some text"
[name] DA (address constant, also auto aligned)
The System I/O map
Port 0, OUT Serial byte to sendSystem Interrupts
Port 2, IN Serial send/receive command
Port 4, IN Serial byte received
Port 6, IN Serial status and Serial Keyboard statuus
Port 8, OUT Sound channel 1 divider/duration/start word
Port 9, IN audio channel status
Port 10, OUT Sound channel 2 divider/duration/start word
Port 11, OUT Audio noise channel enable for each audio channel bits 0-2, 1=enable 0=disable
Port 12, OUT Sound channel 3 divider/duration/start word
Port 13, OUT Enable interrupt #2 at vsync signal
Port 14, IN PS/2 Keyboard data in
Port 15, IN PS/2 Keyboard read command
Port 16, IN SPI data read
Port 17, IN SPI status
Port 18, OUT SPI data to send
Port 19, OUT SPI control
Port 20, OUT sprite buffer change
Port 20, IN read 16-bit timmer 1KHz
Port 21, IN Vsync, Hsync status bits 0,1
Port 22, IN Joystick status
Port 23, IN Current horizontal line number
Port 24, OUT Video mode
Port 25, OUT channel 1 volume 8bit
Port 26, OUT channel 2 volume 8bit
Port 27, OUT channel 3 volume 8bit
Port 28, OUT noise volume 8bit
Port 30, OUT vector display mode
Port 31-33, Second frequency for channel 1 to 3, bits 0 to 3
; INT4 FUNCTION TABLE function in a0
INT4T0 DA SERIN ; Serial port in A1 A0(0)=1
INT4T1 DA SEROUT ; Serial port out A1
INT4T2 DA PLOT ; at X=A1,Y=A2 A4=1 set A4=0 clear
INT4T3 DA CLRSCR ; CLEAR SCREEN
INT4T4 DA PUTC ; Print char A1 at x A2.H y A2.L
INT4T5 DA PSTR ; Print zero & cr terminated string
INT4T6 DA SCROLL ; Scrolls screen 1 char (8 points) up
INT4T7 DA SKEYBIN ; PS/2 Keyboard port in A1 A0(2)=1
INT4T8 DA MULT ; Multiplcation A1*A2 res in A2A1, a0<>0 overflow
INT4T9 DA DIV ; integer Div A2 by A1 res in A1,A0
INT4T10 DA KEYB ; converts to ascii the codes from keyboard
INT4T11 DA SPI_INIT ; initialize spi sd card
INT4T12 DA SPISEND ; spi send/rec byte in A1 mode A2 1=CS low 3=CS h res a0
INT4T13 DA READSEC ; read in buffer at A2, n in A1 512bytes
INT4T14 DA WRITESEC ; WRITE BUFFER at A2 TO A1 BLOCK
INT4T15 DA VSCROLL ; Scroll vertically a defined window in mode 1
INT5T0 DA FMULT ; Fixed point multiply A1*A2
INT5T1 DA FDIV ; Fixed point divide A2.(FRAC2)/A1.(FRAC1)
INT5T2 DA FILELD ; Load file A4 points to filename, at A3
INT5T3 DA VMOUNT ; Load First Volume, return A0=fat root 1st cluster
INT5T4 DA FILEDEL ; Delete file A4 points to filename
INT5T5 DA FILESAV ; Save memory range to file A4 points to filename
INT5T6 DA UDIV ; Unsigned 16bit Div A2 by A1 res in A1,A0
INT5T7 DA LDIV ; 32bit div A1A2/A3A4 res A1A2 rem A3A4
INT5T8 DA LMUL ; 32bit mult A1A2*A3A4 res A1A2
INT5T9 DA FLMUL ; float mult A1A2*A3A4 res A1A2
INT5T10 DA FLDIV ; float div A1A2/A3A4 res A1A2
INT5T11 DA FLADD ; float add A1A2+A3A4 res A1A2
INT5T12 DA FCMP ; float cmp A1A2,A3A4 res A0 (1,0,-1)
INT5T14 DA LINEXY ; plot a line a1,a2 to a3,a4 (to be implemented)
INT5T15 DA HSCROLL ; Scroll horizontally a defined window in mode 1
INT5T16 DA FINDF ; A4 pointer to filename, A0 return cluster relative to (FSTCLST)