STACK_TOP = 0xFFFF ; At 1 MHz the CPU has about 1000 T-states per millisecond. ; The inner delay loop below costs about 26 T-states per taken iteration: ; dec hl = 6T ; ld a,h = 4T ; or l = 4T ; jr nz = 12T ; 1000 / 26 = 38.5. Use 40 iterations to retain the previous calibration, ; which used 20 iterations at 500 kHz. DELAY_LOOPS_PER_MS = 40 .globl _main .globl _delay_ms .globl _io_out .globl _io_in .globl s__DATA .globl l__DATA .globl s__INITIALIZER .globl s__INITIALIZED .globl l__INITIALIZER .area _ITABLE (ABS) .org 0x00 jp init .org 0x08 reti .org 0x10 reti .org 0x18 reti .org 0x20 reti .org 0x28 reti .org 0x30 reti .org 0x38 reti .area _HOME init: di ld sp, #STACK_TOP call gsinit call _main hang: jr hang .area _GSINIT gsinit: ld bc, #l__INITIALIZER ld a, b or c jr z, zero_data ld de, #s__INITIALIZED ld hl, #s__INITIALIZER ldir zero_data: ld bc, #l__DATA ld a, b or c jr z, gsinit_done ld hl, #s__DATA xor a clear_loop: ld (hl), a inc hl dec bc ld a, b or c jr nz, clear_loop gsinit_done: .area _GSFINAL ret .area _CODE ; Write a byte to an I/O port. ; Input: A = port address, L = data byte. _io_out:: ld c, a ld a, l out (c), a ret ; Read a byte from an I/O port. ; Input: A = port address. ; Return: A = data byte. _io_in:: ld c, a in a, (c) ret ; Approximate millisecond delay. ; Input: HL = delay in milliseconds. ; For CLK_SPEED = 1000000 Hz this uses 40 inner iterations per ms. _delay_ms:: ld a, h or l ret z delay_ms_outer$: push hl ld hl, #DELAY_LOOPS_PER_MS delay_ms_inner$: dec hl ld a, h or l jr nz, delay_ms_inner$ pop hl dec hl ld a, h or l jr nz, delay_ms_outer$ ret